From 8351f1e363b91d42553dc3cd0df2d55bf4ee7a36 Mon Sep 17 00:00:00 2001 From: Frank Hsiao Date: Mon, 21 Apr 2025 02:42:11 +0000 Subject: [PATCH 1/2] resources: add support for setting custom samba configuration Add new fields to handle custom Samba configurations. For [global] section, a new field customGlobalConfig is added under smbCommonConfig to handle custom settings. For individual share configurations, modifications can be made in customShareConfig field under smbShare. This design is chosen because, in group mode, a single server may correspond to several grouped shares. Signed-off-by: FTS152 --- api/v1alpha1/smbcommonconfig_types.go | 13 +++++++ api/v1alpha1/smbshare_types.go | 10 ++++++ ...a-operator.samba.org_smbcommonconfigs.yaml | 9 +++++ .../samba-operator.samba.org_smbshares.yaml | 9 +++++ internal/planner/configuration.go | 36 +++++++++++++++++++ 5 files changed, 77 insertions(+) diff --git a/api/v1alpha1/smbcommonconfig_types.go b/api/v1alpha1/smbcommonconfig_types.go index 42f11849..de4dfb34 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,13 @@ type SmbCommonConfigPodSettings struct { Affinity *corev1.Affinity `json:"affinity,omitempty"` } +// SmbCommonConfigGlobalConfig contains values for customizing configs in +// [global] section in smb.conf +type SmbCommonConfigGlobalConfig struct { + //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..27ec1a81 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,11 @@ type SmbShareStorageSpec struct { Pvc *SmbSharePvcSpec `json:"pvc,omitempty"` } +type SmbShareConfig struct { + //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..24add410 100644 --- a/config/crd/bases/samba-operator.samba.org_smbcommonconfigs.yaml +++ b/config/crd/bases/samba-operator.samba.org_smbcommonconfigs.yaml @@ -510,6 +510,15 @@ spec: description: NodeSelector values will be assigned to a PodSpec's NodeSelector. type: object type: object + customGlobalConfig: + description: custom configuration that are applied to [gloabal] section in smb.conf for the smb server. + properties: + configs: + additionalProperties: + type: string + description: configuration keys and values. + type: object + type: object type: object status: description: SmbCommonConfigStatus defines the observed state of SmbCommonConfig diff --git a/config/crd/bases/samba-operator.samba.org_smbshares.yaml b/config/crd/bases/samba-operator.samba.org_smbshares.yaml index ce34c62f..0ff9ea1e 100644 --- a/config/crd/bases/samba-operator.samba.org_smbshares.yaml +++ b/config/crd/bases/samba-operator.samba.org_smbshares.yaml @@ -54,6 +54,15 @@ 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: custom configuration that are applied to [share] section in smb.conf for the smb server. + properties: + configs: + additionalProperties: + type: string + description: configuration keys and values. + type: object + 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..edea986e 100644 --- a/internal/planner/configuration.go +++ b/internal/planner/configuration.go @@ -96,6 +96,14 @@ 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 +173,34 @@ func (pl *Planner) Prune() (changed bool, err error) { return } +func applyCustomGlobal(globals smbcc.GlobalConfig, spec api.SmbCommonConfigSpec) bool { + changed := false + if spec.CustomGlobalConfig != nil { + 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 { + 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 From 7b036054636f549f502c6862fa576c76f2dc1581 Mon Sep 17 00:00:00 2001 From: Frank Hsiao Date: Tue, 22 Apr 2025 05:45:16 +0000 Subject: [PATCH 2/2] resources: Add hint for custom configuration Add a key to check if the user already read docs and know the risks that custom configs may lead to unexpected behaviors. Custom settings are ignored if acknowledgement flags are not set if useUnsafeCustomConfig not set to true explicitly. Signed-off-by: FTS152 --- api/v1alpha1/smbcommonconfig_types.go | 4 +++- api/v1alpha1/smbshare_types.go | 5 ++++- ...a-operator.samba.org_smbcommonconfigs.yaml | 21 +++++++++++-------- .../samba-operator.samba.org_smbshares.yaml | 7 +++++-- internal/planner/configuration.go | 13 +++++++++++- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/api/v1alpha1/smbcommonconfig_types.go b/api/v1alpha1/smbcommonconfig_types.go index de4dfb34..72ff70a6 100644 --- a/api/v1alpha1/smbcommonconfig_types.go +++ b/api/v1alpha1/smbcommonconfig_types.go @@ -70,7 +70,9 @@ type SmbCommonConfigPodSettings struct { // SmbCommonConfigGlobalConfig contains values for customizing configs in // [global] section in smb.conf type SmbCommonConfigGlobalConfig struct { - //Configs specify keys and values to smb.conf + // 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"` } diff --git a/api/v1alpha1/smbshare_types.go b/api/v1alpha1/smbshare_types.go index 27ec1a81..c869dbb0 100644 --- a/api/v1alpha1/smbshare_types.go +++ b/api/v1alpha1/smbshare_types.go @@ -81,8 +81,11 @@ type SmbShareStorageSpec struct { Pvc *SmbSharePvcSpec `json:"pvc,omitempty"` } +// SmbShareConfig defines custom config values for share section type SmbShareConfig struct { - //Configs specify keys and values to smb.conf + // 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"` } diff --git a/config/crd/bases/samba-operator.samba.org_smbcommonconfigs.yaml b/config/crd/bases/samba-operator.samba.org_smbcommonconfigs.yaml index 24add410..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: @@ -510,15 +522,6 @@ spec: description: NodeSelector values will be assigned to a PodSpec's NodeSelector. type: object type: object - customGlobalConfig: - description: custom configuration that are applied to [gloabal] section in smb.conf for the smb server. - properties: - configs: - additionalProperties: - type: string - description: configuration keys and values. - type: object - type: object type: object status: description: SmbCommonConfigStatus defines the observed state of SmbCommonConfig diff --git a/config/crd/bases/samba-operator.samba.org_smbshares.yaml b/config/crd/bases/samba-operator.samba.org_smbshares.yaml index 0ff9ea1e..b5ebbfa7 100644 --- a/config/crd/bases/samba-operator.samba.org_smbshares.yaml +++ b/config/crd/bases/samba-operator.samba.org_smbshares.yaml @@ -55,13 +55,16 @@ spec: minLength: 1 type: string customShareConfig: - description: custom configuration that are applied to [share] section in smb.conf for the smb server. + description: CustomShareConfig specifies custom config values to be applied to share section in smb.conf properties: configs: additionalProperties: type: string - description: configuration keys and values. + 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 diff --git a/internal/planner/configuration.go b/internal/planner/configuration.go index edea986e..854be0e0 100644 --- a/internal/planner/configuration.go +++ b/internal/planner/configuration.go @@ -97,7 +97,8 @@ func (pl *Planner) Update() (changed bool, err error) { changed = true } if pl.CommonConfig != nil { - if c := applyCustomGlobal(pl.ConfigState.Globals[smbcc.Globals], pl.CommonConfig.Spec); c { + if c := applyCustomGlobal(pl.ConfigState.Globals[smbcc.Globals], + pl.CommonConfig.Spec); c { changed = true } } @@ -176,6 +177,11 @@ func (pl *Planner) Prune() (changed bool, err error) { 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) { @@ -190,6 +196,11 @@ func applyCustomGlobal(globals smbcc.GlobalConfig, spec api.SmbCommonConfigSpec) 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) {