diff --git a/apis/profile/v1alpha1/managedclusterprofilebinding_types.go b/apis/profile/v1alpha1/managedclusterprofilebinding_types.go index 5d917cee..a91ea239 100644 --- a/apis/profile/v1alpha1/managedclusterprofilebinding_types.go +++ b/apis/profile/v1alpha1/managedclusterprofilebinding_types.go @@ -32,6 +32,7 @@ const ( type ManagedClusterProfileBindingSpec struct { ProfileRef core.LocalObjectReference `json:"profileRef"` ClusterMetadata kmapi.ClusterInfo `json:"clusterMetadata"` + Features map[string]FeatureSpec `json:"features,omitempty"` } type BindingStatusPhase string diff --git a/apis/profile/v1alpha1/zz_generated.deepcopy.go b/apis/profile/v1alpha1/zz_generated.deepcopy.go index d5a2725b..14374d07 100644 --- a/apis/profile/v1alpha1/zz_generated.deepcopy.go +++ b/apis/profile/v1alpha1/zz_generated.deepcopy.go @@ -121,6 +121,13 @@ func (in *ManagedClusterProfileBindingSpec) DeepCopyInto(out *ManagedClusterProf *out = *in out.ProfileRef = in.ProfileRef in.ClusterMetadata.DeepCopyInto(&out.ClusterMetadata) + if in.Features != nil { + in, out := &in.Features, &out.Features + *out = make(map[string]FeatureSpec, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } return } diff --git a/crds/profile.k8s.appscode.com_managedclusterprofilebindings.yaml b/crds/profile.k8s.appscode.com_managedclusterprofilebindings.yaml index be04a421..fdda6fa7 100644 --- a/crds/profile.k8s.appscode.com_managedclusterprofilebindings.yaml +++ b/crds/profile.k8s.appscode.com_managedclusterprofilebindings.yaml @@ -67,6 +67,73 @@ spec: - name - uid type: object + features: + additionalProperties: + properties: + chart: + properties: + createNamespace: + type: boolean + name: + type: string + namespace: + type: string + sourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - name + type: object + valuesFiles: + items: + type: string + type: array + version: + type: string + required: + - name + - sourceRef + type: object + featureSet: + type: string + values: + x-kubernetes-preserve-unknown-fields: true + valuesFrom: + items: + properties: + kind: + enum: + - Secret + - ConfigMap + type: string + name: + maxLength: 253 + minLength: 1 + type: string + optional: + type: boolean + targetPath: + maxLength: 250 + pattern: ^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$ + type: string + valuesKey: + maxLength: 253 + pattern: ^[\-._a-zA-Z0-9]+$ + type: string + required: + - kind + - name + type: object + type: array + type: object + type: object profileRef: properties: name: diff --git a/pkg/feature_installer/enable_featureset.go b/pkg/feature_installer/enable_featureset.go index 70148b2a..fd09689e 100644 --- a/pkg/feature_installer/enable_featureset.go +++ b/pkg/feature_installer/enable_featureset.go @@ -192,12 +192,12 @@ func enableFeatureSet(ctx context.Context, kc client.Client, featureSet string, return err } - return applyFeatureSet(ctx, kc, mw, fakeServer, featureSet, []string{"kube-ui-server"}, profile, &mc) + return applyFeatureSet(ctx, kc, mw, fakeServer, featureSet, []string{"kube-ui-server"}, profile, &mc, profileBinding) } - return applyFeatureSet(ctx, kc, mw, fakeServer, featureSet, features, profile, &mc) + return applyFeatureSet(ctx, kc, mw, fakeServer, featureSet, features, profile, &mc, profileBinding) } -func applyFeatureSet(ctx context.Context, kc client.Client, mw *workv1.ManifestWork, fakeServer *FakeServer, featureSet string, features []string, profile *profilev1alpha1.ManagedClusterSetProfile, mc *v1.ManagedCluster) error { +func applyFeatureSet(ctx context.Context, kc client.Client, mw *workv1.ManifestWork, fakeServer *FakeServer, featureSet string, features []string, profile *profilev1alpha1.ManagedClusterSetProfile, mc *v1.ManagedCluster, profileBinding *profilev1alpha1.ManagedClusterProfileBinding) error { logger := klog.FromContext(ctx) var err error var fsObj uiapi.FeatureSet @@ -216,6 +216,21 @@ func applyFeatureSet(ctx context.Context, kc client.Client, mw *workv1.ManifestW // Update values based on user-provided inputs stored in the profile for _, f := range features { featureKey := getFeaturePathInValues(f) + if profileBinding.Spec.Features != nil { + if _, exist := profileBinding.Spec.Features[f]; exist { + var valuesMap map[string]interface{} + if profileBinding.Spec.Features[f].Values != nil { + if err = json.Unmarshal(profileBinding.Spec.Features[f].Values.Raw, &valuesMap); err != nil { + return err + } + if err = unstructured.SetNestedMap(model, valuesMap, "resources", featureKey, "spec", "values"); err != nil { + return err + } + continue + } + } + } + curValues, _, err := unstructured.NestedMap(model, "resources", featureKey, "spec", "values") if err != nil { return err