Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for #89 - Use custom UUID for NAB Object #101

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

mpryc
Copy link
Collaborator

@mpryc mpryc commented Oct 14, 2024

With this change a new UUID is generated to reference parent/child relationship between objects in the Non Admin Controller use cases.

The first consumer of this UUID is a Velero Backup, created when the NonAdminBackup object is reconciled.

The NonAdminBackup object generates the NAC UUID and stores it in its Status. This prevents users from modifying it. The UUID is later used to create the Velero Backup during reconciliation.

While the NAC UUID is currently used as the Velero Backup name, this is not required, as the UUID is also stored as a Velero Backup label, which is used during the reconcile loop. Usage of NAC UUID as Velero Backup name is to easy it's creation.

This PR also includes small changes to fix linting issues of the code, as well reworks the tests to properly take advantage of gingko BeforeEach function.

Why the changes were made

Fixes #89
Fixes #90

@mpryc
Copy link
Collaborator Author

mpryc commented Oct 14, 2024

@shubham-pampattiwar FYI please review

With this change a new UUID is generated to reference parent/child relationship
between objects in the Non Admin Controller use cases.

The first consumer of this UUID is a Velero Backup, created when the
NonAdminBackup object is reconciled.

The NonAdminBackup object generates the NAC UUID and stores it in its
Status. This prevents users from modifying it. The UUID is later used
to create the Velero Backup during reconciliation.

While the NAC UUID is currently used as the Velero Backup name, this is
not required, as the UUID is also stored as a Velero Backup label, which
is used during the reconcile loop. Usage of NAC UUID as Velero Backup name
is to easy it's creation.

This PR also includes small changes to fix linting issues of the code,
as well reworks the tests to properly take advantage of gingko BeforeEach
function.

Signed-off-by: Michal Pryc <[email protected]>
Improved function to properly validate NAC Object Labels
Dropped length of Annotation Value validation, as it's not limited
to 63 or 256 chars.

Signed-off-by: Michal Pryc <[email protected]>
Changes to address code review.

Signed-off-by: Michal Pryc <[email protected]>
@mpryc
Copy link
Collaborator Author

mpryc commented Oct 16, 2024

@shubham-pampattiwar @mateusoliveira43 Added commit which I hope answers all comments.

ba85bd5

@shubham-pampattiwar
Copy link
Member

@mpryc ++

Renamed function which lists objects by label in a
specific namespace.

Signed-off-by: Michal Pryc <[email protected]>
Change to include:
 - Reworked diagram to include one reconcile entry and multiple states
 - Labels and annotations uses common function to check for the
   name and namespace value length
 - Additional test to cover above scenario.

