Skip to content

Commit 70f72fc

Browse files
author
mgianluc
committed
(bug) when deploymentType is Local, validate namespace
A Profile using deploymentType: Local, can only deploy resources in the same namespace. Previously, Sveltos used the following format for the OwnerReferences name for resources it deployed due to a Profile: ``` Profile.namespace/Profile.name ``` However, a Profile with this exact name doesn't exist within the management cluster. As a result, the Kubernetes controller would immediately remove the deployed resource. This behavior occurred because: ``` A namespaced owner must exist in the same namespace as the dependent. If it does not, the owner reference is treated as absent, and the dependent is subject to deletion once all owners are verified absent ``` Given this PR ensures that a Profile only creates resources in the management cluster in the same namespace, now only Profile.name is set in the OwnerReference.name
1 parent 1b35cf6 commit 70f72fc

File tree

2 files changed

+20
-29
lines changed

2 files changed

+20
-29
lines changed

controllers/handlers_utils.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,21 @@ func adjustNamespace(policy *unstructured.Unstructured, destConfig *rest.Config)
358358
return nil
359359
}
360360

361+
// isResourceNamespaceValid validates the resource namespace.
362+
// A Profile, when deploying resources locally, i.e, to the management cluster, can
363+
// only deploy resources in the same namespace
364+
func isResourceNamespaceValid(profile client.Object, policy *unstructured.Unstructured,
365+
deployingToMgmtCluster bool) bool {
366+
367+
if profile.GetObjectKind().GroupVersionKind().Kind == configv1beta1.ProfileKind {
368+
if deployingToMgmtCluster && policy.GetNamespace() != profile.GetNamespace() {
369+
return false
370+
}
371+
}
372+
373+
return true
374+
}
375+
361376
// deployUnstructured deploys referencedUnstructured objects.
362377
// Returns an error if one occurred. Otherwise it returns a slice containing the name of
363378
// the policies deployed in the form of kind.group:namespace:name for namespaced policies
@@ -373,9 +388,6 @@ func deployUnstructured(ctx context.Context, deployingToMgmtCluster bool, destCo
373388
if err != nil {
374389
return nil, err
375390
}
376-
if profile.GetObjectKind().GroupVersionKind().Kind == configv1beta1.ProfileKind {
377-
profile.SetName(profileNameToOwnerReferenceName(profile))
378-
}
379391

380392
patches, err := initiatePatches(ctx, clusterSummary, "patch", mgmtResources, logger)
381393
if err != nil {
@@ -400,6 +412,10 @@ func deployUnstructured(ctx context.Context, deployingToMgmtCluster bool, destCo
400412
return nil, err
401413
}
402414

415+
if !isResourceNamespaceValid(profile, policy, deployingToMgmtCluster) {
416+
return nil, fmt.Errorf("profile can only deploy resource in same namespace in the management cluster")
417+
}
418+
403419
logger.V(logs.LogDebug).Info(fmt.Sprintf("deploying resource %s %s/%s (deploy to management cluster: %v)",
404420
policy.GetKind(), policy.GetNamespace(), policy.GetName(), deployingToMgmtCluster))
405421

@@ -517,7 +533,7 @@ func requeueAllOldOwners(ctx context.Context, profileOwners []corev1.ObjectRefer
517533
profileName = types.NamespacedName{Name: profileOwners[i].Name}
518534
case configv1beta1.ProfileKind:
519535
profileKind = configv1beta1.ProfileKind
520-
profileName = *getProfileNameFromOwnerReferenceName(profileOwners[i].Name)
536+
profileName = types.NamespacedName{Namespace: clusterSummary.Namespace, Name: profileOwners[i].Name}
521537
default:
522538
continue
523539
}
@@ -1066,9 +1082,6 @@ func undeployStaleResources(ctx context.Context, isMgmtCluster bool,
10661082
if err != nil {
10671083
return nil, err
10681084
}
1069-
if profile.GetObjectKind().GroupVersionKind().Kind == configv1beta1.ProfileKind {
1070-
profile.SetName(profileNameToOwnerReferenceName(profile))
1071-
}
10721085

10731086
undeployed := make([]configv1beta1.ResourceReport, 0)
10741087

controllers/utils.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -393,28 +393,6 @@ func parseMapFromString(data string) (map[string]string, error) {
393393
return result, nil
394394
}
395395

396-
// Sveltos deployment in managed clusters relies on OwnerReferences to track the responsible profile.
397-
// However, a limitation arises with namespaced Profiles.
398-
// Kubernetes OwnerReferences lack a namespace field, assuming owners reside in the same namespace.
399-
// For Profile resources (namespaced), Sveltos dynamically modifies the owner name to incorporate both
400-
// namespace and name for proper identification.
401-
func profileNameToOwnerReferenceName(profile client.Object) string {
402-
if profile.GetObjectKind().GroupVersionKind().Kind == configv1beta1.ProfileKind {
403-
return fmt.Sprintf("%s/%s", profile.GetNamespace(), profile.GetName())
404-
}
405-
406-
return profile.GetName()
407-
}
408-
409-
func getProfileNameFromOwnerReferenceName(profileName string) *types.NamespacedName {
410-
result := strings.Split(profileName, "/")
411-
if len(result) == 1 {
412-
// resources deployed by Sveltos before release v0.30.0 did not have profile namespace/name
413-
return &types.NamespacedName{Name: profileName}
414-
}
415-
return &types.NamespacedName{Namespace: result[0], Name: result[1]}
416-
}
417-
418396
// Function to remove duplicates from a slice
419397
func unique[T comparable](input []T) []T {
420398
seen := make(map[T]bool)

0 commit comments

Comments
 (0)