diff --git a/bundle/manifests/nac.oadp.openshift.io_nonadminbackups.yaml b/bundle/manifests/nac.oadp.openshift.io_nonadminbackups.yaml index 8fe8599691..9d024cfc25 100644 --- a/bundle/manifests/nac.oadp.openshift.io_nonadminbackups.yaml +++ b/bundle/manifests/nac.oadp.openshift.io_nonadminbackups.yaml @@ -11,6 +11,8 @@ spec: kind: NonAdminBackup listKind: NonAdminBackupList plural: nonadminbackups + shortNames: + - nab singular: nonadminbackup scope: Namespaced versions: @@ -503,8 +505,110 @@ spec: type: string type: array type: object - backupStatus: - description: BackupStatus captures the current status of a Velero + logLevel: + description: NonAdminBackup log level (use debug for the most logging, + leave unset for default) + enum: + - trace + - debug + - info + - warning + - error + - fatal + - panic + type: string + type: object + status: + description: NonAdminBackupStatus defines the observed state of NonAdminBackup + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + phase: + description: NonAdminPhase is a simple one high-level summary of the + lifecycle of a non admin object. + enum: + - New + - BackingOff + - Created + type: string + veleroBackupName: + description: VeleroBackupName references the VeleroBackup object by + it's name. + type: string + veleroBackupNamespace: + description: |- + VeleroBackupNamespace references the Namespace + in which VeleroBackupName object exists. + type: string + veleroBackupStatus: + description: VeleroBackupStatus captures the current status of a Velero backup. properties: backupItemOperationsAttempted: @@ -634,91 +738,6 @@ spec: file in object storage. type: integer type: object - logLevel: - description: NonAdminBackup log level (use debug for the most logging, - leave unset for default) - enum: - - trace - - debug - - info - - warning - - error - - fatal - - panic - type: string - type: object - status: - description: NonAdminBackupStatus defines the observed state of NonAdminBackup - properties: - conditions: - items: - description: "Condition contains details for one aspect of the current - state of this API Resource.\n---\nThis struct is intended for - direct use as an array at the field path .status.conditions. For - example,\n\n\n\ttype FooStatus struct{\n\t // Represents the - observations of a foo's current state.\n\t // Known .status.conditions.type - are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // - +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t - \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t - \ // other fields\n\t}" - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - --- - Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be - useful (see .node.status.conditions), the ability to deconflict is important. - The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array type: object type: object served: true diff --git a/bundle/manifests/nac.oadp.openshift.io_nonadminrestores.yaml b/bundle/manifests/nac.oadp.openshift.io_nonadminrestores.yaml new file mode 100644 index 0000000000..6e7bc09107 --- /dev/null +++ b/bundle/manifests/nac.oadp.openshift.io_nonadminrestores.yaml @@ -0,0 +1,631 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + creationTimestamp: null + name: nonadminrestores.nac.oadp.openshift.io +spec: + group: nac.oadp.openshift.io + names: + kind: NonAdminRestore + listKind: NonAdminRestoreList + plural: nonadminrestores + shortNames: + - nar + singular: nonadminrestore + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: NonAdminRestore is the Schema for the nonadminrestores API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: NonAdminRestoreSpec defines the desired state of NonAdminRestore + properties: + logLevel: + description: TODO NonAdminRestore log level, by default TODO. + enum: + - trace + - debug + - info + - warning + - error + - fatal + - panic + type: string + restoreSpec: + description: Specification for a Velero restore. + properties: + backupName: + description: |- + BackupName is the unique name of the NonAdminBackup to restore + from. + type: string + excludedNamespaces: + description: |- + ExcludedNamespaces contains a list of namespaces that are not + included in the restore. + items: + type: string + nullable: true + type: array + excludedResources: + description: |- + ExcludedResources is a slice of resource names that are not + included in the restore. + items: + type: string + nullable: true + type: array + existingResourcePolicy: + description: ExistingResourcePolicy specifies the restore behavior + for the Kubernetes resource to be restored + nullable: true + type: string + hooks: + description: Hooks represent custom behaviors that should be executed + during or post restore. + properties: + resources: + items: + description: |- + RestoreResourceHookSpec defines one or more RestoreResrouceHooks that should be executed based on + the rules defined for namespaces, resources, and label selector. + properties: + excludedNamespaces: + description: ExcludedNamespaces specifies the namespaces + to which this hook spec does not apply. + items: + type: string + nullable: true + type: array + excludedResources: + description: ExcludedResources specifies the resources + to which this hook spec does not apply. + items: + type: string + nullable: true + type: array + includedNamespaces: + description: |- + IncludedNamespaces specifies the namespaces to which this hook spec applies. If empty, it applies + to all namespaces. + items: + type: string + nullable: true + type: array + includedResources: + description: |- + IncludedResources specifies the resources to which this hook spec applies. If empty, it applies + to all resources. + items: + type: string + nullable: true + type: array + labelSelector: + description: LabelSelector, if specified, filters the + resources to which this hook spec applies. + nullable: true + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: Name is the name of this hook. + type: string + postHooks: + description: PostHooks is a list of RestoreResourceHooks + to execute during and after restoring a resource. + items: + description: RestoreResourceHook defines a restore + hook for a resource. + properties: + exec: + description: Exec defines an exec restore hook. + properties: + command: + description: Command is the command and arguments + to execute from within a container after + a pod has been restored. + items: + type: string + minItems: 1 + type: array + container: + description: |- + Container is the container in the pod where the command should be executed. If not specified, + the pod's first container is used. + type: string + execTimeout: + description: |- + ExecTimeout defines the maximum amount of time Velero should wait for the hook to complete before + considering the execution a failure. + type: string + onError: + description: OnError specifies how Velero + should behave if it encounters an error + executing this hook. + enum: + - Continue + - Fail + type: string + waitTimeout: + description: |- + WaitTimeout defines the maximum amount of time Velero should wait for the container to be Ready + before attempting to run the command. + type: string + required: + - command + type: object + init: + description: Init defines an init restore hook. + properties: + initContainers: + description: InitContainers is list of init + containers to be added to a pod during its + restore. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + x-kubernetes-preserve-unknown-fields: true + timeout: + description: Timeout defines the maximum amount + of time Velero should wait for the initContainers + to complete. + type: string + type: object + type: object + type: array + required: + - name + type: object + type: array + type: object + includeClusterResources: + description: |- + IncludeClusterResources specifies whether cluster-scoped resources + should be included for consideration in the restore. If null, defaults + to true. + nullable: true + type: boolean + includedNamespaces: + description: |- + IncludedNamespaces is a slice of namespace names to include objects + from. If empty, all namespaces are included. + items: + type: string + nullable: true + type: array + includedResources: + description: |- + IncludedResources is a slice of resource names to include + in the restore. If empty, all resources in the backup are included. + items: + type: string + nullable: true + type: array + itemOperationTimeout: + description: |- + ItemOperationTimeout specifies the time used to wait for RestoreItemAction operations + The default value is 1 hour. + type: string + labelSelector: + description: |- + LabelSelector is a metav1.LabelSelector to filter with + when restoring individual objects from the backup. If empty + or nil, all objects are included. Optional. + nullable: true + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceMapping: + additionalProperties: + type: string + description: |- + NamespaceMapping is a map of source namespace names + to target namespace names to restore into. Any source + namespaces not included in the map will be restored into + namespaces of the same name. + type: object + orLabelSelectors: + description: |- + OrLabelSelectors is list of metav1.LabelSelector to filter with + when restoring individual objects from the backup. If multiple provided + they will be joined by the OR operator. LabelSelector as well as + OrLabelSelectors cannot co-exist in restore request, only one of them + can be used + items: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + nullable: true + type: array + preserveNodePorts: + description: PreserveNodePorts specifies whether to restore old + nodePorts from backup. + nullable: true + type: boolean + resourceModifier: + description: ResourceModifier specifies the reference to JSON + resource patches that should be applied to resources before + restoration. + nullable: true + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + restorePVs: + description: |- + RestorePVs specifies whether to restore all included + PVs from snapshot + nullable: true + type: boolean + restoreStatus: + description: |- + RestoreStatus specifies which resources we should restore the status + field. If nil, no objects are included. Optional. + nullable: true + properties: + excludedResources: + description: ExcludedResources specifies the resources to + which will not restore the status. + items: + type: string + nullable: true + type: array + includedResources: + description: |- + IncludedResources specifies the resources to which will restore the status. + If empty, it applies to all resources. + items: + type: string + nullable: true + type: array + type: object + scheduleName: + description: |- + ScheduleName is the unique name of the Velero schedule to restore + from. If specified, and BackupName is empty, Velero will restore + from the most recent successful backup created from this schedule. + type: string + required: + - backupName + type: object + required: + - restoreSpec + type: object + status: + description: NonAdminRestoreStatus defines the observed state of NonAdminRestore + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + phase: + description: NonAdminPhase is a simple one high-level summary of the + lifecycle of a non admin object. + enum: + - New + - BackingOff + - Created + type: string + veleroRestoreName: + description: Related Velero Restore name. + type: string + veleroRestoreStatus: + description: Related Velero Restore status. + properties: + completionTimestamp: + description: |- + CompletionTimestamp records the time the restore operation was completed. + Completion time is recorded even on failed restore. + The server's time is used for StartTimestamps + format: date-time + nullable: true + type: string + errors: + description: |- + Errors is a count of all error messages that were generated during + execution of the restore. The actual errors are stored in object storage. + type: integer + failureReason: + description: FailureReason is an error that caused the entire + restore to fail. + type: string + phase: + description: Phase is the current state of the Restore + enum: + - New + - FailedValidation + - InProgress + - WaitingForPluginOperations + - WaitingForPluginOperationsPartiallyFailed + - Completed + - PartiallyFailed + - Failed + type: string + progress: + description: |- + Progress contains information about the restore's execution progress. Note + that this information is best-effort only -- if Velero fails to update it + during a restore for any reason, it may be inaccurate/stale. + nullable: true + properties: + itemsRestored: + description: ItemsRestored is the number of items that have + actually been restored so far + type: integer + totalItems: + description: |- + TotalItems is the total number of items to be restored. This number may change + throughout the execution of the restore due to plugins that return additional related + items to restore + type: integer + type: object + restoreItemOperationsAttempted: + description: |- + RestoreItemOperationsAttempted is the total number of attempted + async RestoreItemAction operations for this restore. + type: integer + restoreItemOperationsCompleted: + description: |- + RestoreItemOperationsCompleted is the total number of successfully completed + async RestoreItemAction operations for this restore. + type: integer + restoreItemOperationsFailed: + description: |- + RestoreItemOperationsFailed is the total number of async + RestoreItemAction operations for this restore which ended with an error. + type: integer + startTimestamp: + description: |- + StartTimestamp records the time the restore operation was started. + The server's time is used for StartTimestamps + format: date-time + nullable: true + type: string + validationErrors: + description: |- + ValidationErrors is a slice of all validation errors (if + applicable) + items: + type: string + nullable: true + type: array + warnings: + description: |- + Warnings is a count of all warning messages that were generated during + execution of the restore. The actual warnings are stored in object storage. + type: integer + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/oadp-operator.clusterserviceversion.yaml b/bundle/manifests/oadp-operator.clusterserviceversion.yaml index 40c853471a..f5285a9824 100644 --- a/bundle/manifests/oadp-operator.clusterserviceversion.yaml +++ b/bundle/manifests/oadp-operator.clusterserviceversion.yaml @@ -21,6 +21,25 @@ metadata: "backupSpec": {} } }, + { + "apiVersion": "nac.oadp.openshift.io/v1alpha1", + "kind": "NonAdminRestore", + "metadata": { + "labels": { + "app.kubernetes.io/created-by": "oadp-operator", + "app.kubernetes.io/instance": "nonadminrestore-sample", + "app.kubernetes.io/managed-by": "kustomize", + "app.kubernetes.io/name": "nonadminrestore", + "app.kubernetes.io/part-of": "oadp-operator" + }, + "name": "nonadminrestore-sample" + }, + "spec": { + "restoreSpec": { + "backupName": "nonadminbackup-sample" + } + } + }, { "apiVersion": "oadp.openshift.io/v1alpha1", "kind": "DataProtectionApplication", @@ -422,6 +441,9 @@ spec: kind: NonAdminBackup name: nonadminbackups.nac.oadp.openshift.io version: v1alpha1 + - kind: NonAdminRestore + name: nonadminrestores.nac.oadp.openshift.io + version: v1alpha1 - description: A velero pod volume backup is a restic backup of persistent volumes attached to a running pod. displayName: PodVolumeBackup @@ -629,6 +651,32 @@ spec: - get - patch - update + - apiGroups: + - nac.oadp.openshift.io + resources: + - nonadminrestores + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - nac.oadp.openshift.io + resources: + - nonadminrestores/finalizers + verbs: + - update + - apiGroups: + - nac.oadp.openshift.io + resources: + - nonadminrestores/status + verbs: + - get + - patch + - update - apiGroups: - velero.io resources: @@ -640,6 +688,17 @@ spec: - patch - update - watch + - apiGroups: + - velero.io + resources: + - restores + verbs: + - create + - get + - list + - patch + - update + - watch serviceAccountName: non-admin-controller - rules: - apiGroups: diff --git a/config/crd/bases/nac.oadp.openshift.io_nonadminbackups.yaml b/config/crd/bases/nac.oadp.openshift.io_nonadminbackups.yaml index 389c25d363..53e5b39b19 100644 --- a/config/crd/bases/nac.oadp.openshift.io_nonadminbackups.yaml +++ b/config/crd/bases/nac.oadp.openshift.io_nonadminbackups.yaml @@ -11,6 +11,8 @@ spec: kind: NonAdminBackup listKind: NonAdminBackupList plural: nonadminbackups + shortNames: + - nab singular: nonadminbackup scope: Namespaced versions: @@ -503,8 +505,110 @@ spec: type: string type: array type: object - backupStatus: - description: BackupStatus captures the current status of a Velero + logLevel: + description: NonAdminBackup log level (use debug for the most logging, + leave unset for default) + enum: + - trace + - debug + - info + - warning + - error + - fatal + - panic + type: string + type: object + status: + description: NonAdminBackupStatus defines the observed state of NonAdminBackup + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + phase: + description: NonAdminPhase is a simple one high-level summary of the + lifecycle of a non admin object. + enum: + - New + - BackingOff + - Created + type: string + veleroBackupName: + description: VeleroBackupName references the VeleroBackup object by + it's name. + type: string + veleroBackupNamespace: + description: |- + VeleroBackupNamespace references the Namespace + in which VeleroBackupName object exists. + type: string + veleroBackupStatus: + description: VeleroBackupStatus captures the current status of a Velero backup. properties: backupItemOperationsAttempted: @@ -634,91 +738,6 @@ spec: file in object storage. type: integer type: object - logLevel: - description: NonAdminBackup log level (use debug for the most logging, - leave unset for default) - enum: - - trace - - debug - - info - - warning - - error - - fatal - - panic - type: string - type: object - status: - description: NonAdminBackupStatus defines the observed state of NonAdminBackup - properties: - conditions: - items: - description: "Condition contains details for one aspect of the current - state of this API Resource.\n---\nThis struct is intended for - direct use as an array at the field path .status.conditions. For - example,\n\n\n\ttype FooStatus struct{\n\t // Represents the - observations of a foo's current state.\n\t // Known .status.conditions.type - are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // - +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t - \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t - \ // other fields\n\t}" - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - --- - Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be - useful (see .node.status.conditions), the ability to deconflict is important. - The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array type: object type: object served: true diff --git a/config/crd/bases/nac.oadp.openshift.io_nonadminrestores.yaml b/config/crd/bases/nac.oadp.openshift.io_nonadminrestores.yaml new file mode 100644 index 0000000000..fa420e3d59 --- /dev/null +++ b/config/crd/bases/nac.oadp.openshift.io_nonadminrestores.yaml @@ -0,0 +1,625 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: nonadminrestores.nac.oadp.openshift.io +spec: + group: nac.oadp.openshift.io + names: + kind: NonAdminRestore + listKind: NonAdminRestoreList + plural: nonadminrestores + shortNames: + - nar + singular: nonadminrestore + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: NonAdminRestore is the Schema for the nonadminrestores API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: NonAdminRestoreSpec defines the desired state of NonAdminRestore + properties: + logLevel: + description: TODO NonAdminRestore log level, by default TODO. + enum: + - trace + - debug + - info + - warning + - error + - fatal + - panic + type: string + restoreSpec: + description: Specification for a Velero restore. + properties: + backupName: + description: |- + BackupName is the unique name of the NonAdminBackup to restore + from. + type: string + excludedNamespaces: + description: |- + ExcludedNamespaces contains a list of namespaces that are not + included in the restore. + items: + type: string + nullable: true + type: array + excludedResources: + description: |- + ExcludedResources is a slice of resource names that are not + included in the restore. + items: + type: string + nullable: true + type: array + existingResourcePolicy: + description: ExistingResourcePolicy specifies the restore behavior + for the Kubernetes resource to be restored + nullable: true + type: string + hooks: + description: Hooks represent custom behaviors that should be executed + during or post restore. + properties: + resources: + items: + description: |- + RestoreResourceHookSpec defines one or more RestoreResrouceHooks that should be executed based on + the rules defined for namespaces, resources, and label selector. + properties: + excludedNamespaces: + description: ExcludedNamespaces specifies the namespaces + to which this hook spec does not apply. + items: + type: string + nullable: true + type: array + excludedResources: + description: ExcludedResources specifies the resources + to which this hook spec does not apply. + items: + type: string + nullable: true + type: array + includedNamespaces: + description: |- + IncludedNamespaces specifies the namespaces to which this hook spec applies. If empty, it applies + to all namespaces. + items: + type: string + nullable: true + type: array + includedResources: + description: |- + IncludedResources specifies the resources to which this hook spec applies. If empty, it applies + to all resources. + items: + type: string + nullable: true + type: array + labelSelector: + description: LabelSelector, if specified, filters the + resources to which this hook spec applies. + nullable: true + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: Name is the name of this hook. + type: string + postHooks: + description: PostHooks is a list of RestoreResourceHooks + to execute during and after restoring a resource. + items: + description: RestoreResourceHook defines a restore + hook for a resource. + properties: + exec: + description: Exec defines an exec restore hook. + properties: + command: + description: Command is the command and arguments + to execute from within a container after + a pod has been restored. + items: + type: string + minItems: 1 + type: array + container: + description: |- + Container is the container in the pod where the command should be executed. If not specified, + the pod's first container is used. + type: string + execTimeout: + description: |- + ExecTimeout defines the maximum amount of time Velero should wait for the hook to complete before + considering the execution a failure. + type: string + onError: + description: OnError specifies how Velero + should behave if it encounters an error + executing this hook. + enum: + - Continue + - Fail + type: string + waitTimeout: + description: |- + WaitTimeout defines the maximum amount of time Velero should wait for the container to be Ready + before attempting to run the command. + type: string + required: + - command + type: object + init: + description: Init defines an init restore hook. + properties: + initContainers: + description: InitContainers is list of init + containers to be added to a pod during its + restore. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + x-kubernetes-preserve-unknown-fields: true + timeout: + description: Timeout defines the maximum amount + of time Velero should wait for the initContainers + to complete. + type: string + type: object + type: object + type: array + required: + - name + type: object + type: array + type: object + includeClusterResources: + description: |- + IncludeClusterResources specifies whether cluster-scoped resources + should be included for consideration in the restore. If null, defaults + to true. + nullable: true + type: boolean + includedNamespaces: + description: |- + IncludedNamespaces is a slice of namespace names to include objects + from. If empty, all namespaces are included. + items: + type: string + nullable: true + type: array + includedResources: + description: |- + IncludedResources is a slice of resource names to include + in the restore. If empty, all resources in the backup are included. + items: + type: string + nullable: true + type: array + itemOperationTimeout: + description: |- + ItemOperationTimeout specifies the time used to wait for RestoreItemAction operations + The default value is 1 hour. + type: string + labelSelector: + description: |- + LabelSelector is a metav1.LabelSelector to filter with + when restoring individual objects from the backup. If empty + or nil, all objects are included. Optional. + nullable: true + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceMapping: + additionalProperties: + type: string + description: |- + NamespaceMapping is a map of source namespace names + to target namespace names to restore into. Any source + namespaces not included in the map will be restored into + namespaces of the same name. + type: object + orLabelSelectors: + description: |- + OrLabelSelectors is list of metav1.LabelSelector to filter with + when restoring individual objects from the backup. If multiple provided + they will be joined by the OR operator. LabelSelector as well as + OrLabelSelectors cannot co-exist in restore request, only one of them + can be used + items: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + nullable: true + type: array + preserveNodePorts: + description: PreserveNodePorts specifies whether to restore old + nodePorts from backup. + nullable: true + type: boolean + resourceModifier: + description: ResourceModifier specifies the reference to JSON + resource patches that should be applied to resources before + restoration. + nullable: true + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + restorePVs: + description: |- + RestorePVs specifies whether to restore all included + PVs from snapshot + nullable: true + type: boolean + restoreStatus: + description: |- + RestoreStatus specifies which resources we should restore the status + field. If nil, no objects are included. Optional. + nullable: true + properties: + excludedResources: + description: ExcludedResources specifies the resources to + which will not restore the status. + items: + type: string + nullable: true + type: array + includedResources: + description: |- + IncludedResources specifies the resources to which will restore the status. + If empty, it applies to all resources. + items: + type: string + nullable: true + type: array + type: object + scheduleName: + description: |- + ScheduleName is the unique name of the Velero schedule to restore + from. If specified, and BackupName is empty, Velero will restore + from the most recent successful backup created from this schedule. + type: string + required: + - backupName + type: object + required: + - restoreSpec + type: object + status: + description: NonAdminRestoreStatus defines the observed state of NonAdminRestore + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + phase: + description: NonAdminPhase is a simple one high-level summary of the + lifecycle of a non admin object. + enum: + - New + - BackingOff + - Created + type: string + veleroRestoreName: + description: Related Velero Restore name. + type: string + veleroRestoreStatus: + description: Related Velero Restore status. + properties: + completionTimestamp: + description: |- + CompletionTimestamp records the time the restore operation was completed. + Completion time is recorded even on failed restore. + The server's time is used for StartTimestamps + format: date-time + nullable: true + type: string + errors: + description: |- + Errors is a count of all error messages that were generated during + execution of the restore. The actual errors are stored in object storage. + type: integer + failureReason: + description: FailureReason is an error that caused the entire + restore to fail. + type: string + phase: + description: Phase is the current state of the Restore + enum: + - New + - FailedValidation + - InProgress + - WaitingForPluginOperations + - WaitingForPluginOperationsPartiallyFailed + - Completed + - PartiallyFailed + - Failed + type: string + progress: + description: |- + Progress contains information about the restore's execution progress. Note + that this information is best-effort only -- if Velero fails to update it + during a restore for any reason, it may be inaccurate/stale. + nullable: true + properties: + itemsRestored: + description: ItemsRestored is the number of items that have + actually been restored so far + type: integer + totalItems: + description: |- + TotalItems is the total number of items to be restored. This number may change + throughout the execution of the restore due to plugins that return additional related + items to restore + type: integer + type: object + restoreItemOperationsAttempted: + description: |- + RestoreItemOperationsAttempted is the total number of attempted + async RestoreItemAction operations for this restore. + type: integer + restoreItemOperationsCompleted: + description: |- + RestoreItemOperationsCompleted is the total number of successfully completed + async RestoreItemAction operations for this restore. + type: integer + restoreItemOperationsFailed: + description: |- + RestoreItemOperationsFailed is the total number of async + RestoreItemAction operations for this restore which ended with an error. + type: integer + startTimestamp: + description: |- + StartTimestamp records the time the restore operation was started. + The server's time is used for StartTimestamps + format: date-time + nullable: true + type: string + validationErrors: + description: |- + ValidationErrors is a slice of all validation errors (if + applicable) + items: + type: string + nullable: true + type: array + warnings: + description: |- + Warnings is a count of all warning messages that were generated during + execution of the restore. The actual warnings are stored in object storage. + type: integer + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index b0ab8b5fe4..44fd842160 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -18,6 +18,7 @@ resources: - bases/velero.io_serverstatusrequests.yaml - bases/velero.io_volumesnapshotlocations.yaml - bases/nac.oadp.openshift.io_nonadminbackups.yaml +- bases/nac.oadp.openshift.io_nonadminrestores.yaml #+kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: diff --git a/config/non-admin-controller_rbac/role.yaml b/config/non-admin-controller_rbac/role.yaml index 3b3efada80..58ffd37fee 100644 --- a/config/non-admin-controller_rbac/role.yaml +++ b/config/non-admin-controller_rbac/role.yaml @@ -30,6 +30,32 @@ rules: - get - patch - update +- apiGroups: + - nac.oadp.openshift.io + resources: + - nonadminrestores + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - nac.oadp.openshift.io + resources: + - nonadminrestores/finalizers + verbs: + - update +- apiGroups: + - nac.oadp.openshift.io + resources: + - nonadminrestores/status + verbs: + - get + - patch + - update - apiGroups: - velero.io resources: @@ -41,3 +67,14 @@ rules: - patch - update - watch +- apiGroups: + - velero.io + resources: + - restores + verbs: + - create + - get + - list + - patch + - update + - watch diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index e56c745767..41ee0b21db 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -13,4 +13,5 @@ resources: - serverstatusrequest.yaml - volumesnapshotlocation.yaml - nac_v1alpha1_nonadminbackup.yaml +- nac_v1alpha1_nonadminrestore.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/nac_v1alpha1_nonadminrestore.yaml b/config/samples/nac_v1alpha1_nonadminrestore.yaml new file mode 100644 index 0000000000..c8e2e2fd59 --- /dev/null +++ b/config/samples/nac_v1alpha1_nonadminrestore.yaml @@ -0,0 +1,13 @@ +apiVersion: nac.oadp.openshift.io/v1alpha1 +kind: NonAdminRestore +metadata: + labels: + app.kubernetes.io/name: nonadminrestore + app.kubernetes.io/instance: nonadminrestore-sample + app.kubernetes.io/part-of: oadp-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: oadp-operator + name: nonadminrestore-sample +spec: + restoreSpec: + backupName: nonadminbackup-sample diff --git a/tests/e2e/nonadmin_controller_suite_test.go b/tests/e2e/nonadmin_controller_suite_test.go new file mode 100644 index 0000000000..a0535442fe --- /dev/null +++ b/tests/e2e/nonadmin_controller_suite_test.go @@ -0,0 +1,62 @@ +package e2e_test + +import ( + "context" + + "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/openshift/oadp-operator/tests/e2e/lib" +) + +type NonAdminCRDCase struct { + spec map[string]any +} + +const nonAdminCRDNamespace = "test-non-admin-controller" + +var nonAdminRestoreResource = schema.GroupVersionResource{ + Group: "nac.oadp.openshift.io", + Version: "v1alpha1", + Resource: "nonadminrestores", +} + +var _ = ginkgo.Describe("Test NonAdminRestore in cluster validation", func() { + var _ = ginkgo.BeforeAll(func() { + err := lib.CreateNamespace(kubernetesClientForSuiteRun, nonAdminCRDNamespace) + gomega.Expect(err).To(gomega.BeNil()) + }) + + var _ = ginkgo.AfterAll(func() { + err := lib.DeleteNamespace(kubernetesClientForSuiteRun, nonAdminCRDNamespace) + gomega.Expect(err).To(gomega.BeNil()) + }) + + ginkgo.DescribeTable("Validation is false", + func(scenario NonAdminCRDCase) { + nonAdminRestore := &unstructured.Unstructured{Object: map[string]any{ + "apiVersion": "nac.oadp.openshift.io/v1alpha1", + "kind": "NonAdminRestore", + "metadata": map[string]string{ + "name": "wrong-spec", + "namespace": nonAdminCRDNamespace, + }, + "spec": scenario.spec, + }} + _, err := dynamicClientForSuiteRun.Resource(nonAdminRestoreResource).Namespace(nonAdminCRDNamespace).Create(context.Background(), nonAdminRestore, v1.CreateOptions{}) + gomega.Expect(err).To(gomega.Not(gomega.BeNil())) + gomega.Expect(err.Error()).To(gomega.ContainSubstring("Required value")) + }, + ginkgo.Entry("Should NOT create NonAdminRestore without spec.restoreSpec", NonAdminCRDCase{ + spec: map[string]any{}, + }), + ginkgo.Entry("Should NOT create NonAdminRestore without spec.restoreSpec.backupName", NonAdminCRDCase{ + spec: map[string]any{ + "restoreSpec": map[string]any{}, + }, + }), + ) +})