Signed-off-by: Michal Pryc <[email protected]>
return ""
// GenerateNacObjectNameWithUUID generates a unique name based on the provided namespace and object origin name.
// It includes a UUID suffix. If the name exceeds the maximum length, it truncates nacName first, then namespace.
func GenerateNacObjectNameWithUUID(namespace, nacName string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this name does not make sense to me. This does not generate NAB/NAR name, it generates Velero backup/restore name, right? GenerateVeleroObjectName makes more sense?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function generates a UUID to establish a relationship between the NAB or NAR and the corresponding Velero object. However, it should not be assumed that this UUID will be the actual name of the Velero object.

return ""
// GenerateNacObjectNameWithUUID generates a unique name based on the provided namespace and object origin name.
// It includes a UUID suffix. If the name exceeds the maximum length, it truncates nacName first, then namespace.
func GenerateNacObjectNameWithUUID(namespace, nacName string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change function implementation to make it more readable (did not use the consts you defined, but they can be used here)

func Generate(namespace, name string) string {
	uuidSuffix := uuid.New().String()

	remainingLength := validation.DNS1123LabelMaxLength - len(uuidSuffix) - len("--")

	if len(namespace+name) > remainingLength {
		if len(namespace) >= remainingLength {
			return fmt.Sprintf("%s-%s", namespace[:remainingLength], uuidSuffix)
		}
		remainingLength := remainingLength - len(namespace)
		return fmt.Sprintf("%s-%s-%s", name[:remainingLength], namespace, uuidSuffix)
	}

	return fmt.Sprintf("%s-%s-%s", namespace, name, uuidSuffix)
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like your implementation better ! Do you want to include in this PR or as follow-up?

Copy link
Contributor

@mateusoliveira43 mateusoliveira43 Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either way is fine

@@ -139,17 +139,17 @@ This design intends to enable non-admin users the ability to perform Backup and
backupSpec: {}
```
- **NAB controller reconciles on this NAB CR:** The NonAdminBackup controller continuously reconciles the NonAdminBackup object's desired state with the actual state in the cluster.
- **NAB controller validates the NAB CR and then creates a corresponding Velero Backup CR:** When the NonAdminBackup controller detects a new or modified NonAdminBackup object, it creates or updates a corresponding Velero Backup object within the OADP Namespace using the information provided in the `backupSpec` field of the NonAdminBackup object. The resulting Backup object is named as `nab-<namespace>-<hash>`, where the `<namespace>` is the NonAdminBackup namespace and the `<hash>` is computed from the original NonAdminBackup name. The resulting Backup object is labeled and annotated with the following additional metadata:
- **NAB controller validates the NAB CR and then creates a corresponding Velero Backup CR:** When the NonAdminBackup controller detects a new or modified NonAdminBackup object, it creates or updates a corresponding Velero Backup object within the OADP Namespace using the information provided in the `backupSpec` field of the NonAdminBackup object. The resulting Backup object is named as `<namespace>-<name>-<hash>`, where the `<namespace>` is the NonAdminBackup namespace, `<name>` is the NonAdminBackup name and the `<hash>` is the generated UUID (version 4). If the resulting Backup object name is too long the name is adapted to 63 characters limit strpping first characters from name and then from namespace. The resulting Backup object is labeled and annotated with the following additional metadata:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo strpping ?

and status.conditions[Accepted]: **False** ?"};
questionPhaseStatusSetToCreated{"Is status.phase: **Created**
and status.conditions[BackupScheduled]: **True** ?"};
questionStatusVeleroBackupUUID{"Is status.VeleroBackup.NameUUID existing and valid ?"};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reconcile loop does not validate UUID, right?

},
veleroBackup,
)).To(gomega.Succeed())
veleroBackup.Status.Phase = velerov1.BackupPhaseCompleted
// TODO can not call .Status().Update() for veleroBackup object: backups.velero.io "name..." not found error
Copy link
Contributor

@mateusoliveira43 mateusoliveira43 Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do not remove comment. If you want, you can update it, with the reason

// can not call .Status().Update() for veleroBackup object vmware-tanzu/velero#8285

gomega.Expect(checkTestNonAdminBackupStatus(nonAdminBackup, scenario.ExpectedStatus, nonAdminNamespaceName, oadpNamespaceName)).To(gomega.Succeed())

gomega.Expect(checkTestNonAdminBackupStatus(nonAdminBackupAfterReconcile, scenario.nonAdminBackupExpectedStatus, oadpNamespace)).To(gomega.Succeed())
if scenario.uuidCreatedByReconcile {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this check needs to be moved inside checkTestNonAdminBackupStatus function

first expect in this if here is not valid, no? if namespace name is big, it wont be present in nameUUID

Copy link
Contributor

@mateusoliveira43 mateusoliveira43 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to self: would have done things a little different, setting UUID (only 36 length) as a NAB and Velero Backup label (less secure to use as label instead of status in NAB, but easier to iterate over). After creating UUID, would do get call in NAB and OADP namespace, to confirm UUID is unique in the cluster (#102), but that would not check things in storage provider.

Copy link

openshift-ci bot commented Oct 22, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mateusoliveira43, mpryc, shubham-pampattiwar

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [mateusoliveira43,mpryc,shubham-pampattiwar]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Collaborator Author

@mpryc mpryc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mateusoliveira43 I think I responded to all of your comments. Please point me the ones which must be fixed before this will get merged, which we want to fix as follow up and which are just nice to have. Also I am not sure why it's approved by you with so many comments added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Ready for Review
3 participants