Skip to content

Commit

Permalink
nfs: allow users to include additional files in the SSSD sidecar
Browse files Browse the repository at this point in the history
The sssd.conf may refer to additional files, like a CA bundle or TLS
certificates. These files need to be made available in the SSSD sidecar.
With the new `sssdGenericFiles` reference to a VolumeSource and a
`MountPath`, a provided `sssd.conf` can use the additional files.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
Signed-off-by: Blaine Gardner <blaine.gardner@redhat.com>
  • Loading branch information
nixpanic authored and BlaineEXE committed Sep 26, 2022
1 parent dbb9822 commit 79adad7
Show file tree
Hide file tree
Showing 12 changed files with 2,233 additions and 6 deletions.
10 changes: 10 additions & 0 deletions Documentation/CRDs/ceph-nfs-crd.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ The `security` spec sets security configuration for the NFS cluster.
the data item must be named `sssd.conf`, or `items` must be defined to select the key and
give it path `sssd.conf`. A HostPath directory must have the `sssd.conf` file.
2. The volume or config file must have mode 0600.
* `additionalFiles`: adds any number of additional files into the SSSD sidecar. All files will
be placed into `/etc/sssd/rook-additional/<subPath>` and can be referenced by the SSSD
config file. For example, CA and/or TLS certificates to authenticate with Kerberos.
- `subPath`: the sub-path of `/etc/sssd/rook-additional` to add files into. This can
include `/` to create arbitrarily deep sub-paths if desired. If the `volumeSource` is a
file, this will refer to a file name.
- `volumeSource`: this is a standard Kubernetes VolumeSource for additional files like what is
normally used to configure Volumes for a Pod. For example, a ConfigMap, Secret, or HostPath.
The volume may contain multiple files, a single file, or may be a file on its own (e.g., a
host path with `type: File`).
* `debugLevel`: sets the debug level for SSSD. If unset or `0`, Rook does nothing. Otherwise,
this may be a value between 1 and 10. See the
[SSSD docs](https://sssd.io/troubleshooting/basics.html#sssd-debug-logs) for more info.
Expand Down
940 changes: 940 additions & 0 deletions deploy/charts/rook-ceph/templates/resources.yaml

Large diffs are not rendered by default.

940 changes: 940 additions & 0 deletions deploy/examples/crds.yaml

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions deploy/examples/nfs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ spec:
# configMap:
# name: my-nfs-sssd-config
# defaultMode: 0600 # mode must be 0600
# additionalFiles:
# - subPath: ca-certs
# volumeSource:
# secret:
# secretName: sssd-tls-certificates
# defaultMode: 0600 # mode must be 0600 for TLS certs
# - subPath: kerberos.crt
# volumeSource:
# hostPath:
# path: /etc/pki/kerberos.crt
# type: File
# # debugLevel: 6
# resources:
# limits:
Expand Down Expand Up @@ -142,6 +153,18 @@ spec:
# # recommended options for speeding up LDAP lookups:
# enumerate = false
# ignore_group_members = true
#
# this can reference /etc/sssd/rook-additional/certs/ca.crt from the secret below if
# sssd.sidecar.additionalFiles uses the example below
# ---
# # Example secret containing a ca.crt added to SSSD additional files
# apiVersion: v1
# kind: Secret
# metadata:
# name: sssd-tls-certificates
# namespace: rook-ceph
# data:
# ca.crt: aSBhbSBhIGNlcnQK

# # Example secret and configmap providing krb5.keytab and krb5 config files
# ---
Expand Down
8 changes: 8 additions & 0 deletions design/ceph/ceph-nfs-ganesha.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ This allows the NFS-Ganesha server cluster to be scalable and highly available.
will mount the file into the SSSD sidecar.
2. The file mode must be 0600.
- Users only need one SSSD conf Volume per CephNFS that has this option path enabled.
- Users must be able to provide additional files that are referenced in the the SSSD config file

#### Example
Below is an example NFS-Ganesha CRD, `nfs-ganesha.yaml`
Expand Down Expand Up @@ -129,6 +130,13 @@ spec:
configMap:
name: rook-ceph-nfs-organization-sssd-config
defaultMode: 0600 # mode must be 0600
additionalFiles:
- subPath: some-dir
volumeSource:
# example
configMap:
name: rook-ceph-nfs-organization-sssd-ca-bundle
defaultMode: 0600 # mode must be 0600 for CA certs
resources:
# requests:
# cpu: "2"
Expand Down
17 changes: 17 additions & 0 deletions pkg/apis/ceph.rook.io/v1/nfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,23 @@ func (sec *NFSSecuritySpec) Validate() error {
if volSourceExistsAndIsEmpty(sidecar.SSSDConfigFile.VolumeSource) {
return errors.New("System Security Services Daemon (SSSD) sidecar is enabled with config from a VolumeSource, but no source is specified")
}

subDirs := map[string]bool{}
for _, additionalFile := range sidecar.AdditionalFiles {
subDir := additionalFile.SubPath
if subDir == "" {
return errors.New("System Security Services Daemon (SSSD) sidecar is enabled with additional file having no subPath specified")
}

if volSourceExistsAndIsEmpty(additionalFile.VolumeSource) {
return errors.Errorf("System Security Services Daemon (SSSD) sidecar is enabled with additional file (subPath %q), but no source is specified", subDir)
}

if _, ok := subDirs[subDir]; ok {
return errors.Errorf("System Security Services Daemon (SSSD) sidecar is enabled with additional file containing duplicate subPath %q", subDir)
}
subDirs[subDir] = true
}
}

krb := sec.Kerberos
Expand Down
68 changes: 62 additions & 6 deletions pkg/apis/ceph.rook.io/v1/nfs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ func TestNFSSecuritySpec_Validate(t *testing.T) {
}
}

