diff --git a/api/v1alpha1/smbcommonconfig_types.go b/api/v1alpha1/smbcommonconfig_types.go index 42f11849..72ff70a6 100644 --- a/api/v1alpha1/smbcommonconfig_types.go +++ b/api/v1alpha1/smbcommonconfig_types.go @@ -38,6 +38,12 @@ type SmbCommonConfigSpec struct { // under PodSettings allow admins and users to customize how pods // are scheduled in a kubernetes cluster. PodSettings *SmbCommonConfigPodSettings `json:"podSettings,omitempty"` + + // GloabalConfig are configuration values that are applied to [gloabal] + // section in smb.conf for the smb server. This allows users to add or + // override default configurations. + // +opional + CustomGlobalConfig *SmbCommonConfigGlobalConfig `json:"customGlobalConfig,omitempty"` } // SmbCommonNetworkSpec values define networking properties for the services @@ -61,6 +67,15 @@ type SmbCommonConfigPodSettings struct { Affinity *corev1.Affinity `json:"affinity,omitempty"` } +// SmbCommonConfigGlobalConfig contains values for customizing configs in +// [global] section in smb.conf +type SmbCommonConfigGlobalConfig struct { + // Check if the user wants to use custom configs + UseUnsafeCustomConfig bool `json:"useUnsafeCustomConfig,omitempty"` + // Configs specify keys and values to smb.conf + Configs map[string]string `json:"configs,omitempty"` +} + // SmbCommonConfigStatus defines the observed state of SmbCommonConfig type SmbCommonConfigStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster diff --git a/api/v1alpha1/smbshare_types.go b/api/v1alpha1/smbshare_types.go index 31faefc2..c869dbb0 100644 --- a/api/v1alpha1/smbshare_types.go +++ b/api/v1alpha1/smbshare_types.go @@ -64,6 +64,11 @@ type SmbShareSpec struct { // +optional CommonConfig string `json:"commonConfig,omitempty"` + // CustomShareConfig specifies custom config values to be applied + // to share section in smb.conf + // +optional + CustomShareConfig *SmbShareConfig `json:"customShareConfig,omitempty"` + // Scaling specifies parameters relating to how share resources can and // should be scaled. Scaling *SmbShareScalingSpec `json:"scaling,omitempty"` @@ -76,6 +81,14 @@ type SmbShareStorageSpec struct { Pvc *SmbSharePvcSpec `json:"pvc,omitempty"` } +// SmbShareConfig defines custom config values for share section +type SmbShareConfig struct { + // Check if the user wants to use custom configs + UseUnsafeCustomConfig bool `json:"useUnsafeCustomConfig,omitempty"` + // Configs specify keys and values to smb.conf + Configs map[string]string `json:"configs,omitempty"` +} + // SmbSharePvcSpec defines how a PVC may be associated with a share. type SmbSharePvcSpec struct { // Name of the PVC to use for the share. diff --git a/config/crd/bases/samba-operator.samba.org_smbcommonconfigs.yaml b/config/crd/bases/samba-operator.samba.org_smbcommonconfigs.yaml index feb8b40c..83d71aea 100644 --- a/config/crd/bases/samba-operator.samba.org_smbcommonconfigs.yaml +++ b/config/crd/bases/samba-operator.samba.org_smbcommonconfigs.yaml @@ -30,6 +30,18 @@ spec: spec: description: SmbCommonConfigSpec values act as a template for properties of the services that will host shares. properties: + customGlobalConfig: + description: GloabalConfig are configuration values that are applied to [gloabal] section in smb.conf for the smb server. This allows users to add or override default configurations. + properties: + configs: + additionalProperties: + type: string + description: Configs specify keys and values to smb.conf + type: object + useUnsafeCustomConfig: + description: Check if the user wants to use custom configs + type: boolean + type: object network: description: Network specifies what kind of networking shares associated with this config will use. properties: diff --git a/config/crd/bases/samba-operator.samba.org_smbshares.yaml b/config/crd/bases/samba-operator.samba.org_smbshares.yaml index ce34c62f..b5ebbfa7 100644 --- a/config/crd/bases/samba-operator.samba.org_smbshares.yaml +++ b/config/crd/bases/samba-operator.samba.org_smbshares.yaml @@ -54,6 +54,18 @@ spec: description: CommonConfig specifies which SmbCommonConfig CR is to be used for this share. If left blank, the operator's default will be used. minLength: 1 type: string + customShareConfig: + description: CustomShareConfig specifies custom config values to be applied to share section in smb.conf + properties: + configs: + additionalProperties: + type: string + description: Configs specify keys and values to smb.conf + type: object + useUnsafeCustomConfig: + description: Check if the user wants to use custom configs + type: boolean + type: object readOnly: default: false description: ReadOnly controls if this share is to be read-only or not. diff --git a/internal/planner/configuration.go b/internal/planner/configuration.go index f96ed019..854be0e0 100644 --- a/internal/planner/configuration.go +++ b/internal/planner/configuration.go @@ -96,6 +96,15 @@ func (pl *Planner) Update() (changed bool, err error) { pl.ConfigState.Shares[shareKey] = share changed = true } + if pl.CommonConfig != nil { + if c := applyCustomGlobal(pl.ConfigState.Globals[smbcc.Globals], + pl.CommonConfig.Spec); c { + changed = true + } + } + if c := applyCustomShare(share, pl.SmbShare.Spec); c { + changed = true + } if c := applyShareValues(share, pl.SmbShare.Spec); c { changed = true } @@ -165,6 +174,44 @@ func (pl *Planner) Prune() (changed bool, err error) { return } +func applyCustomGlobal(globals smbcc.GlobalConfig, spec api.SmbCommonConfigSpec) bool { + changed := false + if spec.CustomGlobalConfig != nil { + // check if the user wants to use custom configs + // if not, just return + if !spec.CustomGlobalConfig.UseUnsafeCustomConfig { + return changed + } + for k, v := range spec.CustomGlobalConfig.Configs { + oriValue, ok := globals.Options[k] + if !ok || (ok && oriValue != v) { + globals.Options[k] = v + changed = true + } + } + } + return changed +} + +func applyCustomShare(share smbcc.ShareConfig, spec api.SmbShareSpec) bool { + changed := false + if spec.CustomShareConfig != nil { + // check if the user wants to use custom configs + // if not, just return + if !spec.CustomShareConfig.UseUnsafeCustomConfig { + return changed + } + for k, v := range spec.CustomShareConfig.Configs { + oriValue, ok := share.Options[k] + if !ok || (ok && oriValue != v) { + share.Options[k] = v + changed = true + } + } + } + return changed +} + func applyShareValues(share smbcc.ShareConfig, spec api.SmbShareSpec) bool { changed := false