From e29c3c80179e377de90821516d056d420149dddf Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 17 Oct 2025 17:14:38 +0800 Subject: [PATCH] init --- apis/apps/v1alpha1/type.go | 18 ++++ apis/apps/v1alpha1/zz_generated.deepcopy.go | 42 ++++++++ ...ps.kubeblocks.io_componentdefinitions.yaml | 80 +++++++++++++++ ...ps.kubeblocks.io_componentdefinitions.yaml | 80 +++++++++++++++ docs/developer_docs/api-reference/cluster.md | 98 ++++++++++++++++++- pkg/controller/component/vars.go | 44 +++++++-- 6 files changed, 353 insertions(+), 9 deletions(-) diff --git a/apis/apps/v1alpha1/type.go b/apis/apps/v1alpha1/type.go index decec6f9964..5e6ec1e917c 100644 --- a/apis/apps/v1alpha1/type.go +++ b/apis/apps/v1alpha1/type.go @@ -1050,6 +1050,10 @@ type VarSource struct { // +optional CredentialVarRef *CredentialVarSelector `json:"credentialVarRef,omitempty"` + // Selects a defined var of the TLS. + // +optional + TLSVarRef *TLSVarSelector `json:"tlsVarRef,omitempty"` + // Selects a defined var of a ServiceRef. // +optional ServiceRefVarRef *ServiceRefVarSelector `json:"serviceRefVarRef,omitempty"` @@ -1127,6 +1131,12 @@ type CredentialVars struct { Password *VarOption `json:"password,omitempty"` } +// TLSVars defines the vars that can be referenced from the TLS. +type TLSVars struct { + // +optional + Enabled *VarOption `json:"enabled,omitempty"` +} + // ServiceRefVars defines the vars that can be referenced from a ServiceRef. type ServiceRefVars struct { // +optional @@ -1166,6 +1176,14 @@ type CredentialVarSelector struct { CredentialVars `json:",inline"` } +// TLSVarSelector selects a var from the TLS. +type TLSVarSelector struct { + // The Component to select from. + ClusterObjectReference `json:",inline"` + + TLSVars `json:",inline"` +} + // ServiceRefVarSelector selects a var from a ServiceRefDeclaration. type ServiceRefVarSelector struct { // The ServiceRefDeclaration to select from. diff --git a/apis/apps/v1alpha1/zz_generated.deepcopy.go b/apis/apps/v1alpha1/zz_generated.deepcopy.go index b178bc3390b..f019285a327 100644 --- a/apis/apps/v1alpha1/zz_generated.deepcopy.go +++ b/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -6715,6 +6715,43 @@ func (in *TLSSecretRef) DeepCopy() *TLSSecretRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSVarSelector) DeepCopyInto(out *TLSVarSelector) { + *out = *in + in.ClusterObjectReference.DeepCopyInto(&out.ClusterObjectReference) + in.TLSVars.DeepCopyInto(&out.TLSVars) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSVarSelector. +func (in *TLSVarSelector) DeepCopy() *TLSVarSelector { + if in == nil { + return nil + } + out := new(TLSVarSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSVars) DeepCopyInto(out *TLSVars) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(VarOption) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSVars. +func (in *TLSVars) DeepCopy() *TLSVars { + if in == nil { + return nil + } + out := new(TLSVars) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TargetInstance) DeepCopyInto(out *TargetInstance) { *out = *in @@ -6953,6 +6990,11 @@ func (in *VarSource) DeepCopyInto(out *VarSource) { *out = new(CredentialVarSelector) (*in).DeepCopyInto(*out) } + if in.TLSVarRef != nil { + in, out := &in.TLSVarRef, &out.TLSVarRef + *out = new(TLSVarSelector) + (*in).DeepCopyInto(*out) + } if in.ServiceRefVarRef != nil { in, out := &in.ServiceRefVarRef, &out.ServiceRefVarRef *out = new(ServiceRefVarSelector) diff --git a/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml b/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml index 1c550912084..3f99e00cffe 100644 --- a/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml +++ b/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml @@ -14612,6 +14612,86 @@ spec: type: string type: object type: object + tlsVarRef: + description: Selects a defined var of the TLS. + properties: + compDef: + description: |- + Specifies the exact name, name prefix, or regular expression pattern for matching the name of the ComponentDefinition + custom resource (CR) used by the component that the referent object resident in. + + + If not specified, the component itself will be used. + type: string + enabled: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + requireAllComponentObjects: + description: |- + RequireAllComponentObjects controls whether all component objects must exist before resolving. + If set to true, resolving will only proceed if all component objects are present. + type: boolean + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + type: object type: object required: - name diff --git a/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml b/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml index 1c550912084..3f99e00cffe 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml @@ -14612,6 +14612,86 @@ spec: type: string type: object type: object + tlsVarRef: + description: Selects a defined var of the TLS. + properties: + compDef: + description: |- + Specifies the exact name, name prefix, or regular expression pattern for matching the name of the ComponentDefinition + custom resource (CR) used by the component that the referent object resident in. + + + If not specified, the component itself will be used. + type: string + enabled: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + requireAllComponentObjects: + description: |- + RequireAllComponentObjects controls whether all component objects must exist before resolving. + If set to true, resolving will only proceed if all component objects are present. + type: boolean + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + type: object type: object required: - name diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index a6c18a2bd28..0d03f7eebfb 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -6439,7 +6439,7 @@ bool

ClusterObjectReference

-(Appears on:ComponentVarSelector, CredentialVarSelector, HostNetworkVarSelector, ServiceRefVarSelector, ServiceVarSelector) +(Appears on:ComponentVarSelector, CredentialVarSelector, HostNetworkVarSelector, ServiceRefVarSelector, ServiceVarSelector, TLSVarSelector)

ClusterObjectReference defines information to let you locate the referenced object inside the same Cluster.

@@ -21914,6 +21914,86 @@ string +

TLSVarSelector +

+

+(Appears on:VarSource) +

+
+

TLSVarSelector selects a var from the TLS.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ClusterObjectReference
+ + +ClusterObjectReference + + +
+

+(Members of ClusterObjectReference are embedded into this type.) +

+

The Component to select from.

+
+TLSVars
+ + +TLSVars + + +
+

+(Members of TLSVars are embedded into this type.) +

+
+

TLSVars +

+

+(Appears on:TLSVarSelector) +

+
+

TLSVars defines the vars that can be referenced from the TLS.

+
+ + + + + + + + + + + + + +
FieldDescription
+enabled
+ + +VarOption + + +
+(Optional) +

TargetInstance

@@ -22561,7 +22641,7 @@ string

VarOption (string alias)

-(Appears on:ComponentVars, CredentialVars, NamedVar, ServiceRefVars, ServiceVars) +(Appears on:ComponentVars, CredentialVars, NamedVar, ServiceRefVars, ServiceVars, TLSVars)

VarOption defines whether a variable is required or optional.

@@ -22654,6 +22734,20 @@ CredentialVarSelector +tlsVarRef
+ + +TLSVarSelector + + + + +(Optional) +

Selects a defined var of the TLS.

+ + + + serviceRefVarRef
diff --git a/pkg/controller/component/vars.go b/pkg/controller/component/vars.go index 8fe72c56f8d..df6ad2dc312 100644 --- a/pkg/controller/component/vars.go +++ b/pkg/controller/component/vars.go @@ -491,6 +491,8 @@ func resolveClusterObjectVarRef(ctx context.Context, cli client.Reader, synthesi return resolveServiceVarRef(ctx, cli, synthesizedComp, defineKey, *source.ServiceVarRef) case source.CredentialVarRef != nil: return resolveCredentialVarRef(ctx, cli, synthesizedComp, defineKey, *source.CredentialVarRef) + case source.TLSVarRef != nil: + return resolveTLSVarRef(ctx, cli, synthesizedComp, defineKey, *source.TLSVarRef) case source.ServiceRefVarRef != nil: return resolveServiceRefVarRef(ctx, cli, synthesizedComp, defineKey, *source.ServiceRefVarRef) case source.ComponentVarRef != nil: @@ -873,6 +875,34 @@ func resolveCredentialPasswordRef(ctx context.Context, cli client.Reader, synthe return resolveCredentialVarRefLow(ctx, cli, synthesizedComp, selector, selector.Password, resolvePassword) } +func resolveTLSVarRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, + defineKey string, selector appsv1alpha1.TLSVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { + var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1alpha1.TLSVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) + switch { + case selector.Enabled != nil: + resolveFunc = resolveTLSEnabledRef + default: + return nil, nil, nil + } + return checkNBuildVars(resolveFunc(ctx, cli, synthesizedComp, defineKey, selector)) +} + +func resolveTLSEnabledRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, + defineKey string, selector appsv1alpha1.TLSVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + resolveEnabled := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { + comp := obj.(*appsv1alpha1.Component) + if comp.Spec.TLSConfig == nil { + return nil, nil, nil + } + enabled := "false" + if comp.Spec.TLSConfig.Enable { + enabled = "true" + } + return &corev1.EnvVar{Name: defineKey, Value: enabled}, nil, nil + } + return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector.ClusterObjectReference, selector.Enabled, resolveEnabled) +} + func resolveServiceRefVarRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) @@ -1141,7 +1171,7 @@ func resolveComponentNameRef(ctx context.Context, cli client.Reader, synthesized comp := obj.(*appsv1alpha1.Component) return &corev1.EnvVar{Name: defineKey, Value: comp.Name}, nil, nil } - return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector, selector.ComponentName, resolveComponentName) + return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector.ClusterObjectReference, selector.ComponentName, resolveComponentName) } func resolveComponentReplicasRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, @@ -1150,7 +1180,7 @@ func resolveComponentReplicasRef(ctx context.Context, cli client.Reader, synthes comp := obj.(*appsv1alpha1.Component) return &corev1.EnvVar{Name: defineKey, Value: strconv.Itoa(int(comp.Spec.Replicas))}, nil, nil } - return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector, selector.Replicas, resolveReplicas) + return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector.ClusterObjectReference, selector.Replicas, resolveReplicas) } func resolveComponentInstanceNamesRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, @@ -1167,7 +1197,7 @@ func resolveComponentInstanceNamesRef(ctx context.Context, cli client.Reader, sy } return &corev1.EnvVar{Name: defineKey, Value: strings.Join(instanceNameList, ",")}, nil, nil } - return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector, selector.InstanceNames, resolveInstanceNames) + return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector.ClusterObjectReference, selector.InstanceNames, resolveInstanceNames) } func resolveComponentPodFQDNsRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, @@ -1193,11 +1223,11 @@ func resolveComponentPodFQDNsRef(ctx context.Context, cli client.Reader, synthes } return &corev1.EnvVar{Name: defineKey, Value: strings.Join(names, ",")}, nil, nil } - return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector, selector.PodFQDNs, resolveFQDNList) + return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector.ClusterObjectReference, selector.PodFQDNs, resolveFQDNList) } func resolveComponentVarRefLow(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - selector appsv1alpha1.ComponentVarSelector, option *appsv1alpha1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + objRef appsv1alpha1.ClusterObjectReference, option *appsv1alpha1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveObjs := func() (map[string]any, error) { getter := func(compName string) (any, error) { key := types.NamespacedName{ @@ -1208,9 +1238,9 @@ func resolveComponentVarRefLow(ctx context.Context, cli client.Reader, synthesiz err := cli.Get(ctx, key, obj, inDataContext()) return obj, err } - return resolveReferentObjects(synthesizedComp, selector.ClusterObjectReference, getter) + return resolveReferentObjects(synthesizedComp, objRef, getter) } - return resolveClusterObjectVars("Component", selector.ClusterObjectReference, option, resolveObjs, resolveVar) + return resolveClusterObjectVars("Component", objRef, option, resolveObjs, resolveVar) } func resolveReferentObjects(synthesizedComp *SynthesizedComponent,