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
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/v1alpha1/nonadminbackup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ type VeleroBackup struct {
// +optional
Status *velerov1.BackupStatus `json:"status,omitempty"`

// nabnacuuid references the Non Admin Backup object by it's nacUUID.
// nameuuid references the Velero Backup object by it's label containing same NameUUID.
// +optional
NabNacUUID string `json:"nabnacuuid,omitempty"`
NameUUID string `json:"nameuuid,omitempty"`
mateusoliveira43 marked this conversation as resolved.
Show resolved Hide resolved

// namespace references the Namespace in which Velero backup exists.
// +optional
Expand Down
8 changes: 4 additions & 4 deletions config/crd/bases/nac.oadp.openshift.io_nonadminbackups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -612,14 +612,14 @@ spec:
description: VeleroBackup contains information of the related Velero
backup object.
properties:
nabnacuuid:
description: nabnacuuid references the Non Admin Backup object
by it's nacUUID.
type: string
namespace:
description: namespace references the Namespace in which Velero
backup exists.
type: string
nameuuid:
description: nameuuid references the Velero Backup object by it's
label containing same NameUUID.
type: string
status:
description: status captures the current status of the Velero
backup.
Expand Down
8 changes: 4 additions & 4 deletions docs/design/Non_Admin_Controller_design.md
mateusoliveira43 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -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 ?


```yaml
metadata:
annotations:
openshift.io/oadp-nab-origin-name: <NonAdminBackup name>
openshift.io/oadp-nab-origin-namespace: <NonAdminBackup Namespace>
openshift.io/oadp-nab-origin-uuid: <NonAdminBackup UUID>
labels:
app.kubernetes.io/managed-by: <OADP NonAdminController id>
openshift.io/oadp: 'True'
openshift.io/oadp-nab-origin-nameuuid: <NonAdminBackup's NameUUID from Status>
```
- **Velero runs Backup**: Velero executes the backup operation based on the configuration specified in the Velero Backup object. Velero updates the status of the Velero Backup object to reflect the outcome of the backup process.
- **Reconcile loop updates NonAdminBackup object Status**: Upon detecting changes in the status of the Velero Backup object, the NonAdminBackup controller's reconciliation loop updates the Status field of the corresponding NonAdminBackup object with the updated status from the Velero Backup object.
Expand All @@ -162,17 +162,17 @@ This design intends to enable non-admin users the ability to perform Backup and
- **Backup Sync controller syncs the Non-admin Backup CRs:** The Backup-Sync controller ensures that the NS relevant backups are synced and Non-admin backup CRs exists for non-admin users to refer them for restore operations.
- **Non-Admin user creates the Non-Admin restore CR:** The user creates NonAdminRestore custom resource object in the Namespace on which the restore will run within the Kubernetes cluster. The `NonAdminRestore` schema has the `restoreSpec`, which is the same as `Restore` CR from the `velero.io/v1` apiVersion. Note that the non-admin user will use non-admin backup name (and not Velero backup name) in non-admin restore spec.
- **NAR controller reconciles on this NAR CR:** The NonAdminRestore controller continuously reconciles the NonAdminRestore object's desired state with the actual state in the cluster.
- **NAR controller validates the NAR CR and then creates a corresponding Velero Restore CR:** When the NonAdminRestore controller detects a new or modified NonAdminRestore object, it creates the corresponding Velero Restore object within the OADP Namespace using the information provided in the `restoreSpec` field of the NonAdminRestore object. The resulting Restore object is named as `nar-<namespace>-<hash>`, where the `<namespace>` is the NonAdminRestore namespace and the `<hash>` is computed from the original NonAdminRestore name. The resulting Restore object is labeled and annotated with the following additional metadata:
- **NAR controller validates the NAR CR and then creates a corresponding Velero Restore CR:** When the NonAdminRestore controller detects a new or modified NonAdminRestore object, it creates the corresponding Velero Restore object within the OADP Namespace using the information provided in the `restoreSpec` field of the NonAdminRestore object. The resulting Restore object is named as `<namespace>-<name>-<hash>`, where the `<namespace>` is the NonAdminRestore namespace, `<name>` is the NonAdminRestore name and the `<hash>` is the generated UUID (version 4). If the resulting Restore object name is too long the name is adapted to 63 characters limit strpping first characters from name and then from namespace. The resulting Restore object is labeled and annotated with the following additional metadata:

```yaml
metadata:
annotations:
openshift.io/oadp-nar-origin-name: <NonAdminRestore name>
openshift.io/oadp-nar-origin-namespace: <NonAdminRestore Namespace>
openshift.io/oadp-nar-origin-uuid: <NonAdminRestore UUID>
labels:
app.kubernetes.io/managed-by: <OADP NonAdminController id>
openshift.io/oadp: 'True'
openshift.io/oadp-nar-origin-nameuuid: <NonAdminRestore's NameUUID from Status>
```
- **Velero runs Restore**: Velero executes the restore operation based on the configuration specified in the Velero Restore object. Velero updates the status of the Velero Restore object to reflect the outcome of the restore process.
- **Reconcile loop updates NonAdminRestore object Status**: Upon detecting changes in the status of the Velero Restore object, the NonAdminRestore controller's reconciliation loop updates the Status field of the corresponding NonAdminRestore object with the updated status from the Velero Restore object.
Expand Down
12 changes: 6 additions & 6 deletions docs/design/nab_and_nar_status_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ Those are are the possible values for `NonAdminCondition`:

NonAdminBackup/NonAdminRestore `status` contains reference to the related Velero Backup/Restore.

NonAdminBackup `status.veleroBackup` contains `nabnacuuid`, `namespace` and `status`.
- `status.veleroBackup.nabnacuuid` field stores generated unique UUID of the `VeleroBackup` object. The same UUID is also stored as the label value `openshift.io/oadp-nab-origin-uuid` within the created `VeleroBackup` object.
NonAdminBackup `status.veleroBackup` contains `nameuuid`, `namespace` and `status`.
- `status.veleroBackup.nameuuid` field stores generated unique UUID of the `VeleroBackup` object. The same UUID is also stored as the label value `openshift.io/oadp-nab-origin-nameuuid` within the created `VeleroBackup` object.
- `status.veleroBackup.namespace` represents the namespace in which the `VeleroBackup` object was created.
- `status.veleroBackup.status` field is a copy of the `VeleroBackup` object status.

Expand All @@ -76,8 +76,8 @@ status:
velero backup describe -n openshift-adp nab-nacproject-c3499c2729730a
```

Similarly, NonAdminRestore `status.veleroRestore` contains `nabnacuuid`, `namespace` and `status`.
- `status.veleroRestore.nabnacuuid` field stores generated unique UUID of the `VeleroRestore` object. The same UUID is also stored as the label value `openshift.io/oadp-nar-origin-uuid` within the created `VeleroRestore` object.
Similarly, NonAdminRestore `status.veleroRestore` contains `nameuuid`, `namespace` and `status`.
- `status.veleroRestore.nameuuid` field stores generated unique UUID of the `VeleroRestore` object. The same UUID is also stored as the label value `openshift.io/oadp-nar-origin-nameuuid` within the created `VeleroRestore` object.
- `status.veleroRestore.namespace` represents the namespace in which the `veleroRestore` object was created.
- `status.veleroRestore.status` field is a copy of the `VeleroRestore` object status.

Expand All @@ -91,7 +91,7 @@ Object passed validation and Velero `Backup` object was created, but there was a
```yaml
status:
veleroBackup:
nabnacuuid: nonadmin-test-86b8d92b-66b2-11e4-8a2d-42010af06f3f
nameuuid: nonadmin-test-86b8d92b-66b2-11e4-8a2d-42010af06f3f
namespace: openshift-adp
status:
expiration: '2024-05-16T08:12:11Z'
Expand Down Expand Up @@ -147,7 +147,7 @@ reconcileExit2[\Requeue: true, nil/] ==>

reconcileStart3[/Reconcile start\] ==>

setVeleroBackupUUID([Set status.veleroBackup.nabNacUUID]) -. Requeue: false, err .- reconcileStart3
setVeleroBackupUUID([Set status.veleroBackup.nameUUID]) -. Requeue: false, err .- reconcileStart3

setVeleroBackupUUID ==>

Expand Down
4 changes: 2 additions & 2 deletions internal/common/constant/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ const (
ManagedByLabelValue = "oadp-nac-controller" // TODO why not use same project name as in PROJECT file?
NabOriginNameAnnotation = "openshift.io/oadp-nab-origin-name"
NabOriginNamespaceAnnotation = "openshift.io/oadp-nab-origin-namespace"
NabOriginUUIDLabel = "openshift.io/oadp-nab-origin-uuid"
NarOriginUUIDLabel = "openshift.io/oadp-nar-origin-uuid"
NabOriginNameUUIDLabel = "openshift.io/oadp-nab-origin-nameuuid"
NarOriginNameUUIDLabel = "openshift.io/oadp-nar-origin-nameuuid"
)

// Common environment variables for the Non Admin Controller
Expand Down
14 changes: 7 additions & 7 deletions internal/common/function/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ func GenerateNacObjectNameWithUUID(namespace, nacName string) string {
return nacObjectName
}

// GetObjectByLabel retrieves a list of Kubernetes objects of a specified type based on a label within a given namespace.
// It returns a slice of the specified object type and an error.
func GetObjectByLabel(ctx context.Context, clientInstance client.Client, namespace string, labelKey string, labelValue string, objectList client.ObjectList) error {
// ListLabeledObjectsInNamespace retrieves a list of Kubernetes objects in a specified namespace
// that match a given label key-value pair.
func ListLabeledObjectsInNamespace(ctx context.Context, clientInstance client.Client, namespace string, labelKey string, labelValue string, objectList client.ObjectList) error {
mateusoliveira43 marked this conversation as resolved.
Show resolved Hide resolved
// Validate input parameters
if namespace == constant.EmptyString || labelKey == constant.EmptyString || labelValue == constant.EmptyString {
mateusoliveira43 marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Errorf("invalid input: namespace, labelKey, and labelValue must not be empty")
Expand All @@ -146,8 +146,8 @@ func GetObjectByLabel(ctx context.Context, clientInstance client.Client, namespa
func GetVeleroBackupByLabel(ctx context.Context, clientInstance client.Client, namespace string, labelValue string) (*velerov1.Backup, error) {
veleroBackupList := &velerov1.BackupList{}

// Call the generic GetObjectByLabel function
if err := GetObjectByLabel(ctx, clientInstance, namespace, constant.NabOriginUUIDLabel, labelValue, veleroBackupList); err != nil {
// Call the generic ListLabeledObjectsInNamespace function
if err := ListLabeledObjectsInNamespace(ctx, clientInstance, namespace, constant.NabOriginNameUUIDLabel, labelValue, veleroBackupList); err != nil {
return nil, err
}

Expand All @@ -157,7 +157,7 @@ func GetVeleroBackupByLabel(ctx context.Context, clientInstance client.Client, n
case 1:
return &veleroBackupList.Items[0], nil // Found 1 matching VeleroBackup
default:
return nil, fmt.Errorf("multiple VeleroBackup objects found with label %s=%s in namespace '%s'", constant.NabOriginUUIDLabel, labelValue, namespace)
return nil, fmt.Errorf("multiple VeleroBackup objects found with label %s=%s in namespace '%s'", constant.NabOriginNameUUIDLabel, labelValue, namespace)
mateusoliveira43 marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand All @@ -171,7 +171,7 @@ func CheckVeleroBackupMetadata(obj client.Object) bool {
return false
}

if !checkLabelValueIsValid(objLabels, constant.NabOriginUUIDLabel) {
if !checkLabelValueIsValid(objLabels, constant.NabOriginNameUUIDLabel) {
return false
}

Expand Down
28 changes: 14 additions & 14 deletions internal/common/function/function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,11 @@ func TestGetVeleroBackupByLabel(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Namespace: defaultStr,
Name: "backup1",
Labels: map[string]string{constant.NabOriginUUIDLabel: testAppStr},
Labels: map[string]string{constant.NabOriginNameUUIDLabel: testAppStr},
},
},
},
expected: &velerov1.Backup{ObjectMeta: metav1.ObjectMeta{Namespace: defaultStr, Name: "backup1", Labels: map[string]string{constant.NabOriginUUIDLabel: testAppStr}}},
expected: &velerov1.Backup{ObjectMeta: metav1.ObjectMeta{Namespace: defaultStr, Name: "backup1", Labels: map[string]string{constant.NabOriginNameUUIDLabel: testAppStr}}},
expectedError: nil,
},
{
Expand All @@ -252,19 +252,19 @@ func TestGetVeleroBackupByLabel(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Namespace: defaultStr,
Name: "backup2",
Labels: map[string]string{constant.NabOriginUUIDLabel: testAppStr},
Labels: map[string]string{constant.NabOriginNameUUIDLabel: testAppStr},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Namespace: defaultStr,
Name: "backup3",
Labels: map[string]string{constant.NabOriginUUIDLabel: testAppStr},
Labels: map[string]string{constant.NabOriginNameUUIDLabel: testAppStr},
},
},
},
expected: nil,
expectedError: errors.New("multiple VeleroBackup objects found with label openshift.io/oadp-nab-origin-uuid=test-app in namespace 'default'"),
expectedError: errors.New("multiple VeleroBackup objects found with label openshift.io/oadp-nab-origin-nameuuid=test-app in namespace 'default'"),
},
{
name: "Invalid input - empty namespace",
Expand Down Expand Up @@ -355,9 +355,9 @@ func TestCheckVeleroBackupMetadata(t *testing.T) {
backup: &velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
constant.OadpLabel: constant.OadpLabelValue,
constant.ManagedByLabel: constant.ManagedByLabelValue,
constant.NabOriginUUIDLabel: testNonAdminBackupUUID,
constant.OadpLabel: constant.OadpLabelValue,
constant.ManagedByLabel: constant.ManagedByLabelValue,
constant.NabOriginNameUUIDLabel: testNonAdminBackupUUID,
},
Annotations: map[string]string{
constant.NabOriginNamespaceAnnotation: constant.EmptyString,
Expand All @@ -372,9 +372,9 @@ func TestCheckVeleroBackupMetadata(t *testing.T) {
backup: &velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
constant.OadpLabel: constant.OadpLabelValue,
constant.ManagedByLabel: strings.Repeat("ll", validation.DNS1123SubdomainMaxLength),
constant.NabOriginUUIDLabel: testNonAdminBackupUUID,
constant.OadpLabel: constant.OadpLabelValue,
constant.ManagedByLabel: strings.Repeat("ll", validation.DNS1123SubdomainMaxLength),
constant.NabOriginNameUUIDLabel: testNonAdminBackupUUID,
},
Annotations: map[string]string{
constant.NabOriginNamespaceAnnotation: testNonAdminBackupNamespace,
Expand All @@ -389,9 +389,9 @@ func TestCheckVeleroBackupMetadata(t *testing.T) {
backup: &velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
constant.OadpLabel: constant.OadpLabelValue,
constant.ManagedByLabel: constant.ManagedByLabelValue,
constant.NabOriginUUIDLabel: testNonAdminBackupUUID,
constant.OadpLabel: constant.OadpLabelValue,
constant.ManagedByLabel: constant.ManagedByLabelValue,
constant.NabOriginNameUUIDLabel: testNonAdminBackupUUID,
},
Annotations: map[string]string{
constant.NabOriginNamespaceAnnotation: testNonAdminBackupNamespace,
Expand Down
Loading
Loading