Skip to content

Commit 4c260e7

Browse files
committed
(feat) Add PatchesFrom
Profiles can now references ConfigMap/Secret instances containing StrategicMerge or JSON Patch. The namespace/name of the referenced ConfigMap/Secret can be expressed as template.
1 parent 693ebc8 commit 4c260e7

20 files changed

+1076
-198
lines changed

api/v1beta1/clusterpromotion_types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@ type ProfileSpec struct {
156156
// +optional
157157
Patches []libsveltosv1beta1.Patch `json:"patches,omitempty"`
158158

159+
// PatchesFrom can reference ConfigMap/Secret instances. Within the ConfigMap or Secret data,
160+
// it is possible to store additional Kustomize inline Patches applied for all resources on this profile
161+
// These values can be static or leverage Go templates for dynamic customization.
162+
// When expressed as templates, the values are filled in using information from
163+
// resources within the management cluster before deployment (Cluster and TemplateResourceRefs)
164+
// +listType=atomic
165+
// +optional
166+
PatchesFrom []ValueFrom `json:"patchesFrom,omitempty"`
167+
159168
// DriftExclusions is a list of configuration drift exclusions to be applied when syncMode is
160169
// set to ContinuousWithDriftDetection. Each exclusion specifies JSON6902 paths to ignore
161170
// when evaluating drift, optionally targeting specific resources and features.

api/v1beta1/spec.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,15 @@ type Spec struct {
784784
// +optional
785785
Patches []libsveltosv1beta1.Patch `json:"patches,omitempty"`
786786

787+
// PatchesFrom can reference ConfigMap/Secret instances. Within the ConfigMap or Secret data,
788+
// it is possible to store additional Kustomize inline Patches applied for all resources on this profile
789+
// These values can be static or leverage Go templates for dynamic customization.
790+
// When expressed as templates, the values are filled in using information from
791+
// resources within the management cluster before deployment (Cluster and TemplateResourceRefs)
792+
// +listType=atomic
793+
// +optional
794+
PatchesFrom []ValueFrom `json:"patchesFrom,omitempty"`
795+
787796
// DriftExclusions is a list of configuration drift exclusions to be applied when syncMode is
788797
// set to ContinuousWithDriftDetection. Each exclusion specifies JSON6902 paths to ignore
789798
// when evaluating drift, optionally targeting specific resources and features.

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,50 @@ spec:
888888
type: object
889889
type: array
890890
x-kubernetes-list-type: atomic
891+
patchesFrom:
892+
description: |-
893+
PatchesFrom can reference ConfigMap/Secret instances. Within the ConfigMap or Secret data,
894+
it is possible to store additional Kustomize inline Patches applied for all resources on this profile
895+
These values can be static or leverage Go templates for dynamic customization.
896+
When expressed as templates, the values are filled in using information from
897+
resources within the management cluster before deployment (Cluster and TemplateResourceRefs)
898+
items:
899+
properties:
900+
kind:
901+
description: |-
902+
Kind of the resource. Supported kinds are:
903+
- ConfigMap/Secret
904+
enum:
905+
- ConfigMap
906+
- Secret
907+
type: string
908+
name:
909+
description: |-
910+
Name of the referenced resource.
911+
Name can be expressed as a template and instantiate using any cluster field.
912+
minLength: 1
913+
type: string
914+
namespace:
915+
description: |-
916+
Namespace of the referenced resource.
917+
For ClusterProfile namespace can be left empty. In such a case, namespace will
918+
be implicit set to cluster's namespace.
919+
For Profile namespace must be left empty. The Profile namespace will be used.
920+
Namespace can be expressed as a template and instantiate using any cluster field.
921+
type: string
922+
optional:
923+
default: false
924+
description: |-
925+
Optional indicates that the referenced resource is not mandatory.
926+
If set to true and the resource is not found, the error will be ignored,
927+
and Sveltos will continue processing other ValueFroms.
928+
type: boolean
929+
required:
930+
- kind
931+
- name
932+
type: object
933+
type: array
934+
x-kubernetes-list-type: atomic
891935
policyRefs:
892936
description: |-
893937
PolicyRefs references all the ConfigMaps/Secrets/Flux Sources containing kubernetes resources

config/crd/bases/config.projectsveltos.io_clusterpromotions.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,50 @@ spec:
789789
type: object
790790
type: array
791791
x-kubernetes-list-type: atomic
792+
patchesFrom:
793+
description: |-
794+
PatchesFrom can reference ConfigMap/Secret instances. Within the ConfigMap or Secret data,
795+
it is possible to store additional Kustomize inline Patches applied for all resources on this profile
796+
These values can be static or leverage Go templates for dynamic customization.
797+
When expressed as templates, the values are filled in using information from
798+
resources within the management cluster before deployment (Cluster and TemplateResourceRefs)
799+
items:
800+
properties:
801+
kind:
802+
description: |-
803+
Kind of the resource. Supported kinds are:
804+
- ConfigMap/Secret
805+
enum:
806+
- ConfigMap
807+
- Secret
808+
type: string
809+
name:
810+
description: |-
811+
Name of the referenced resource.
812+
Name can be expressed as a template and instantiate using any cluster field.
813+
minLength: 1
814+
type: string
815+
namespace:
816+
description: |-
817+
Namespace of the referenced resource.
818+
For ClusterProfile namespace can be left empty. In such a case, namespace will
819+
be implicit set to cluster's namespace.
820+
For Profile namespace must be left empty. The Profile namespace will be used.
821+
Namespace can be expressed as a template and instantiate using any cluster field.
822+
type: string
823+
optional:
824+
default: false
825+
description: |-
826+
Optional indicates that the referenced resource is not mandatory.
827+
If set to true and the resource is not found, the error will be ignored,
828+
and Sveltos will continue processing other ValueFroms.
829+
type: boolean
830+
required:
831+
- kind
832+
- name
833+
type: object
834+
type: array
835+
x-kubernetes-list-type: atomic
792836
policyRefs:
793837
description: |-
794838
PolicyRefs references all the ConfigMaps/Secrets/Flux Sources containing kubernetes resources

config/crd/bases/config.projectsveltos.io_clustersummaries.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,50 @@ spec:
926926
type: object
927927
type: array
928928
x-kubernetes-list-type: atomic
929+
patchesFrom:
930+
description: |-
931+
PatchesFrom can reference ConfigMap/Secret instances. Within the ConfigMap or Secret data,
932+
it is possible to store additional Kustomize inline Patches applied for all resources on this profile
933+
These values can be static or leverage Go templates for dynamic customization.
934+
When expressed as templates, the values are filled in using information from
935+
resources within the management cluster before deployment (Cluster and TemplateResourceRefs)
936+
items:
937+
properties:
938+
kind:
939+
description: |-
940+
Kind of the resource. Supported kinds are:
941+
- ConfigMap/Secret
942+
enum:
943+
- ConfigMap
944+
- Secret
945+
type: string
946+
name:
947+
description: |-
948+
Name of the referenced resource.
949+
Name can be expressed as a template and instantiate using any cluster field.
950+
minLength: 1
951+
type: string
952+
namespace:
953+
description: |-
954+
Namespace of the referenced resource.
955+
For ClusterProfile namespace can be left empty. In such a case, namespace will
956+
be implicit set to cluster's namespace.
957+
For Profile namespace must be left empty. The Profile namespace will be used.
958+
Namespace can be expressed as a template and instantiate using any cluster field.
959+
type: string
960+
optional:
961+
default: false
962+
description: |-
963+
Optional indicates that the referenced resource is not mandatory.
964+
If set to true and the resource is not found, the error will be ignored,
965+
and Sveltos will continue processing other ValueFroms.
966+
type: boolean
967+
required:
968+
- kind
969+
- name
970+
type: object
971+
type: array
972+
x-kubernetes-list-type: atomic
929973
policyRefs:
930974
description: |-
931975
PolicyRefs references all the ConfigMaps/Secrets/Flux Sources containing kubernetes resources

config/crd/bases/config.projectsveltos.io_profiles.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,50 @@ spec:
888888
type: object
889889
type: array
890890
x-kubernetes-list-type: atomic
891+
patchesFrom:
892+
description: |-
893+
PatchesFrom can reference ConfigMap/Secret instances. Within the ConfigMap or Secret data,
894+
it is possible to store additional Kustomize inline Patches applied for all resources on this profile
895+
These values can be static or leverage Go templates for dynamic customization.
896+
When expressed as templates, the values are filled in using information from
897+
resources within the management cluster before deployment (Cluster and TemplateResourceRefs)
898+
items:
899+
properties:
900+
kind:
901+
description: |-
902+
Kind of the resource. Supported kinds are:
903+
- ConfigMap/Secret
904+
enum:
905+
- ConfigMap
906+
- Secret
907+
type: string
908+
name:
909+
description: |-
910+
Name of the referenced resource.
911+
Name can be expressed as a template and instantiate using any cluster field.
912+
minLength: 1
913+
type: string
914+
namespace:
915+
description: |-
916+
Namespace of the referenced resource.
917+
For ClusterProfile namespace can be left empty. In such a case, namespace will
918+
be implicit set to cluster's namespace.
919+
For Profile namespace must be left empty. The Profile namespace will be used.
920+
Namespace can be expressed as a template and instantiate using any cluster field.
921+
type: string
922+
optional:
923+
default: false
924+
description: |-
925+
Optional indicates that the referenced resource is not mandatory.
926+
If set to true and the resource is not found, the error will be ignored,
927+
and Sveltos will continue processing other ValueFroms.
928+
type: boolean
929+
required:
930+
- kind
931+
- name
932+
type: object
933+
type: array
934+
x-kubernetes-list-type: atomic
891935
policyRefs:
892936
description: |-
893937
PolicyRefs references all the ConfigMaps/Secrets/Flux Sources containing kubernetes resources

controllers/clustersummary_controller.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,12 @@ func (r *ClusterSummaryReconciler) getCurrentReferences(ctx context.Context,
975975
}
976976
currentReferences.Append(helmRefs)
977977

978+
patchesFromReferences, err := getPatchesFrom(ctx, clusterSummaryScope.ClusterSummary)
979+
if err != nil {
980+
return nil, err
981+
}
982+
currentReferences.Append(patchesFromReferences)
983+
978984
return currentReferences, nil
979985
}
980986

@@ -1743,3 +1749,35 @@ func (r *ClusterSummaryReconciler) processUndeployError(clusterSummaryScope *sco
17431749

17441750
return reconcile.Result{Requeue: true, RequeueAfter: deleteRequeueAfter}, nil
17451751
}
1752+
1753+
// getPatchesFrom gets referenced ConfigMap/Secret in a PatchesFrom.
1754+
func getPatchesFrom(ctx context.Context, clusterSummary *configv1beta1.ClusterSummary) (*libsveltosset.Set, error) {
1755+
currentValuesFromReferences := &libsveltosset.Set{}
1756+
1757+
patchesFrom := clusterSummary.Spec.ClusterProfileSpec.PatchesFrom
1758+
for i := range patchesFrom {
1759+
referencedNamespace := patchesFrom[i].Namespace
1760+
namespace, err := libsveltostemplate.GetReferenceResourceNamespace(ctx, getManagementClusterClient(),
1761+
clusterSummary.Spec.ClusterNamespace, clusterSummary.Spec.ClusterName, referencedNamespace,
1762+
clusterSummary.Spec.ClusterType)
1763+
if err != nil {
1764+
return nil, err
1765+
}
1766+
1767+
referencedName, err := libsveltostemplate.GetReferenceResourceName(ctx, getManagementClusterClient(),
1768+
clusterSummary.Spec.ClusterNamespace, clusterSummary.Spec.ClusterName, patchesFrom[i].Name,
1769+
clusterSummary.Spec.ClusterType)
1770+
if err != nil {
1771+
return nil, err
1772+
}
1773+
1774+
currentValuesFromReferences.Insert(&corev1.ObjectReference{
1775+
APIVersion: corev1.SchemeGroupVersion.String(),
1776+
Kind: patchesFrom[i].Kind,
1777+
Namespace: namespace,
1778+
Name: referencedName,
1779+
})
1780+
}
1781+
1782+
return currentValuesFromReferences, nil
1783+
}

controllers/clustersummary_controller_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,4 +1341,63 @@ var _ = Describe("ClusterSummaryReconciler: requeue methods", func() {
13411341

13421342
Expect(testEnv.Delete(context.TODO(), ns)).To(Succeed())
13431343
})
1344+
1345+
It("getPatchesFrom returns list of all ConfigMap/Secret instances referenced in PatchesFrom section", func() {
1346+
ns := &corev1.Namespace{
1347+
ObjectMeta: metav1.ObjectMeta{
1348+
Name: namespace,
1349+
},
1350+
}
1351+
Expect(testEnv.Create(context.TODO(), ns)).To(Succeed())
1352+
Expect(waitForObject(context.TODO(), testEnv, ns))
1353+
1354+
Expect(testEnv.Create(context.TODO(), cluster)).To(Succeed())
1355+
Expect(waitForObject(context.TODO(), testEnv.Client, cluster)).To(Succeed())
1356+
1357+
clusterSummary := &configv1beta1.ClusterSummary{
1358+
ObjectMeta: metav1.ObjectMeta{
1359+
Name: randomString(),
1360+
Namespace: ns.Name,
1361+
},
1362+
Spec: configv1beta1.ClusterSummarySpec{
1363+
ClusterNamespace: cluster.Namespace,
1364+
ClusterName: cluster.Name,
1365+
ClusterType: libsveltosv1beta1.ClusterTypeCapi,
1366+
ClusterProfileSpec: configv1beta1.Spec{
1367+
PatchesFrom: []configv1beta1.ValueFrom{
1368+
{
1369+
Kind: string(libsveltosv1beta1.ConfigMapReferencedResourceKind),
1370+
Namespace: "{{ .Cluster.metadata.name }}",
1371+
Name: "{{ .Cluster.metadata.name }}-patch",
1372+
},
1373+
{
1374+
Kind: string(libsveltosv1beta1.SecretReferencedResourceKind),
1375+
Namespace: "{{ .Cluster.metadata.name }}",
1376+
Name: "{{ .Cluster.metadata.name }}-patch",
1377+
},
1378+
},
1379+
},
1380+
},
1381+
}
1382+
1383+
Expect(testEnv.Create(context.TODO(), clusterSummary)).To(Succeed())
1384+
Expect(waitForObject(context.TODO(), testEnv, clusterSummary))
1385+
1386+
patchesFrom, err := controllers.GetPatchesFrom(context.TODO(), clusterSummary)
1387+
Expect(err).To(BeNil())
1388+
Expect(patchesFrom.Len()).To(Equal(2))
1389+
Expect(patchesFrom.Has(&corev1.ObjectReference{
1390+
APIVersion: corev1.SchemeGroupVersion.String(),
1391+
Kind: string(libsveltosv1beta1.ConfigMapReferencedResourceKind),
1392+
Namespace: cluster.Namespace,
1393+
Name: fmt.Sprintf("%s-patch", cluster.Name),
1394+
}))
1395+
1396+
Expect(patchesFrom.Has(&corev1.ObjectReference{
1397+
APIVersion: corev1.SchemeGroupVersion.String(),
1398+
Kind: string(libsveltosv1beta1.SecretReferencedResourceKind),
1399+
Namespace: cluster.Namespace,
1400+
Name: fmt.Sprintf("%s-patch", cluster.Name),
1401+
}))
1402+
})
13441403
})

0 commit comments

Comments
 (0)