configMapVolumeSource := &v1.VolumeSource{
ConfigMap: &v1.ConfigMapVolumeSource{},
}

tests := []struct {
name string
security *NFSSecuritySpec
Expand All @@ -51,9 +55,7 @@ func TestNFSSecuritySpec_Validate(t *testing.T) {
Sidecar: &SSSDSidecar{
Image: "myimage",
SSSDConfigFile: SSSDSidecarConfigFile{
VolumeSource: &v1.VolumeSource{
ConfigMap: &v1.ConfigMapVolumeSource{},
},
VolumeSource: configMapVolumeSource,
},
},
}),
Expand All @@ -63,9 +65,7 @@ func TestNFSSecuritySpec_Validate(t *testing.T) {
Sidecar: &SSSDSidecar{
Image: "",
SSSDConfigFile: SSSDSidecarConfigFile{
VolumeSource: &v1.VolumeSource{
ConfigMap: &v1.ConfigMapVolumeSource{},
},
VolumeSource: configMapVolumeSource,
},
},
}),
Expand All @@ -88,6 +88,62 @@ func TestNFSSecuritySpec_Validate(t *testing.T) {
},
}),
isFailing},
{"security.sssd.sidecar.additionalFiles empty",
withSSSD(&SSSDSpec{
Sidecar: &SSSDSidecar{
Image: "myimage",
AdditionalFiles: []SSSDSidecarAdditionalFile{},
},
}),
isOkay},
{"security.sssd.sidecar.additionalFiles multiple valid",
withSSSD(&SSSDSpec{
Sidecar: &SSSDSidecar{
Image: "myimage",
AdditionalFiles: []SSSDSidecarAdditionalFile{
{SubPath: "one", VolumeSource: configMapVolumeSource},
{SubPath: "two", VolumeSource: configMapVolumeSource},
{SubPath: "three", VolumeSource: configMapVolumeSource},
},
},
}),
isOkay},
{"security.sssd.sidecar.additionalFiles one empty subDir",
withSSSD(&SSSDSpec{
Sidecar: &SSSDSidecar{
Image: "myimage",
AdditionalFiles: []SSSDSidecarAdditionalFile{
{SubPath: "one", VolumeSource: configMapVolumeSource},
{SubPath: "", VolumeSource: configMapVolumeSource},
{SubPath: "three", VolumeSource: configMapVolumeSource},
},
},
}),
isFailing},
{"security.sssd.sidecar.additionalFiles duplicate subDirs",
withSSSD(&SSSDSpec{
Sidecar: &SSSDSidecar{
Image: "myimage",
AdditionalFiles: []SSSDSidecarAdditionalFile{
{SubPath: "one", VolumeSource: configMapVolumeSource},
{SubPath: "two", VolumeSource: configMapVolumeSource},
{SubPath: "one", VolumeSource: configMapVolumeSource},
},
},
}),
isFailing},
{"security.sssd.sidecar.additionalFiles one vol source empty",
withSSSD(&SSSDSpec{
Sidecar: &SSSDSidecar{
Image: "myimage",
AdditionalFiles: []SSSDSidecarAdditionalFile{
{SubPath: "one", VolumeSource: configMapVolumeSource},
{SubPath: "", VolumeSource: &v1.VolumeSource{}},
{SubPath: "three", VolumeSource: configMapVolumeSource},
},
},
}),
isFailing},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
24 changes: 24 additions & 0 deletions pkg/apis/ceph.rook.io/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2060,6 +2060,11 @@ type SSSDSidecar struct {
// +optional
SSSDConfigFile SSSDSidecarConfigFile `json:"sssdConfigFile"`

// AdditionalFiles defines any number of additional files that should be mounted into the SSSD
// sidecar. These files may be referenced by the sssd.conf config file.
// +optional
AdditionalFiles []SSSDSidecarAdditionalFile `json:"additionalFiles,omitempty"`

// Resources allow specifying resource requests/limits on the SSSD sidecar container.
// +optional
Resources v1.ResourceRequirements `json:"resources,omitempty"`
Expand All @@ -2085,6 +2090,25 @@ type SSSDSidecarConfigFile struct {
VolumeSource *v1.VolumeSource `json:"volumeSource,omitempty"`
}

// SSSDSidecarAdditionalFile represents the source from where additional files for the the SSSD
// configuration should come from and are made available.
type SSSDSidecarAdditionalFile struct {
// SubPath defines the sub-path in `/etc/sssd/rook-additional/` where the additional file(s)
// will be placed. Each subPath definition must be unique and must not contain ':'.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^[^:]+$`
SubPath string `json:"subPath"`

// VolumeSource accepts standard Kubernetes VolumeSource for the additional file(s) like what is
// normally used to configure Volumes for a Pod. Fore example, a ConfigMap, Secret, or HostPath.
// Each VolumeSource adds one or more additional files to the SSSD sidecar container in the
// `/etc/sssd/rook-additional/<subPath>` directory.
// Be aware that some files may need to have a specific file mode like 0600 due to requirements
// by SSSD for some files. For example, CA or TLS certificates.
VolumeSource *v1.VolumeSource `json:"volumeSource"`
}

// NetworkSpec for Ceph includes backward compatibility code
type NetworkSpec struct {
// Provider is what provides network connectivity to the cluster e.g. "host" or "multus"
Expand Down
28 changes: 28 additions & 0 deletions pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions pkg/operator/ceph/nfs/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ package nfs

import (
"fmt"
"path/filepath"

cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
"github.com/rook/rook/pkg/operator/k8sutil"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
)
Expand Down Expand Up @@ -140,6 +142,10 @@ func generateSssdSidecarResources(sidecarCfg *cephv1.SSSDSidecar) (
sssdMounts = append(sssdMounts, mount)
}

genericVols, genericMounts := generateGenericFileVolsAndMounts(sidecarCfg.AdditionalFiles)
volumes = append(volumes, genericVols...)
sssdMounts = append(sssdMounts, genericMounts...)

// the init container is needed to copy the starting content from the /var/lib/sss/pipes
// directory into the shared sockets dir so that SSSD has the content it needs to start up
init = &v1.Container{
Expand Down Expand Up @@ -237,6 +243,26 @@ func sssdConfigVolAndMount(volSource v1.VolumeSource) (v1.Volume, v1.VolumeMount
return vol, mount
}

func generateGenericFileVolsAndMounts(additionalFiles []cephv1.SSSDSidecarAdditionalFile) ([]v1.Volume, []v1.VolumeMount) {
vols := []v1.Volume{}
mounts := []v1.VolumeMount{}

for _, additionalFile := range additionalFiles {
mountPath := filepath.Join("/etc/sssd/rook-additional/", additionalFile.SubPath)
volName := k8sutil.ToValidDNSLabel(mountPath)
vols = append(vols, v1.Volume{
Name: volName,
VolumeSource: *additionalFile.VolumeSource,
})
mounts = append(mounts, v1.VolumeMount{
Name: volName,
MountPath: mountPath,
})
}

return vols, mounts
}

func generateSssdNsswitchConfResources(r *ReconcileCephNFS, nfs *cephv1.CephNFS) (*v1.Container, *v1.Volume, *v1.VolumeMount) {
volName := "nsswitch-conf"

Expand Down
Loading

0 comments on commit 79adad7

Please sign in to comment.