mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-05-02 13:25:48 +00:00
Merge branch 'main' into issue-fix-5875
This commit is contained in:
2
.github/workflows/pr-codespell.yml
vendored
2
.github/workflows/pr-codespell.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
uses: codespell-project/actions-codespell@master
|
||||
with:
|
||||
# ignore the config/.../crd.go file as it's generated binary data that is edited elswhere.
|
||||
skip: .git,*.png,*.jpg,*.woff,*.ttf,*.gif,*.ico,./config/crd/v1beta1/crds/crds.go,./config/crd/v1/crds/crds.go,./go.sum,./LICENSE
|
||||
skip: .git,*.png,*.jpg,*.woff,*.ttf,*.gif,*.ico,./config/crd/v1beta1/crds/crds.go,./config/crd/v1/crds/crds.go,,./config/crd/v2alpha1/crds/crds.go,./go.sum,./LICENSE
|
||||
ignore_words_list: iam,aks,ist,bridget,ue,shouldnot,atleast
|
||||
check_filenames: true
|
||||
check_hidden: true
|
||||
|
||||
@@ -68,7 +68,7 @@ RUN mkdir -p /output/usr/bin && \
|
||||
# Velero image packing section
|
||||
FROM gcr.io/distroless/base-nossl-debian11:nonroot
|
||||
|
||||
LABEL maintainer="Nolan Brubaker <brubakern@vmware.com>"
|
||||
LABEL maintainer="Xun Jiang <jxun@vmware.com>"
|
||||
|
||||
COPY --from=velero-builder /output /
|
||||
|
||||
|
||||
4
Makefile
4
Makefile
@@ -229,6 +229,10 @@ endif
|
||||
update:
|
||||
@$(MAKE) shell CMD="-c 'hack/update-all.sh'"
|
||||
|
||||
# update-crd is for development purpose only, it is faster than update, so is a shortcut when you want to generate CRD changes only
|
||||
update-crd:
|
||||
@$(MAKE) shell CMD="-c 'hack/update-3generated-crd-code.sh'"
|
||||
|
||||
build-dirs:
|
||||
@mkdir -p _output/bin/$(GOOS)/$(GOARCH)
|
||||
@mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH) .go/go-build .go/golangci-lint
|
||||
|
||||
4
Tiltfile
4
Tiltfile
@@ -12,6 +12,8 @@ k8s_yaml([
|
||||
'config/crd/v1/bases/velero.io_schedules.yaml',
|
||||
'config/crd/v1/bases/velero.io_serverstatusrequests.yaml',
|
||||
'config/crd/v1/bases/velero.io_volumesnapshotlocations.yaml',
|
||||
'config/crd/v2alpha1/bases/velero.io_datauploads.yaml',
|
||||
'config/crd/v2alpha1/bases/velero.io_datadownloads.yaml',
|
||||
])
|
||||
|
||||
# default values
|
||||
@@ -60,7 +62,7 @@ RUN wget --output-document /restart.sh --quiet https://raw.githubusercontent.com
|
||||
|
||||
additional_docker_helper_commands = """
|
||||
# Install delve to allow debugging
|
||||
RUN go get github.com/go-delve/delve/cmd/dlv
|
||||
RUN go install github.com/go-delve/delve/cmd/dlv@latest
|
||||
|
||||
RUN wget -qO- https://dl.k8s.io/v1.25.2/kubernetes-client-linux-amd64.tar.gz | tar xvz
|
||||
RUN wget -qO- https://get.docker.com | sh
|
||||
|
||||
2
changelogs/unreleased/6111-eemcmullan
Normal file
2
changelogs/unreleased/6111-eemcmullan
Normal file
@@ -0,0 +1,2 @@
|
||||
Remove any dataSource or dataSourceRef fields from PVCs in PVC BIA for cases of
|
||||
prior PVC restores with CSI
|
||||
1
changelogs/unreleased/6176-Lyndon-Li
Normal file
1
changelogs/unreleased/6176-Lyndon-Li
Normal file
@@ -0,0 +1 @@
|
||||
Add data mover CRD under v2alpha1, include DataUpload CRD and DataDownload CRD
|
||||
1
changelogs/unreleased/6232-kaovilai
Normal file
1
changelogs/unreleased/6232-kaovilai
Normal file
@@ -0,0 +1 @@
|
||||
log volumes to backup to help debug why `IsPodRunning` is called.
|
||||
1
changelogs/unreleased/6268-Lyndon-Li
Normal file
1
changelogs/unreleased/6268-Lyndon-Li
Normal file
@@ -0,0 +1 @@
|
||||
Fix issue #5123, Kopia repository supports self-cert CA for S3 compatible storage.
|
||||
@@ -40,6 +40,11 @@ spec:
|
||||
CSI VolumeSnapshot status turns to ReadyToUse during creation, before
|
||||
returning error as timeout. The default value is 10 minute.
|
||||
type: string
|
||||
datamover:
|
||||
description: DataMover specifies the data mover to be used by the
|
||||
backup. If DataMover is "" or "velero", the built-in data mover
|
||||
will be used.
|
||||
type: string
|
||||
defaultVolumesToFsBackup:
|
||||
description: DefaultVolumesToFsBackup specifies whether pod volume
|
||||
file system backup should be used for all volumes by default.
|
||||
@@ -454,6 +459,11 @@ spec:
|
||||
- name
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
snapshotMoveData:
|
||||
description: SnapshotMoveData specifies whether snapshot data should
|
||||
be moved
|
||||
nullable: true
|
||||
type: boolean
|
||||
snapshotVolumes:
|
||||
description: SnapshotVolumes specifies whether to take snapshots of
|
||||
any PV's referenced in the set of objects included in the Backup.
|
||||
|
||||
@@ -70,6 +70,11 @@ spec:
|
||||
for CSI VolumeSnapshot status turns to ReadyToUse during creation,
|
||||
before returning error as timeout. The default value is 10 minute.
|
||||
type: string
|
||||
datamover:
|
||||
description: DataMover specifies the data mover to be used by
|
||||
the backup. If DataMover is "" or "velero", the built-in data
|
||||
mover will be used.
|
||||
type: string
|
||||
defaultVolumesToFsBackup:
|
||||
description: DefaultVolumesToFsBackup specifies whether pod volume
|
||||
file system backup should be used for all volumes by default.
|
||||
@@ -490,6 +495,11 @@ spec:
|
||||
- name
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
snapshotMoveData:
|
||||
description: SnapshotMoveData specifies whether snapshot data
|
||||
should be moved
|
||||
nullable: true
|
||||
type: boolean
|
||||
snapshotVolumes:
|
||||
description: SnapshotVolumes specifies whether to take snapshots
|
||||
of any PV's referenced in the set of objects included in the
|
||||
|
||||
File diff suppressed because one or more lines are too long
169
config/crd/v2alpha1/bases/velero.io_datadownloads.yaml
Normal file
169
config/crd/v2alpha1/bases/velero.io_datadownloads.yaml
Normal file
@@ -0,0 +1,169 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.12.0
|
||||
name: datadownloads.velero.io
|
||||
spec:
|
||||
group: velero.io
|
||||
names:
|
||||
kind: DataDownload
|
||||
listKind: DataDownloadList
|
||||
plural: datadownloads
|
||||
singular: datadownload
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- description: DataDownload status such as New/InProgress
|
||||
jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- description: Time duration since this DataDownload was started
|
||||
jsonPath: .status.startTimestamp
|
||||
name: Started
|
||||
type: date
|
||||
- description: Completed bytes
|
||||
format: int64
|
||||
jsonPath: .status.progress.bytesDone
|
||||
name: Bytes Done
|
||||
type: integer
|
||||
- description: Total bytes
|
||||
format: int64
|
||||
jsonPath: .status.progress.totalBytes
|
||||
name: Total Bytes
|
||||
type: integer
|
||||
- description: Name of the Backup Storage Location where the backup data is stored
|
||||
jsonPath: .spec.backupStorageLocation
|
||||
name: Storage Location
|
||||
type: string
|
||||
- description: Time duration since this DataDownload was created
|
||||
jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v2alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
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: DataDownloadSpec is the specification for a DataDownload.
|
||||
properties:
|
||||
backupStorageLocation:
|
||||
description: BackupStorageLocation is the name of the backup storage
|
||||
location where the backup repository is stored.
|
||||
type: string
|
||||
cancel:
|
||||
description: Cancel indicates request to cancel the ongoing DataDownload.
|
||||
It can be set when the DataDownload is in InProgress phase
|
||||
type: boolean
|
||||
dataMoverConfig:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: DataMoverConfig is for data-mover-specific configuration
|
||||
fields.
|
||||
type: object
|
||||
datamover:
|
||||
description: DataMover specifies the data mover to be used by the
|
||||
backup. If DataMover is "" or "velero", the built-in data mover
|
||||
will be used.
|
||||
type: string
|
||||
operationTimeout:
|
||||
description: OperationTimeout specifies the time used to wait internal
|
||||
operations, before returning error as timeout.
|
||||
type: string
|
||||
snapshotID:
|
||||
description: SnapshotID is the ID of the Velero backup snapshot to
|
||||
be restored from.
|
||||
type: string
|
||||
sourceNamespace:
|
||||
description: SourceNamespace is the original namespace where the volume
|
||||
is backed up from. It may be different from SourcePVC's namespace
|
||||
if namespace is remapped during restore.
|
||||
type: string
|
||||
targetVolume:
|
||||
description: TargetVolume is the information of the target PVC and
|
||||
PV.
|
||||
properties:
|
||||
namespace:
|
||||
description: Namespace is the target namespace
|
||||
type: string
|
||||
pv:
|
||||
description: PV is the name of the target PV that is created by
|
||||
Velero restore
|
||||
type: string
|
||||
pvc:
|
||||
description: PVC is the name of the target PVC that is created
|
||||
by Velero restore
|
||||
type: string
|
||||
required:
|
||||
- namespace
|
||||
- pv
|
||||
- pvc
|
||||
type: object
|
||||
required:
|
||||
- backupStorageLocation
|
||||
- operationTimeout
|
||||
- snapshotID
|
||||
- sourceNamespace
|
||||
- targetVolume
|
||||
type: object
|
||||
status:
|
||||
description: DataDownloadStatus is the current status of a DataDownload.
|
||||
properties:
|
||||
completionTimestamp:
|
||||
description: CompletionTimestamp records the time a restore was completed.
|
||||
Completion time is recorded even on failed restores. The server's
|
||||
time is used for CompletionTimestamps
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
message:
|
||||
description: Message is a message about the DataDownload's status.
|
||||
type: string
|
||||
phase:
|
||||
description: Phase is the current state of the DataDownload.
|
||||
enum:
|
||||
- New
|
||||
- Accepted
|
||||
- Prepared
|
||||
- InProgress
|
||||
- Canceling
|
||||
- Canceled
|
||||
- Completed
|
||||
- Failed
|
||||
type: string
|
||||
progress:
|
||||
description: Progress holds the total number of bytes of the snapshot
|
||||
and the current number of restored bytes. This can be used to display
|
||||
progress information about the restore operation.
|
||||
properties:
|
||||
bytesDone:
|
||||
format: int64
|
||||
type: integer
|
||||
totalBytes:
|
||||
format: int64
|
||||
type: integer
|
||||
type: object
|
||||
startTimestamp:
|
||||
description: StartTimestamp records the time a restore was started.
|
||||
The server's time is used for StartTimestamps
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources: {}
|
||||
193
config/crd/v2alpha1/bases/velero.io_datauploads.yaml
Normal file
193
config/crd/v2alpha1/bases/velero.io_datauploads.yaml
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.12.0
|
||||
name: datauploads.velero.io
|
||||
spec:
|
||||
group: velero.io
|
||||
names:
|
||||
kind: DataUpload
|
||||
listKind: DataUploadList
|
||||
plural: datauploads
|
||||
singular: dataupload
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- description: DataUpload status such as New/InProgress
|
||||
jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- description: Time duration since this DataUpload was started
|
||||
jsonPath: .status.startTimestamp
|
||||
name: Started
|
||||
type: date
|
||||
- description: Completed bytes
|
||||
format: int64
|
||||
jsonPath: .status.progress.bytesDone
|
||||
name: Bytes Done
|
||||
type: integer
|
||||
- description: Total bytes
|
||||
format: int64
|
||||
jsonPath: .status.progress.totalBytes
|
||||
name: Total Bytes
|
||||
type: integer
|
||||
- description: Name of the Backup Storage Location where this backup should be
|
||||
stored
|
||||
jsonPath: .spec.backupStorageLocation
|
||||
name: Storage Location
|
||||
type: string
|
||||
- description: Time duration since this DataUpload was created
|
||||
jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v2alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
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: DataUploadSpec is the specification for a DataUpload.
|
||||
properties:
|
||||
backupStorageLocation:
|
||||
description: BackupStorageLocation is the name of the backup storage
|
||||
location where the backup repository is stored.
|
||||
type: string
|
||||
cancel:
|
||||
description: Cancel indicates request to cancel the ongoing DataUpload.
|
||||
It can be set when the DataUpload is in InProgress phase
|
||||
type: boolean
|
||||
csiSnapshot:
|
||||
description: If SnapshotType is CSI, CSISnapshot provides the information
|
||||
of the CSI snapshot.
|
||||
nullable: true
|
||||
properties:
|
||||
snapshotClass:
|
||||
description: StorageClass is the name of the snapshot class that
|
||||
the volume snapshot is created with
|
||||
type: string
|
||||
storageClass:
|
||||
description: StorageClass is the name of the storage class of
|
||||
the PVC that the volume snapshot is created from
|
||||
type: string
|
||||
volumeSnapshot:
|
||||
description: VolumeSnapshot is the name of the volume snapshot
|
||||
to be backed up
|
||||
type: string
|
||||
required:
|
||||
- storageClass
|
||||
- volumeSnapshot
|
||||
type: object
|
||||
dataMoverConfig:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: DataMoverConfig is for data-mover-specific configuration
|
||||
fields.
|
||||
nullable: true
|
||||
type: object
|
||||
datamover:
|
||||
description: DataMover specifies the data mover to be used by the
|
||||
backup. If DataMover is "" or "velero", the built-in data mover
|
||||
will be used.
|
||||
type: string
|
||||
operationTimeout:
|
||||
description: OperationTimeout specifies the time used to wait internal
|
||||
operations, before returning error as timeout.
|
||||
type: string
|
||||
snapshotType:
|
||||
description: SnapshotType is the type of the snapshot to be backed
|
||||
up.
|
||||
type: string
|
||||
sourceNamespace:
|
||||
description: SourceNamespace is the original namespace where the volume
|
||||
is backed up from. It is the same namespace for SourcePVC and CSI
|
||||
namespaced objects.
|
||||
type: string
|
||||
sourcePVC:
|
||||
description: SourcePVC is the name of the PVC which the snapshot is
|
||||
taken for.
|
||||
type: string
|
||||
required:
|
||||
- backupStorageLocation
|
||||
- operationTimeout
|
||||
- snapshotType
|
||||
- sourceNamespace
|
||||
- sourcePVC
|
||||
type: object
|
||||
status:
|
||||
description: DataUploadStatus is the current status of a DataUpload.
|
||||
properties:
|
||||
completionTimestamp:
|
||||
description: CompletionTimestamp records the time a backup was completed.
|
||||
Completion time is recorded even on failed backups. Completion time
|
||||
is recorded before uploading the backup object. The server's time
|
||||
is used for CompletionTimestamps
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
dataMoverResult:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: DataMoverResult stores data-mover-specific information
|
||||
as a result of the DataUpload.
|
||||
nullable: true
|
||||
type: object
|
||||
message:
|
||||
description: Message is a message about the DataUpload's status.
|
||||
type: string
|
||||
path:
|
||||
description: Path is the full path of the snapshot volume being backed
|
||||
up.
|
||||
type: string
|
||||
phase:
|
||||
description: Phase is the current state of the DataUpload.
|
||||
enum:
|
||||
- New
|
||||
- Accepted
|
||||
- Prepared
|
||||
- InProgress
|
||||
- Canceling
|
||||
- Canceled
|
||||
- Completed
|
||||
- Failed
|
||||
type: string
|
||||
progress:
|
||||
description: Progress holds the total number of bytes of the volume
|
||||
and the current number of backed up bytes. This can be used to display
|
||||
progress information about the backup operation.
|
||||
properties:
|
||||
bytesDone:
|
||||
format: int64
|
||||
type: integer
|
||||
totalBytes:
|
||||
format: int64
|
||||
type: integer
|
||||
type: object
|
||||
snapshotID:
|
||||
description: SnapshotID is the identifier for the snapshot in the
|
||||
backup repository.
|
||||
type: string
|
||||
startTimestamp:
|
||||
description: StartTimestamp records the time a backup was started.
|
||||
Separate from CreationTimestamp, since that value changes on restores.
|
||||
The server's time is used for StartTimestamps
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources: {}
|
||||
60
config/crd/v2alpha1/crds/crds.go
Normal file
60
config/crd/v2alpha1/crds/crds.go
Normal file
File diff suppressed because one or more lines are too long
4
config/crd/v2alpha1/crds/doc.go
Normal file
4
config/crd/v2alpha1/crds/doc.go
Normal file
@@ -0,0 +1,4 @@
|
||||
// Package crds embeds the controller-tools generated CRD manifests
|
||||
package crds
|
||||
|
||||
//go:generate go run ../../../../hack/crd-gen/v1/main.go
|
||||
@@ -82,6 +82,46 @@ rules:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- velero.io
|
||||
resources:
|
||||
- datadownloads
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- velero.io
|
||||
resources:
|
||||
- datadownloads/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- velero.io
|
||||
resources:
|
||||
- datauploads
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- velero.io
|
||||
resources:
|
||||
- datauploads/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- velero.io
|
||||
resources:
|
||||
|
||||
@@ -57,7 +57,7 @@ spec:
|
||||
- emptyDir: {}
|
||||
name: scratch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
labels:
|
||||
|
||||
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This code embeds the CRD manifests in config/crd/v1/bases in
|
||||
// config/crd/v1/crds/crds.go.
|
||||
// This code embeds the CRD manifests in ../bases in ../crds/crds.go
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -35,13 +35,11 @@ fi
|
||||
|
||||
files="$(find . -type f -name '*.go' -not -path './.go/*' -not -path './vendor/*' -not -path './site/*' -not -path '*/generated/*' -not -name 'zz_generated*' -not -path '*/mocks/*')"
|
||||
echo "${ACTION} gofmt"
|
||||
for file in ${files}; do
|
||||
output=$(gofmt "${MODE}" -s "${file}")
|
||||
if [[ -n "${output}" ]]; then
|
||||
VERIFY_FMT_FAILED=1
|
||||
echo "${output}"
|
||||
fi
|
||||
done
|
||||
output=$(printf '%s\n' "${files}" | xargs gofmt "${MODE}" -s)
|
||||
if [[ -n "${output}" ]]; then
|
||||
VERIFY_FMT_FAILED=1
|
||||
echo "${output}"
|
||||
fi
|
||||
if [[ -n "${VERIFY_FMT_FAILED:-}" ]]; then
|
||||
echo "${ACTION} gofmt - failed! Please run 'make update'."
|
||||
else
|
||||
@@ -49,13 +47,11 @@ else
|
||||
fi
|
||||
|
||||
echo "${ACTION} goimports"
|
||||
for file in ${files}; do
|
||||
output=$(goimports "${MODE}" -local github.com/vmware-tanzu/velero "${file}")
|
||||
if [[ -n "${output}" ]]; then
|
||||
VERIFY_IMPORTS_FAILED=1
|
||||
echo "${output}"
|
||||
fi
|
||||
done
|
||||
output=$(printf '%s\n' "${files}" | xargs goimports "${MODE}" -local github.com/vmware-tanzu/velero)
|
||||
if [[ -n "${output}" ]]; then
|
||||
VERIFY_IMPORTS_FAILED=1
|
||||
echo "${output}"
|
||||
fi
|
||||
if [[ -n "${VERIFY_IMPORTS_FAILED:-}" ]]; then
|
||||
echo "${ACTION} goimports - failed! Please run 'make update'."
|
||||
else
|
||||
|
||||
@@ -40,20 +40,38 @@ ${GOPATH}/src/k8s.io/code-generator/generate-groups.sh \
|
||||
all \
|
||||
github.com/vmware-tanzu/velero/pkg/generated \
|
||||
github.com/vmware-tanzu/velero/pkg/apis \
|
||||
"velero:v1" \
|
||||
"velero:v1,v2alpha1" \
|
||||
--go-header-file ./hack/boilerplate.go.txt \
|
||||
--output-base ../../.. \
|
||||
$@
|
||||
|
||||
# Generate apiextensions.k8s.io/v1
|
||||
# Generate manifests e.g. CRD, RBAC etc.
|
||||
|
||||
# Generate CRD for v1.
|
||||
controller-gen \
|
||||
crd:crdVersions=v1 \
|
||||
paths=./pkg/apis/velero/v1/... \
|
||||
rbac:roleName=velero-perms \
|
||||
paths=./pkg/controller/... \
|
||||
output:crd:artifacts:config=config/crd/v1/bases \
|
||||
object \
|
||||
paths=./pkg/apis/velero/v1/...
|
||||
|
||||
# Generate CRD for v2alpha1.
|
||||
controller-gen \
|
||||
crd:crdVersions=v1 \
|
||||
paths=./pkg/apis/velero/v2alpha1/... \
|
||||
paths=./pkg/controller/... \
|
||||
output:crd:artifacts:config=config/crd/v2alpha1/bases \
|
||||
object \
|
||||
paths=./pkg/apis/velero/v2alpha1/...
|
||||
|
||||
# Generate RBAC.
|
||||
controller-gen \
|
||||
paths=./pkg/apis/velero/v1/... \
|
||||
paths=./pkg/apis/velero/v2alpha1/... \
|
||||
paths=./pkg/controller/... \
|
||||
rbac:roleName=velero-perms
|
||||
|
||||
go generate ./config/crd/v1/crds
|
||||
|
||||
go generate ./config/crd/v2alpha1/crds
|
||||
|
||||
@@ -19,7 +19,7 @@ HACK_DIR=$(dirname "${BASH_SOURCE}")
|
||||
${HACK_DIR}/update-3generated-crd-code.sh
|
||||
|
||||
# ensure no changes to generated CRDs
|
||||
if ! git diff --exit-code config/crd/v1/crds/crds.go >/dev/null; then
|
||||
if [! git diff --exit-code config/crd/v1/crds/crds.go config/crd/v2alpha1/crds/crds.go >/dev/null]; then
|
||||
# revert changes to state before running CRD generation to stay consistent
|
||||
# with code-generator `--verify-only` option which discards generated changes
|
||||
git checkout config/crd
|
||||
|
||||
@@ -14,11 +14,13 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
package shared
|
||||
|
||||
// PodVolumeOperationProgress represents the progress of a
|
||||
// PodVolumeBackup/Restore operation
|
||||
type PodVolumeOperationProgress struct {
|
||||
// DataMoveOperationProgress represents the progress of a
|
||||
// data movement operation
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type DataMoveOperationProgress struct {
|
||||
// +optional
|
||||
TotalBytes int64 `json:"totalBytes,omitempty"`
|
||||
|
||||
@@ -165,6 +165,16 @@ type BackupSpec struct {
|
||||
// ResourcePolicy specifies the referenced resource policies that backup should follow
|
||||
// +optional
|
||||
ResourcePolicy *v1.TypedLocalObjectReference `json:"resourcePolicy,omitempty"`
|
||||
|
||||
// SnapshotMoveData specifies whether snapshot data should be moved
|
||||
// +optional
|
||||
// +nullable
|
||||
SnapshotMoveData *bool `json:"snapshotMoveData,omitempty"`
|
||||
|
||||
// DataMover specifies the data mover to be used by the backup.
|
||||
// If DataMover is "" or "velero", the built-in data mover will be used.
|
||||
// +optional
|
||||
DataMover string `json:"datamover,omitempty"`
|
||||
}
|
||||
|
||||
// BackupHooks contains custom behaviors that should be executed at different phases of the backup.
|
||||
|
||||
@@ -19,6 +19,8 @@ package v1
|
||||
import (
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
)
|
||||
|
||||
// PodVolumeBackupSpec is the specification for a PodVolumeBackup.
|
||||
@@ -100,7 +102,7 @@ type PodVolumeBackupStatus struct {
|
||||
// number of backed up bytes. This can be used to display progress information
|
||||
// about the backup operation.
|
||||
// +optional
|
||||
Progress PodVolumeOperationProgress `json:"progress,omitempty"`
|
||||
Progress shared.DataMoveOperationProgress `json:"progress,omitempty"`
|
||||
}
|
||||
|
||||
// TODO(2.0) After converting all resources to use the runttime-controller client,
|
||||
|
||||
@@ -19,6 +19,8 @@ package v1
|
||||
import (
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
)
|
||||
|
||||
// PodVolumeRestoreSpec is the specification for a PodVolumeRestore.
|
||||
@@ -86,7 +88,7 @@ type PodVolumeRestoreStatus struct {
|
||||
// number of restored bytes. This can be used to display progress information
|
||||
// about the restore operation.
|
||||
// +optional
|
||||
Progress PodVolumeOperationProgress `json:"progress,omitempty"`
|
||||
Progress shared.DataMoveOperationProgress `json:"progress,omitempty"`
|
||||
}
|
||||
|
||||
// TODO(2.0) After converting all resources to use the runtime-controller client, the genclient and k8s:deepcopy markers will no longer be needed and should be removed.
|
||||
|
||||
@@ -376,6 +376,11 @@ func (in *BackupSpec) DeepCopyInto(out *BackupSpec) {
|
||||
*out = new(corev1.TypedLocalObjectReference)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.SnapshotMoveData != nil {
|
||||
in, out := &in.SnapshotMoveData, &out.SnapshotMoveData
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupSpec.
|
||||
@@ -977,21 +982,6 @@ func (in *PodVolumeBackupStatus) DeepCopy() *PodVolumeBackupStatus {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodVolumeOperationProgress) DeepCopyInto(out *PodVolumeOperationProgress) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeOperationProgress.
|
||||
func (in *PodVolumeOperationProgress) DeepCopy() *PodVolumeOperationProgress {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodVolumeOperationProgress)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodVolumeRestore) DeepCopyInto(out *PodVolumeRestore) {
|
||||
*out = *in
|
||||
|
||||
156
pkg/apis/velero/v2alpha1/data_download_types.go
Normal file
156
pkg/apis/velero/v2alpha1/data_download_types.go
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
)
|
||||
|
||||
// DataDownloadSpec is the specification for a DataDownload.
|
||||
type DataDownloadSpec struct {
|
||||
// TargetVolume is the information of the target PVC and PV.
|
||||
TargetVolume TargetVolumeSpec `json:"targetVolume"`
|
||||
|
||||
// BackupStorageLocation is the name of the backup storage location
|
||||
// where the backup repository is stored.
|
||||
BackupStorageLocation string `json:"backupStorageLocation"`
|
||||
|
||||
// DataMover specifies the data mover to be used by the backup.
|
||||
// If DataMover is "" or "velero", the built-in data mover will be used.
|
||||
// +optional
|
||||
DataMover string `json:"datamover,omitempty"`
|
||||
|
||||
// SnapshotID is the ID of the Velero backup snapshot to be restored from.
|
||||
SnapshotID string `json:"snapshotID"`
|
||||
|
||||
// SourceNamespace is the original namespace where the volume is backed up from.
|
||||
// It may be different from SourcePVC's namespace if namespace is remapped during restore.
|
||||
SourceNamespace string `json:"sourceNamespace"`
|
||||
|
||||
// DataMoverConfig is for data-mover-specific configuration fields.
|
||||
// +optional
|
||||
DataMoverConfig map[string]string `json:"dataMoverConfig,omitempty"`
|
||||
|
||||
// Cancel indicates request to cancel the ongoing DataDownload. It can be set
|
||||
// when the DataDownload is in InProgress phase
|
||||
Cancel bool `json:"cancel,omitempty"`
|
||||
|
||||
// OperationTimeout specifies the time used to wait internal operations,
|
||||
// before returning error as timeout.
|
||||
OperationTimeout metav1.Duration `json:"operationTimeout"`
|
||||
}
|
||||
|
||||
// TargetPVCSpec is the specification for a target PVC.
|
||||
type TargetVolumeSpec struct {
|
||||
// PVC is the name of the target PVC that is created by Velero restore
|
||||
PVC string `json:"pvc"`
|
||||
|
||||
// PV is the name of the target PV that is created by Velero restore
|
||||
PV string `json:"pv"`
|
||||
|
||||
// Namespace is the target namespace
|
||||
Namespace string `json:"namespace"`
|
||||
}
|
||||
|
||||
// DataDownloadPhase represents the lifecycle phase of a DataDownload.
|
||||
// +kubebuilder:validation:Enum=New;Accepted;Prepared;InProgress;Canceling;Canceled;Completed;Failed
|
||||
type DataDownloadPhase string
|
||||
|
||||
const (
|
||||
DataDownloadPhaseNew DataDownloadPhase = "New"
|
||||
DataDownloadPhaseAccepted DataDownloadPhase = "Accepted"
|
||||
DataDownloadPhasePrepared DataDownloadPhase = "Prepared"
|
||||
DataDownloadPhaseInProgress DataDownloadPhase = "InProgress"
|
||||
DataDownloadPhaseCanceling DataDownloadPhase = "Canceling"
|
||||
DataDownloadPhaseCanceled DataDownloadPhase = "Canceled"
|
||||
DataDownloadPhaseCompleted DataDownloadPhase = "Completed"
|
||||
DataDownloadPhaseFailed DataDownloadPhase = "Failed"
|
||||
)
|
||||
|
||||
// DataDownloadStatus is the current status of a DataDownload.
|
||||
type DataDownloadStatus struct {
|
||||
// Phase is the current state of the DataDownload.
|
||||
// +optional
|
||||
Phase DataDownloadPhase `json:"phase,omitempty"`
|
||||
|
||||
// Message is a message about the DataDownload's status.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// StartTimestamp records the time a restore was started.
|
||||
// The server's time is used for StartTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||
|
||||
// CompletionTimestamp records the time a restore was completed.
|
||||
// Completion time is recorded even on failed restores.
|
||||
// The server's time is used for CompletionTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
CompletionTimestamp *metav1.Time `json:"completionTimestamp,omitempty"`
|
||||
|
||||
// Progress holds the total number of bytes of the snapshot and the current
|
||||
// number of restored bytes. This can be used to display progress information
|
||||
// about the restore operation.
|
||||
// +optional
|
||||
Progress shared.DataMoveOperationProgress `json:"progress,omitempty"`
|
||||
}
|
||||
|
||||
// TODO(2.0) After converting all resources to use the runtime-controller client, the genclient and k8s:deepcopy markers will no longer be needed and should be removed.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:generate=true
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.phase",description="DataDownload status such as New/InProgress"
|
||||
// +kubebuilder:printcolumn:name="Started",type="date",JSONPath=".status.startTimestamp",description="Time duration since this DataDownload was started"
|
||||
// +kubebuilder:printcolumn:name="Bytes Done",type="integer",format="int64",JSONPath=".status.progress.bytesDone",description="Completed bytes"
|
||||
// +kubebuilder:printcolumn:name="Total Bytes",type="integer",format="int64",JSONPath=".status.progress.totalBytes",description="Total bytes"
|
||||
// +kubebuilder:printcolumn:name="Storage Location",type="string",JSONPath=".spec.backupStorageLocation",description="Name of the Backup Storage Location where the backup data is stored"
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since this DataDownload was created"
|
||||
|
||||
type DataDownload struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +optional
|
||||
Spec DataDownloadSpec `json:"spec,omitempty"`
|
||||
|
||||
// +optional
|
||||
Status DataDownloadStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:generate=true
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=datadownloads,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=datadownloads/status,verbs=get;update;patch
|
||||
|
||||
// DataDownloadList is a list of DataDownloads.
|
||||
type DataDownloadList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []DataDownload `json:"items"`
|
||||
}
|
||||
209
pkg/apis/velero/v2alpha1/data_upload_types.go
Normal file
209
pkg/apis/velero/v2alpha1/data_upload_types.go
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
)
|
||||
|
||||
// DataUploadSpec is the specification for a DataUpload.
|
||||
type DataUploadSpec struct {
|
||||
// SnapshotType is the type of the snapshot to be backed up.
|
||||
SnapshotType SnapshotType `json:"snapshotType"`
|
||||
|
||||
// If SnapshotType is CSI, CSISnapshot provides the information of the CSI snapshot.
|
||||
// +optional
|
||||
// +nullable
|
||||
CSISnapshot *CSISnapshotSpec `json:"csiSnapshot"`
|
||||
|
||||
// SourcePVC is the name of the PVC which the snapshot is taken for.
|
||||
SourcePVC string `json:"sourcePVC"`
|
||||
|
||||
// DataMover specifies the data mover to be used by the backup.
|
||||
// If DataMover is "" or "velero", the built-in data mover will be used.
|
||||
// +optional
|
||||
DataMover string `json:"datamover,omitempty"`
|
||||
|
||||
// BackupStorageLocation is the name of the backup storage location
|
||||
// where the backup repository is stored.
|
||||
BackupStorageLocation string `json:"backupStorageLocation"`
|
||||
|
||||
// SourceNamespace is the original namespace where the volume is backed up from.
|
||||
// It is the same namespace for SourcePVC and CSI namespaced objects.
|
||||
SourceNamespace string `json:"sourceNamespace"`
|
||||
|
||||
// DataMoverConfig is for data-mover-specific configuration fields.
|
||||
// +optional
|
||||
// +nullable
|
||||
DataMoverConfig *map[string]string `json:"dataMoverConfig,omitempty"`
|
||||
|
||||
// Cancel indicates request to cancel the ongoing DataUpload. It can be set
|
||||
// when the DataUpload is in InProgress phase
|
||||
Cancel bool `json:"cancel,omitempty"`
|
||||
|
||||
// OperationTimeout specifies the time used to wait internal operations,
|
||||
// before returning error as timeout.
|
||||
OperationTimeout metav1.Duration `json:"operationTimeout"`
|
||||
}
|
||||
|
||||
type SnapshotType string
|
||||
|
||||
const (
|
||||
SnapshotTypeCSI SnapshotType = "CSI"
|
||||
)
|
||||
|
||||
// CSISnapshotSpec is the specification for a CSI snapshot.
|
||||
type CSISnapshotSpec struct {
|
||||
// VolumeSnapshot is the name of the volume snapshot to be backed up
|
||||
VolumeSnapshot string `json:"volumeSnapshot"`
|
||||
|
||||
// StorageClass is the name of the storage class of the PVC that the volume snapshot is created from
|
||||
StorageClass string `json:"storageClass"`
|
||||
|
||||
// StorageClass is the name of the snapshot class that the volume snapshot is created with
|
||||
// +optional
|
||||
SnapshotClass string `json:"snapshotClass"`
|
||||
}
|
||||
|
||||
// DataUploadPhase represents the lifecycle phase of a DataUpload.
|
||||
// +kubebuilder:validation:Enum=New;Accepted;Prepared;InProgress;Canceling;Canceled;Completed;Failed
|
||||
type DataUploadPhase string
|
||||
|
||||
const (
|
||||
DataUploadPhaseNew DataUploadPhase = "New"
|
||||
DataUploadPhaseAccepted DataUploadPhase = "Accepted"
|
||||
DataUploadPhasePrepared DataUploadPhase = "Prepared"
|
||||
DataUploadPhaseInProgress DataUploadPhase = "InProgress"
|
||||
DataUploadPhaseCanceling DataUploadPhase = "Canceling"
|
||||
DataUploadPhaseCanceled DataUploadPhase = "Canceled"
|
||||
DataUploadPhaseCompleted DataUploadPhase = "Completed"
|
||||
DataUploadPhaseFailed DataUploadPhase = "Failed"
|
||||
)
|
||||
|
||||
// DataUploadStatus is the current status of a DataUpload.
|
||||
type DataUploadStatus struct {
|
||||
// Phase is the current state of the DataUpload.
|
||||
// +optional
|
||||
Phase DataUploadPhase `json:"phase,omitempty"`
|
||||
|
||||
// Path is the full path of the snapshot volume being backed up.
|
||||
// +optional
|
||||
Path string `json:"path,omitempty"`
|
||||
|
||||
// SnapshotID is the identifier for the snapshot in the backup repository.
|
||||
// +optional
|
||||
SnapshotID string `json:"snapshotID,omitempty"`
|
||||
|
||||
// DataMoverResult stores data-mover-specific information as a result of the DataUpload.
|
||||
// +optional
|
||||
// +nullable
|
||||
DataMoverResult *map[string]string `json:"dataMoverResult,omitempty"`
|
||||
|
||||
// Message is a message about the DataUpload's status.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// StartTimestamp records the time a backup was started.
|
||||
// Separate from CreationTimestamp, since that value changes
|
||||
// on restores.
|
||||
// The server's time is used for StartTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||
|
||||
// CompletionTimestamp records the time a backup was completed.
|
||||
// Completion time is recorded even on failed backups.
|
||||
// Completion time is recorded before uploading the backup object.
|
||||
// The server's time is used for CompletionTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
CompletionTimestamp *metav1.Time `json:"completionTimestamp,omitempty"`
|
||||
|
||||
// Progress holds the total number of bytes of the volume and the current
|
||||
// number of backed up bytes. This can be used to display progress information
|
||||
// about the backup operation.
|
||||
// +optional
|
||||
Progress shared.DataMoveOperationProgress `json:"progress,omitempty"`
|
||||
}
|
||||
|
||||
// TODO(2.0) After converting all resources to use the runttime-controller client,
|
||||
// the genclient and k8s:deepcopy markers will no longer be needed and should be removed.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:object:generate=true
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.phase",description="DataUpload status such as New/InProgress"
|
||||
// +kubebuilder:printcolumn:name="Started",type="date",JSONPath=".status.startTimestamp",description="Time duration since this DataUpload was started"
|
||||
// +kubebuilder:printcolumn:name="Bytes Done",type="integer",format="int64",JSONPath=".status.progress.bytesDone",description="Completed bytes"
|
||||
// +kubebuilder:printcolumn:name="Total Bytes",type="integer",format="int64",JSONPath=".status.progress.totalBytes",description="Total bytes"
|
||||
// +kubebuilder:printcolumn:name="Storage Location",type="string",JSONPath=".spec.backupStorageLocation",description="Name of the Backup Storage Location where this backup should be stored"
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since this DataUpload was created"
|
||||
|
||||
type DataUpload struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +optional
|
||||
Spec DataUploadSpec `json:"spec,omitempty"`
|
||||
|
||||
// +optional
|
||||
Status DataUploadStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// TODO(2.0) After converting all resources to use the runtime-controller client,
|
||||
// the k8s:deepcopy marker will no longer be needed and should be removed.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=datauploads,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=datauploads/status,verbs=get;update;patch
|
||||
|
||||
// DataUploadList is a list of DataUploads.
|
||||
type DataUploadList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []DataUpload `json:"items"`
|
||||
}
|
||||
|
||||
// DataUploadResult represents the SnasphotBackup result to be used by DataDownload.
|
||||
type DataUploadResult struct {
|
||||
// BackupStorageLocation is the name of the backup storage location
|
||||
// where the backup repository is stored.
|
||||
BackupStorageLocation string `json:"backupStorageLocation"`
|
||||
|
||||
// DataMover specifies the data mover used by the DataUpload
|
||||
// +optional
|
||||
DataMover string `json:"datamover,omitempty"`
|
||||
|
||||
// SnapshotID is the identifier for the snapshot in the backup repository.
|
||||
SnapshotID string `json:"snapshotID,omitempty"`
|
||||
|
||||
// SourceNamespace is the original namespace where the volume is backed up from.
|
||||
SourceNamespace string `json:"sourceNamespace"`
|
||||
|
||||
// DataMoverResult stores data-mover-specific information as a result of the DataUpload.
|
||||
// +optional
|
||||
// +nullable
|
||||
DataMoverResult *map[string]string `json:"dataMoverResult,omitempty"`
|
||||
}
|
||||
21
pkg/apis/velero/v2alpha1/doc.go
Normal file
21
pkg/apis/velero/v2alpha1/doc.go
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// Package v2alpha1 is the v2alpha1 version of the API.
|
||||
// +groupName=velero.io
|
||||
package v2alpha1
|
||||
36
pkg/apis/velero/v2alpha1/groupversion_info.go
Normal file
36
pkg/apis/velero/v2alpha1/groupversion_info.go
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package v2alpha1 contains API Schema definitions for the velero v2alpha1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=velero.io
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: "velero.io", Version: "v2alpha1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
60
pkg/apis/velero/v2alpha1/register.go
Normal file
60
pkg/apis/velero/v2alpha1/register.go
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// Resource gets a Velero GroupResource for a specified resource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
type typeInfo struct {
|
||||
PluralName string
|
||||
ItemType runtime.Object
|
||||
ItemListType runtime.Object
|
||||
}
|
||||
|
||||
func newTypeInfo(pluralName string, itemType, itemListType runtime.Object) typeInfo {
|
||||
return typeInfo{
|
||||
PluralName: pluralName,
|
||||
ItemType: itemType,
|
||||
ItemListType: itemListType,
|
||||
}
|
||||
}
|
||||
|
||||
// CustomResources returns a map of all custom resources within the Velero
|
||||
// API group, keyed on Kind.
|
||||
func CustomResources() map[string]typeInfo {
|
||||
return map[string]typeInfo{
|
||||
"DataUpload": newTypeInfo("datauploads", &DataUpload{}, &DataUploadList{}),
|
||||
"DataDownload": newTypeInfo("datadownloads", &DataDownload{}, &DataDownloadList{}),
|
||||
}
|
||||
}
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
for _, typeInfo := range CustomResources() {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion, typeInfo.ItemType, typeInfo.ItemListType)
|
||||
}
|
||||
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
299
pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go
Normal file
299
pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go
Normal file
@@ -0,0 +1,299 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CSISnapshotSpec) DeepCopyInto(out *CSISnapshotSpec) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSISnapshotSpec.
|
||||
func (in *CSISnapshotSpec) DeepCopy() *CSISnapshotSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CSISnapshotSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DataDownload) DeepCopyInto(out *DataDownload) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataDownload.
|
||||
func (in *DataDownload) DeepCopy() *DataDownload {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DataDownload)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DataDownload) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DataDownloadList) DeepCopyInto(out *DataDownloadList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]DataDownload, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataDownloadList.
|
||||
func (in *DataDownloadList) DeepCopy() *DataDownloadList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DataDownloadList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DataDownloadList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DataDownloadSpec) DeepCopyInto(out *DataDownloadSpec) {
|
||||
*out = *in
|
||||
out.TargetVolume = in.TargetVolume
|
||||
if in.DataMoverConfig != nil {
|
||||
in, out := &in.DataMoverConfig, &out.DataMoverConfig
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
out.OperationTimeout = in.OperationTimeout
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataDownloadSpec.
|
||||
func (in *DataDownloadSpec) DeepCopy() *DataDownloadSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DataDownloadSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DataDownloadStatus) DeepCopyInto(out *DataDownloadStatus) {
|
||||
*out = *in
|
||||
if in.StartTimestamp != nil {
|
||||
in, out := &in.StartTimestamp, &out.StartTimestamp
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.CompletionTimestamp != nil {
|
||||
in, out := &in.CompletionTimestamp, &out.CompletionTimestamp
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
out.Progress = in.Progress
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataDownloadStatus.
|
||||
func (in *DataDownloadStatus) DeepCopy() *DataDownloadStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DataDownloadStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DataUpload) DeepCopyInto(out *DataUpload) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataUpload.
|
||||
func (in *DataUpload) DeepCopy() *DataUpload {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DataUpload)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DataUpload) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DataUploadList) DeepCopyInto(out *DataUploadList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]DataUpload, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataUploadList.
|
||||
func (in *DataUploadList) DeepCopy() *DataUploadList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DataUploadList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DataUploadList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DataUploadResult) DeepCopyInto(out *DataUploadResult) {
|
||||
*out = *in
|
||||
if in.DataMoverResult != nil {
|
||||
in, out := &in.DataMoverResult, &out.DataMoverResult
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataUploadResult.
|
||||
func (in *DataUploadResult) DeepCopy() *DataUploadResult {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DataUploadResult)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DataUploadSpec) DeepCopyInto(out *DataUploadSpec) {
|
||||
*out = *in
|
||||
if in.CSISnapshot != nil {
|
||||
in, out := &in.CSISnapshot, &out.CSISnapshot
|
||||
*out = new(CSISnapshotSpec)
|
||||
**out = **in
|
||||
}
|
||||
if in.DataMoverConfig != nil {
|
||||
in, out := &in.DataMoverConfig, &out.DataMoverConfig
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
out.OperationTimeout = in.OperationTimeout
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataUploadSpec.
|
||||
func (in *DataUploadSpec) DeepCopy() *DataUploadSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DataUploadSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DataUploadStatus) DeepCopyInto(out *DataUploadStatus) {
|
||||
*out = *in
|
||||
if in.DataMoverResult != nil {
|
||||
in, out := &in.DataMoverResult, &out.DataMoverResult
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.StartTimestamp != nil {
|
||||
in, out := &in.StartTimestamp, &out.StartTimestamp
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.CompletionTimestamp != nil {
|
||||
in, out := &in.CompletionTimestamp, &out.CompletionTimestamp
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
out.Progress = in.Progress
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataUploadStatus.
|
||||
func (in *DataUploadStatus) DeepCopy() *DataUploadStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DataUploadStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TargetVolumeSpec) DeepCopyInto(out *TargetVolumeSpec) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetVolumeSpec.
|
||||
func (in *TargetVolumeSpec) DeepCopy() *TargetVolumeSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TargetVolumeSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
@@ -61,5 +62,18 @@ func (a *PVCAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runti
|
||||
GroupResource: kuberesource.PersistentVolumes,
|
||||
Name: pvc.Spec.VolumeName,
|
||||
}
|
||||
return item, []velero.ResourceIdentifier{pv}, nil
|
||||
// remove dataSource if exists from prior restored CSI volumes
|
||||
if pvc.Spec.DataSource != nil {
|
||||
pvc.Spec.DataSource = nil
|
||||
}
|
||||
if pvc.Spec.DataSourceRef != nil {
|
||||
pvc.Spec.DataSourceRef = nil
|
||||
}
|
||||
|
||||
pvcMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&pvc)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "unable to convert pvc to unstructured item")
|
||||
}
|
||||
|
||||
return &unstructured.Unstructured{Object: pvcMap}, []velero.ResourceIdentifier{pv}, nil
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
clientset "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
|
||||
)
|
||||
|
||||
@@ -156,6 +157,9 @@ func (f *factory) KubebuilderClient() (kbclient.Client, error) {
|
||||
if err := velerov1api.AddToScheme(scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := velerov2alpha1api.AddToScheme(scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := k8scheme.AddToScheme(scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import (
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/credentials"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
"github.com/vmware-tanzu/velero/pkg/buildinfo"
|
||||
"github.com/vmware-tanzu/velero/pkg/client"
|
||||
"github.com/vmware-tanzu/velero/pkg/cmd"
|
||||
@@ -125,6 +126,10 @@ func newNodeAgentServer(logger logrus.FieldLogger, factory client.Factory, metri
|
||||
cancelFunc()
|
||||
return nil, err
|
||||
}
|
||||
if err := velerov2alpha1api.AddToScheme(scheme); err != nil {
|
||||
cancelFunc()
|
||||
return nil, err
|
||||
}
|
||||
if err := v1.AddToScheme(scheme); err != nil {
|
||||
cancelFunc()
|
||||
return nil, err
|
||||
|
||||
@@ -55,6 +55,7 @@ import (
|
||||
"github.com/vmware-tanzu/velero/internal/credentials"
|
||||
"github.com/vmware-tanzu/velero/internal/storage"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
"github.com/vmware-tanzu/velero/pkg/backup"
|
||||
"github.com/vmware-tanzu/velero/pkg/buildinfo"
|
||||
"github.com/vmware-tanzu/velero/pkg/client"
|
||||
@@ -317,6 +318,10 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s
|
||||
cancelFunc()
|
||||
return nil, err
|
||||
}
|
||||
if err := velerov2alpha1api.AddToScheme(scheme); err != nil {
|
||||
cancelFunc()
|
||||
return nil, err
|
||||
}
|
||||
if err := corev1api.AddToScheme(scheme); err != nil {
|
||||
cancelFunc()
|
||||
return nil, err
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"github.com/fatih/color"
|
||||
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
veleroapishared "github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/cmd/util/downloadrequest"
|
||||
"github.com/vmware-tanzu/velero/pkg/features"
|
||||
@@ -597,7 +598,7 @@ type volumesByPod struct {
|
||||
|
||||
// Add adds a pod volume with the specified pod namespace, name
|
||||
// and volume to the appropriate group.
|
||||
func (v *volumesByPod) Add(namespace, name, volume, phase string, progress velerov1api.PodVolumeOperationProgress) {
|
||||
func (v *volumesByPod) Add(namespace, name, volume, phase string, progress veleroapishared.DataMoveOperationProgress) {
|
||||
if v.volumesByPodMap == nil {
|
||||
v.volumesByPodMap = make(map[string]*podVolumeGroup)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/credentials"
|
||||
veleroapishared "github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/metrics"
|
||||
"github.com/vmware-tanzu/velero/pkg/podvolume"
|
||||
@@ -303,7 +304,7 @@ func (r *PodVolumeBackupReconciler) NewBackupProgressUpdater(ctx context.Context
|
||||
// UpdateProgress which implement ProgressUpdater interface to update pvb progress status
|
||||
func (b *BackupProgressUpdater) UpdateProgress(p *uploader.Progress) {
|
||||
original := b.PodVolumeBackup.DeepCopy()
|
||||
b.PodVolumeBackup.Status.Progress = velerov1api.PodVolumeOperationProgress{TotalBytes: p.TotalBytes, BytesDone: p.BytesDone}
|
||||
b.PodVolumeBackup.Status.Progress = veleroapishared.DataMoveOperationProgress{TotalBytes: p.TotalBytes, BytesDone: p.BytesDone}
|
||||
if b.Cli == nil {
|
||||
b.Log.Errorf("failed to update backup pod %s volume %s progress with uninitailize client", b.PodVolumeBackup.Spec.Pod.Name, b.PodVolumeBackup.Spec.Volume)
|
||||
return
|
||||
|
||||
@@ -38,6 +38,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/source"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/credentials"
|
||||
veleroapishared "github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/podvolume"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
@@ -321,7 +322,7 @@ func (c *PodVolumeRestoreReconciler) NewRestoreProgressUpdater(ctx context.Conte
|
||||
// UpdateProgress which implement ProgressUpdater interface to update pvr progress status
|
||||
func (c *RestoreProgressUpdater) UpdateProgress(p *uploader.Progress) {
|
||||
original := c.PodVolumeRestore.DeepCopy()
|
||||
c.PodVolumeRestore.Status.Progress = velerov1api.PodVolumeOperationProgress{TotalBytes: p.TotalBytes, BytesDone: p.BytesDone}
|
||||
c.PodVolumeRestore.Status.Progress = veleroapishared.DataMoveOperationProgress{TotalBytes: p.TotalBytes, BytesDone: p.BytesDone}
|
||||
if c.Cli == nil {
|
||||
c.Log.Errorf("failed to update restore pod %s volume %s progress with uninitailize client", c.PodVolumeRestore.Spec.Pod.Name, c.PodVolumeRestore.Spec.Volume)
|
||||
return
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
@@ -98,6 +99,9 @@ func newTestEnvironment() *testEnvironment {
|
||||
err := velerov1api.AddToScheme(scheme.Scheme)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = velerov2alpha1api.AddToScheme(scheme.Scheme)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
env = &envtest.Environment{
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
velerov1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1"
|
||||
velerov2alpha1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v2alpha1"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
rest "k8s.io/client-go/rest"
|
||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
||||
@@ -30,13 +31,15 @@ import (
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
VeleroV1() velerov1.VeleroV1Interface
|
||||
VeleroV2alpha1() velerov2alpha1.VeleroV2alpha1Interface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
veleroV1 *velerov1.VeleroV1Client
|
||||
veleroV1 *velerov1.VeleroV1Client
|
||||
veleroV2alpha1 *velerov2alpha1.VeleroV2alpha1Client
|
||||
}
|
||||
|
||||
// VeleroV1 retrieves the VeleroV1Client
|
||||
@@ -44,6 +47,11 @@ func (c *Clientset) VeleroV1() velerov1.VeleroV1Interface {
|
||||
return c.veleroV1
|
||||
}
|
||||
|
||||
// VeleroV2alpha1 retrieves the VeleroV2alpha1Client
|
||||
func (c *Clientset) VeleroV2alpha1() velerov2alpha1.VeleroV2alpha1Interface {
|
||||
return c.veleroV2alpha1
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
if c == nil {
|
||||
@@ -69,6 +77,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.veleroV2alpha1, err = velerov2alpha1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
@@ -82,6 +94,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
var cs Clientset
|
||||
cs.veleroV1 = velerov1.NewForConfigOrDie(c)
|
||||
cs.veleroV2alpha1 = velerov2alpha1.NewForConfigOrDie(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &cs
|
||||
@@ -91,6 +104,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.veleroV1 = velerov1.New(c)
|
||||
cs.veleroV2alpha1 = velerov2alpha1.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &cs
|
||||
|
||||
@@ -22,6 +22,8 @@ import (
|
||||
clientset "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
|
||||
velerov1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1"
|
||||
fakevelerov1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1/fake"
|
||||
velerov2alpha1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v2alpha1"
|
||||
fakevelerov2alpha1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v2alpha1/fake"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
||||
@@ -83,3 +85,8 @@ var (
|
||||
func (c *Clientset) VeleroV1() velerov1.VeleroV1Interface {
|
||||
return &fakevelerov1.FakeVeleroV1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// VeleroV2alpha1 retrieves the VeleroV2alpha1Client
|
||||
func (c *Clientset) VeleroV2alpha1() velerov2alpha1.VeleroV2alpha1Interface {
|
||||
return &fakevelerov2alpha1.FakeVeleroV2alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ package fake
|
||||
|
||||
import (
|
||||
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -32,6 +33,7 @@ var codecs = serializer.NewCodecFactory(scheme)
|
||||
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
velerov1.AddToScheme,
|
||||
velerov2alpha1.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
|
||||
@@ -20,6 +20,7 @@ package scheme
|
||||
|
||||
import (
|
||||
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -32,6 +33,7 @@ var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
velerov1.AddToScheme,
|
||||
velerov2alpha1.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
scheme "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// DataDownloadsGetter has a method to return a DataDownloadInterface.
|
||||
// A group's client should implement this interface.
|
||||
type DataDownloadsGetter interface {
|
||||
DataDownloads(namespace string) DataDownloadInterface
|
||||
}
|
||||
|
||||
// DataDownloadInterface has methods to work with DataDownload resources.
|
||||
type DataDownloadInterface interface {
|
||||
Create(ctx context.Context, dataDownload *v2alpha1.DataDownload, opts v1.CreateOptions) (*v2alpha1.DataDownload, error)
|
||||
Update(ctx context.Context, dataDownload *v2alpha1.DataDownload, opts v1.UpdateOptions) (*v2alpha1.DataDownload, error)
|
||||
UpdateStatus(ctx context.Context, dataDownload *v2alpha1.DataDownload, opts v1.UpdateOptions) (*v2alpha1.DataDownload, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v2alpha1.DataDownload, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v2alpha1.DataDownloadList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2alpha1.DataDownload, err error)
|
||||
DataDownloadExpansion
|
||||
}
|
||||
|
||||
// dataDownloads implements DataDownloadInterface
|
||||
type dataDownloads struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newDataDownloads returns a DataDownloads
|
||||
func newDataDownloads(c *VeleroV2alpha1Client, namespace string) *dataDownloads {
|
||||
return &dataDownloads{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the dataDownload, and returns the corresponding dataDownload object, and an error if there is any.
|
||||
func (c *dataDownloads) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2alpha1.DataDownload, err error) {
|
||||
result = &v2alpha1.DataDownload{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("datadownloads").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of DataDownloads that match those selectors.
|
||||
func (c *dataDownloads) List(ctx context.Context, opts v1.ListOptions) (result *v2alpha1.DataDownloadList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v2alpha1.DataDownloadList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("datadownloads").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested dataDownloads.
|
||||
func (c *dataDownloads) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("datadownloads").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a dataDownload and creates it. Returns the server's representation of the dataDownload, and an error, if there is any.
|
||||
func (c *dataDownloads) Create(ctx context.Context, dataDownload *v2alpha1.DataDownload, opts v1.CreateOptions) (result *v2alpha1.DataDownload, err error) {
|
||||
result = &v2alpha1.DataDownload{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("datadownloads").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(dataDownload).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a dataDownload and updates it. Returns the server's representation of the dataDownload, and an error, if there is any.
|
||||
func (c *dataDownloads) Update(ctx context.Context, dataDownload *v2alpha1.DataDownload, opts v1.UpdateOptions) (result *v2alpha1.DataDownload, err error) {
|
||||
result = &v2alpha1.DataDownload{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("datadownloads").
|
||||
Name(dataDownload.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(dataDownload).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *dataDownloads) UpdateStatus(ctx context.Context, dataDownload *v2alpha1.DataDownload, opts v1.UpdateOptions) (result *v2alpha1.DataDownload, err error) {
|
||||
result = &v2alpha1.DataDownload{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("datadownloads").
|
||||
Name(dataDownload.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(dataDownload).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the dataDownload and deletes it. Returns an error if one occurs.
|
||||
func (c *dataDownloads) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("datadownloads").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *dataDownloads) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("datadownloads").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched dataDownload.
|
||||
func (c *dataDownloads) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2alpha1.DataDownload, err error) {
|
||||
result = &v2alpha1.DataDownload{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("datadownloads").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
scheme "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// DataUploadsGetter has a method to return a DataUploadInterface.
|
||||
// A group's client should implement this interface.
|
||||
type DataUploadsGetter interface {
|
||||
DataUploads(namespace string) DataUploadInterface
|
||||
}
|
||||
|
||||
// DataUploadInterface has methods to work with DataUpload resources.
|
||||
type DataUploadInterface interface {
|
||||
Create(ctx context.Context, dataUpload *v2alpha1.DataUpload, opts v1.CreateOptions) (*v2alpha1.DataUpload, error)
|
||||
Update(ctx context.Context, dataUpload *v2alpha1.DataUpload, opts v1.UpdateOptions) (*v2alpha1.DataUpload, error)
|
||||
UpdateStatus(ctx context.Context, dataUpload *v2alpha1.DataUpload, opts v1.UpdateOptions) (*v2alpha1.DataUpload, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v2alpha1.DataUpload, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v2alpha1.DataUploadList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2alpha1.DataUpload, err error)
|
||||
DataUploadExpansion
|
||||
}
|
||||
|
||||
// dataUploads implements DataUploadInterface
|
||||
type dataUploads struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newDataUploads returns a DataUploads
|
||||
func newDataUploads(c *VeleroV2alpha1Client, namespace string) *dataUploads {
|
||||
return &dataUploads{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the dataUpload, and returns the corresponding dataUpload object, and an error if there is any.
|
||||
func (c *dataUploads) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2alpha1.DataUpload, err error) {
|
||||
result = &v2alpha1.DataUpload{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("datauploads").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of DataUploads that match those selectors.
|
||||
func (c *dataUploads) List(ctx context.Context, opts v1.ListOptions) (result *v2alpha1.DataUploadList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v2alpha1.DataUploadList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("datauploads").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested dataUploads.
|
||||
func (c *dataUploads) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("datauploads").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a dataUpload and creates it. Returns the server's representation of the dataUpload, and an error, if there is any.
|
||||
func (c *dataUploads) Create(ctx context.Context, dataUpload *v2alpha1.DataUpload, opts v1.CreateOptions) (result *v2alpha1.DataUpload, err error) {
|
||||
result = &v2alpha1.DataUpload{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("datauploads").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(dataUpload).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a dataUpload and updates it. Returns the server's representation of the dataUpload, and an error, if there is any.
|
||||
func (c *dataUploads) Update(ctx context.Context, dataUpload *v2alpha1.DataUpload, opts v1.UpdateOptions) (result *v2alpha1.DataUpload, err error) {
|
||||
result = &v2alpha1.DataUpload{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("datauploads").
|
||||
Name(dataUpload.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(dataUpload).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *dataUploads) UpdateStatus(ctx context.Context, dataUpload *v2alpha1.DataUpload, opts v1.UpdateOptions) (result *v2alpha1.DataUpload, err error) {
|
||||
result = &v2alpha1.DataUpload{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("datauploads").
|
||||
Name(dataUpload.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(dataUpload).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the dataUpload and deletes it. Returns an error if one occurs.
|
||||
func (c *dataUploads) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("datauploads").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *dataUploads) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("datauploads").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched dataUpload.
|
||||
func (c *dataUploads) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2alpha1.DataUpload, err error) {
|
||||
result = &v2alpha1.DataUpload{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("datauploads").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v2alpha1
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeDataDownloads implements DataDownloadInterface
|
||||
type FakeDataDownloads struct {
|
||||
Fake *FakeVeleroV2alpha1
|
||||
ns string
|
||||
}
|
||||
|
||||
var datadownloadsResource = schema.GroupVersionResource{Group: "velero.io", Version: "v2alpha1", Resource: "datadownloads"}
|
||||
|
||||
var datadownloadsKind = schema.GroupVersionKind{Group: "velero.io", Version: "v2alpha1", Kind: "DataDownload"}
|
||||
|
||||
// Get takes name of the dataDownload, and returns the corresponding dataDownload object, and an error if there is any.
|
||||
func (c *FakeDataDownloads) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2alpha1.DataDownload, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(datadownloadsResource, c.ns, name), &v2alpha1.DataDownload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataDownload), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of DataDownloads that match those selectors.
|
||||
func (c *FakeDataDownloads) List(ctx context.Context, opts v1.ListOptions) (result *v2alpha1.DataDownloadList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(datadownloadsResource, datadownloadsKind, c.ns, opts), &v2alpha1.DataDownloadList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v2alpha1.DataDownloadList{ListMeta: obj.(*v2alpha1.DataDownloadList).ListMeta}
|
||||
for _, item := range obj.(*v2alpha1.DataDownloadList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested dataDownloads.
|
||||
func (c *FakeDataDownloads) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(datadownloadsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a dataDownload and creates it. Returns the server's representation of the dataDownload, and an error, if there is any.
|
||||
func (c *FakeDataDownloads) Create(ctx context.Context, dataDownload *v2alpha1.DataDownload, opts v1.CreateOptions) (result *v2alpha1.DataDownload, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(datadownloadsResource, c.ns, dataDownload), &v2alpha1.DataDownload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataDownload), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a dataDownload and updates it. Returns the server's representation of the dataDownload, and an error, if there is any.
|
||||
func (c *FakeDataDownloads) Update(ctx context.Context, dataDownload *v2alpha1.DataDownload, opts v1.UpdateOptions) (result *v2alpha1.DataDownload, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(datadownloadsResource, c.ns, dataDownload), &v2alpha1.DataDownload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataDownload), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeDataDownloads) UpdateStatus(ctx context.Context, dataDownload *v2alpha1.DataDownload, opts v1.UpdateOptions) (*v2alpha1.DataDownload, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(datadownloadsResource, "status", c.ns, dataDownload), &v2alpha1.DataDownload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataDownload), err
|
||||
}
|
||||
|
||||
// Delete takes name of the dataDownload and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeDataDownloads) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(datadownloadsResource, c.ns, name), &v2alpha1.DataDownload{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeDataDownloads) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(datadownloadsResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v2alpha1.DataDownloadList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched dataDownload.
|
||||
func (c *FakeDataDownloads) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2alpha1.DataDownload, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(datadownloadsResource, c.ns, name, pt, data, subresources...), &v2alpha1.DataDownload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataDownload), err
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeDataUploads implements DataUploadInterface
|
||||
type FakeDataUploads struct {
|
||||
Fake *FakeVeleroV2alpha1
|
||||
ns string
|
||||
}
|
||||
|
||||
var datauploadsResource = schema.GroupVersionResource{Group: "velero.io", Version: "v2alpha1", Resource: "datauploads"}
|
||||
|
||||
var datauploadsKind = schema.GroupVersionKind{Group: "velero.io", Version: "v2alpha1", Kind: "DataUpload"}
|
||||
|
||||
// Get takes name of the dataUpload, and returns the corresponding dataUpload object, and an error if there is any.
|
||||
func (c *FakeDataUploads) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2alpha1.DataUpload, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(datauploadsResource, c.ns, name), &v2alpha1.DataUpload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataUpload), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of DataUploads that match those selectors.
|
||||
func (c *FakeDataUploads) List(ctx context.Context, opts v1.ListOptions) (result *v2alpha1.DataUploadList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(datauploadsResource, datauploadsKind, c.ns, opts), &v2alpha1.DataUploadList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v2alpha1.DataUploadList{ListMeta: obj.(*v2alpha1.DataUploadList).ListMeta}
|
||||
for _, item := range obj.(*v2alpha1.DataUploadList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested dataUploads.
|
||||
func (c *FakeDataUploads) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(datauploadsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a dataUpload and creates it. Returns the server's representation of the dataUpload, and an error, if there is any.
|
||||
func (c *FakeDataUploads) Create(ctx context.Context, dataUpload *v2alpha1.DataUpload, opts v1.CreateOptions) (result *v2alpha1.DataUpload, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(datauploadsResource, c.ns, dataUpload), &v2alpha1.DataUpload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataUpload), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a dataUpload and updates it. Returns the server's representation of the dataUpload, and an error, if there is any.
|
||||
func (c *FakeDataUploads) Update(ctx context.Context, dataUpload *v2alpha1.DataUpload, opts v1.UpdateOptions) (result *v2alpha1.DataUpload, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(datauploadsResource, c.ns, dataUpload), &v2alpha1.DataUpload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataUpload), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeDataUploads) UpdateStatus(ctx context.Context, dataUpload *v2alpha1.DataUpload, opts v1.UpdateOptions) (*v2alpha1.DataUpload, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(datauploadsResource, "status", c.ns, dataUpload), &v2alpha1.DataUpload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataUpload), err
|
||||
}
|
||||
|
||||
// Delete takes name of the dataUpload and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeDataUploads) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(datauploadsResource, c.ns, name), &v2alpha1.DataUpload{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeDataUploads) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(datauploadsResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v2alpha1.DataUploadList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched dataUpload.
|
||||
func (c *FakeDataUploads) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2alpha1.DataUpload, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(datauploadsResource, c.ns, name, pt, data, subresources...), &v2alpha1.DataUpload{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2alpha1.DataUpload), err
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v2alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeVeleroV2alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeVeleroV2alpha1) DataDownloads(namespace string) v2alpha1.DataDownloadInterface {
|
||||
return &FakeDataDownloads{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeVeleroV2alpha1) DataUploads(namespace string) v2alpha1.DataUploadInterface {
|
||||
return &FakeDataUploads{c, namespace}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeVeleroV2alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
type DataDownloadExpansion interface{}
|
||||
|
||||
type DataUploadExpansion interface{}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type VeleroV2alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
DataDownloadsGetter
|
||||
DataUploadsGetter
|
||||
}
|
||||
|
||||
// VeleroV2alpha1Client is used to interact with features provided by the velero.io group.
|
||||
type VeleroV2alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *VeleroV2alpha1Client) DataDownloads(namespace string) DataDownloadInterface {
|
||||
return newDataDownloads(c, namespace)
|
||||
}
|
||||
|
||||
func (c *VeleroV2alpha1Client) DataUploads(namespace string) DataUploadInterface {
|
||||
return newDataUploads(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new VeleroV2alpha1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*VeleroV2alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &VeleroV2alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new VeleroV2alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *VeleroV2alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new VeleroV2alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *VeleroV2alpha1Client {
|
||||
return &VeleroV2alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v2alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *VeleroV2alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
@@ -76,6 +77,12 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
case v1.SchemeGroupVersion.WithResource("volumesnapshotlocations"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Velero().V1().VolumeSnapshotLocations().Informer()}, nil
|
||||
|
||||
// Group=velero.io, Version=v2alpha1
|
||||
case v2alpha1.SchemeGroupVersion.WithResource("datadownloads"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Velero().V2alpha1().DataDownloads().Informer()}, nil
|
||||
case v2alpha1.SchemeGroupVersion.WithResource("datauploads"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Velero().V2alpha1().DataUploads().Informer()}, nil
|
||||
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no informer found for %v", resource)
|
||||
|
||||
@@ -21,12 +21,15 @@ package velero
|
||||
import (
|
||||
internalinterfaces "github.com/vmware-tanzu/velero/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
v1 "github.com/vmware-tanzu/velero/pkg/generated/informers/externalversions/velero/v1"
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/generated/informers/externalversions/velero/v2alpha1"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1 provides access to shared informers for resources in V1.
|
||||
V1() v1.Interface
|
||||
// V2alpha1 provides access to shared informers for resources in V2alpha1.
|
||||
V2alpha1() v2alpha1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
@@ -44,3 +47,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
func (g *group) V1() v1.Interface {
|
||||
return v1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
// V2alpha1 returns a new v2alpha1.Interface.
|
||||
func (g *group) V2alpha1() v2alpha1.Interface {
|
||||
return v2alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
velerov2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
versioned "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
|
||||
internalinterfaces "github.com/vmware-tanzu/velero/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/generated/listers/velero/v2alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// DataDownloadInformer provides access to a shared informer and lister for
|
||||
// DataDownloads.
|
||||
type DataDownloadInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v2alpha1.DataDownloadLister
|
||||
}
|
||||
|
||||
type dataDownloadInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewDataDownloadInformer constructs a new informer for DataDownload type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewDataDownloadInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredDataDownloadInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredDataDownloadInformer constructs a new informer for DataDownload type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredDataDownloadInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.VeleroV2alpha1().DataDownloads(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.VeleroV2alpha1().DataDownloads(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&velerov2alpha1.DataDownload{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *dataDownloadInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredDataDownloadInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *dataDownloadInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&velerov2alpha1.DataDownload{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *dataDownloadInformer) Lister() v2alpha1.DataDownloadLister {
|
||||
return v2alpha1.NewDataDownloadLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
velerov2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
versioned "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
|
||||
internalinterfaces "github.com/vmware-tanzu/velero/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/generated/listers/velero/v2alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// DataUploadInformer provides access to a shared informer and lister for
|
||||
// DataUploads.
|
||||
type DataUploadInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v2alpha1.DataUploadLister
|
||||
}
|
||||
|
||||
type dataUploadInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewDataUploadInformer constructs a new informer for DataUpload type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewDataUploadInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredDataUploadInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredDataUploadInformer constructs a new informer for DataUpload type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredDataUploadInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.VeleroV2alpha1().DataUploads(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.VeleroV2alpha1().DataUploads(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&velerov2alpha1.DataUpload{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *dataUploadInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredDataUploadInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *dataUploadInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&velerov2alpha1.DataUpload{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *dataUploadInformer) Lister() v2alpha1.DataUploadLister {
|
||||
return v2alpha1.NewDataUploadLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
internalinterfaces "github.com/vmware-tanzu/velero/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// DataDownloads returns a DataDownloadInformer.
|
||||
DataDownloads() DataDownloadInformer
|
||||
// DataUploads returns a DataUploadInformer.
|
||||
DataUploads() DataUploadInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// DataDownloads returns a DataDownloadInformer.
|
||||
func (v *version) DataDownloads() DataDownloadInformer {
|
||||
return &dataDownloadInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// DataUploads returns a DataUploadInformer.
|
||||
func (v *version) DataUploads() DataUploadInformer {
|
||||
return &dataUploadInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
99
pkg/generated/listers/velero/v2alpha1/datadownload.go
Normal file
99
pkg/generated/listers/velero/v2alpha1/datadownload.go
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// DataDownloadLister helps list DataDownloads.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type DataDownloadLister interface {
|
||||
// List lists all DataDownloads in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v2alpha1.DataDownload, err error)
|
||||
// DataDownloads returns an object that can list and get DataDownloads.
|
||||
DataDownloads(namespace string) DataDownloadNamespaceLister
|
||||
DataDownloadListerExpansion
|
||||
}
|
||||
|
||||
// dataDownloadLister implements the DataDownloadLister interface.
|
||||
type dataDownloadLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewDataDownloadLister returns a new DataDownloadLister.
|
||||
func NewDataDownloadLister(indexer cache.Indexer) DataDownloadLister {
|
||||
return &dataDownloadLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all DataDownloads in the indexer.
|
||||
func (s *dataDownloadLister) List(selector labels.Selector) (ret []*v2alpha1.DataDownload, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v2alpha1.DataDownload))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// DataDownloads returns an object that can list and get DataDownloads.
|
||||
func (s *dataDownloadLister) DataDownloads(namespace string) DataDownloadNamespaceLister {
|
||||
return dataDownloadNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// DataDownloadNamespaceLister helps list and get DataDownloads.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type DataDownloadNamespaceLister interface {
|
||||
// List lists all DataDownloads in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v2alpha1.DataDownload, err error)
|
||||
// Get retrieves the DataDownload from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v2alpha1.DataDownload, error)
|
||||
DataDownloadNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// dataDownloadNamespaceLister implements the DataDownloadNamespaceLister
|
||||
// interface.
|
||||
type dataDownloadNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all DataDownloads in the indexer for a given namespace.
|
||||
func (s dataDownloadNamespaceLister) List(selector labels.Selector) (ret []*v2alpha1.DataDownload, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v2alpha1.DataDownload))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the DataDownload from the indexer for a given namespace and name.
|
||||
func (s dataDownloadNamespaceLister) Get(name string) (*v2alpha1.DataDownload, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v2alpha1.Resource("datadownload"), name)
|
||||
}
|
||||
return obj.(*v2alpha1.DataDownload), nil
|
||||
}
|
||||
99
pkg/generated/listers/velero/v2alpha1/dataupload.go
Normal file
99
pkg/generated/listers/velero/v2alpha1/dataupload.go
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
v2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// DataUploadLister helps list DataUploads.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type DataUploadLister interface {
|
||||
// List lists all DataUploads in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v2alpha1.DataUpload, err error)
|
||||
// DataUploads returns an object that can list and get DataUploads.
|
||||
DataUploads(namespace string) DataUploadNamespaceLister
|
||||
DataUploadListerExpansion
|
||||
}
|
||||
|
||||
// dataUploadLister implements the DataUploadLister interface.
|
||||
type dataUploadLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewDataUploadLister returns a new DataUploadLister.
|
||||
func NewDataUploadLister(indexer cache.Indexer) DataUploadLister {
|
||||
return &dataUploadLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all DataUploads in the indexer.
|
||||
func (s *dataUploadLister) List(selector labels.Selector) (ret []*v2alpha1.DataUpload, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v2alpha1.DataUpload))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// DataUploads returns an object that can list and get DataUploads.
|
||||
func (s *dataUploadLister) DataUploads(namespace string) DataUploadNamespaceLister {
|
||||
return dataUploadNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// DataUploadNamespaceLister helps list and get DataUploads.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type DataUploadNamespaceLister interface {
|
||||
// List lists all DataUploads in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v2alpha1.DataUpload, err error)
|
||||
// Get retrieves the DataUpload from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v2alpha1.DataUpload, error)
|
||||
DataUploadNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// dataUploadNamespaceLister implements the DataUploadNamespaceLister
|
||||
// interface.
|
||||
type dataUploadNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all DataUploads in the indexer for a given namespace.
|
||||
func (s dataUploadNamespaceLister) List(selector labels.Selector) (ret []*v2alpha1.DataUpload, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v2alpha1.DataUpload))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the DataUpload from the indexer for a given namespace and name.
|
||||
func (s dataUploadNamespaceLister) Get(name string) (*v2alpha1.DataUpload, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v2alpha1.Resource("dataupload"), name)
|
||||
}
|
||||
return obj.(*v2alpha1.DataUpload), nil
|
||||
}
|
||||
35
pkg/generated/listers/velero/v2alpha1/expansion_generated.go
Normal file
35
pkg/generated/listers/velero/v2alpha1/expansion_generated.go
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v2alpha1
|
||||
|
||||
// DataDownloadListerExpansion allows custom methods to be added to
|
||||
// DataDownloadLister.
|
||||
type DataDownloadListerExpansion interface{}
|
||||
|
||||
// DataDownloadNamespaceListerExpansion allows custom methods to be added to
|
||||
// DataDownloadNamespaceLister.
|
||||
type DataDownloadNamespaceListerExpansion interface{}
|
||||
|
||||
// DataUploadListerExpansion allows custom methods to be added to
|
||||
// DataUploadLister.
|
||||
type DataUploadListerExpansion interface{}
|
||||
|
||||
// DataUploadNamespaceListerExpansion allows custom methods to be added to
|
||||
// DataUploadNamespaceLister.
|
||||
type DataUploadNamespaceListerExpansion interface{}
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
v1crds "github.com/vmware-tanzu/velero/config/crd/v1/crds"
|
||||
v2alpha1crds "github.com/vmware-tanzu/velero/config/crd/v2alpha1/crds"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
)
|
||||
|
||||
@@ -252,7 +253,14 @@ func AllCRDs() *unstructured.UnstructuredList {
|
||||
for _, crd := range v1crds.CRDs {
|
||||
crd.SetLabels(Labels())
|
||||
if err := appendUnstructured(resources, crd); err != nil {
|
||||
fmt.Printf("error appending CRD %s: %s\n", crd.GetName(), err.Error())
|
||||
fmt.Printf("error appending v1 CRD %s: %s\n", crd.GetName(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
for _, crd := range v2alpha1crds.CRDs {
|
||||
crd.SetLabels(Labels())
|
||||
if err := appendUnstructured(resources, crd); err != nil {
|
||||
fmt.Printf("error appending v2alpha1 CRD %s: %s\n", crd.GetName(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
)
|
||||
|
||||
func PluginConfigLabelSelector(kind PluginKind, name string) string {
|
||||
return fmt.Sprintf("velero.io/plugin-config=true,%s=%s", name, kind)
|
||||
return fmt.Sprintf("velero.io/plugin-config,%s=%s", name, kind)
|
||||
}
|
||||
|
||||
func GetPluginConfig(kind PluginKind, name string, client corev1client.ConfigMapInterface) (*corev1.ConfigMap, error) {
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
@@ -35,7 +34,7 @@ func TestGetPluginConfig(t *testing.T) {
|
||||
name string
|
||||
objects []runtime.Object
|
||||
}
|
||||
pluginLabelsSet, _ := labels.ConvertSelectorToLabelsMap(PluginConfigLabelSelector(PluginKindRestoreItemAction, "foo"))
|
||||
pluginLabelsMap := map[string]string{"velero.io/plugin-config": "", "foo": "RestoreItemAction"}
|
||||
testConfigMap := &corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "ConfigMap",
|
||||
@@ -43,7 +42,7 @@ func TestGetPluginConfig(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo-config",
|
||||
Namespace: velerov1.DefaultNamespace,
|
||||
Labels: pluginLabelsSet,
|
||||
Labels: pluginLabelsMap,
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
@@ -75,7 +74,7 @@ func TestGetPluginConfig(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo-config",
|
||||
Namespace: velerov1.DefaultNamespace,
|
||||
Labels: pluginLabelsSet,
|
||||
Labels: pluginLabelsMap,
|
||||
},
|
||||
},
|
||||
&corev1.ConfigMap{
|
||||
@@ -85,7 +84,7 @@ func TestGetPluginConfig(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo-config-duplicate",
|
||||
Namespace: velerov1.DefaultNamespace,
|
||||
Labels: pluginLabelsSet,
|
||||
Labels: pluginLabelsMap,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -131,7 +131,7 @@ func (b *backupper) BackupPodVolumes(backup *velerov1api.Backup, pod *corev1api.
|
||||
if len(volumesToBackup) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
log.Infof("pod %s/%s has volumes to backup: %v", pod.Namespace, pod.Name, volumesToBackup)
|
||||
err := kube.IsPodRunning(pod)
|
||||
if err != nil {
|
||||
for _, volumeName := range volumesToBackup {
|
||||
|
||||
@@ -17,13 +17,19 @@ limitations under the License.
|
||||
package podvolume
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/resourcepolicies"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
)
|
||||
|
||||
func TestIsHostPathVolume(t *testing.T) {
|
||||
@@ -139,3 +145,62 @@ func (g *fakePVGetter) Get(ctx context.Context, name string, opts metav1.GetOpti
|
||||
|
||||
return nil, errors.New("item not found")
|
||||
}
|
||||
|
||||
func Test_backupper_BackupPodVolumes_log_test(t *testing.T) {
|
||||
type args struct {
|
||||
backup *velerov1api.Backup
|
||||
pod *corev1api.Pod
|
||||
volumesToBackup []string
|
||||
resPolicies *resourcepolicies.Policies
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantLog string
|
||||
}{
|
||||
{
|
||||
name: "backup pod volumes should log volume names",
|
||||
args: args{
|
||||
backup: &velerov1api.Backup{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "backup-1",
|
||||
Namespace: "ns-1",
|
||||
},
|
||||
},
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-1",
|
||||
Namespace: "ns-1",
|
||||
},
|
||||
Spec: corev1api.PodSpec{
|
||||
Volumes: []corev1api.Volume{
|
||||
{
|
||||
Name: "vol-1",
|
||||
},
|
||||
{
|
||||
Name: "vol-2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
volumesToBackup: []string{"vol-1", "vol-2"},
|
||||
resPolicies: nil,
|
||||
},
|
||||
wantLog: "pod ns-1/pod-1 has volumes to backup: [vol-1 vol-2]",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
b := &backupper{
|
||||
ctx: context.Background(),
|
||||
}
|
||||
logOutput := bytes.Buffer{}
|
||||
var log = logrus.New()
|
||||
log.SetOutput(&logOutput)
|
||||
b.BackupPodVolumes(tt.args.backup, tt.args.pod, tt.args.volumesToBackup, tt.args.resPolicies, log)
|
||||
fmt.Println(logOutput.String())
|
||||
assert.Contains(t, logOutput.String(), tt.wantLog)
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -498,6 +499,10 @@ func getStorageVariables(backupLocation *velerov1api.BackupStorageLocation, repo
|
||||
result[udmrepo.StoreOptionS3Endpoint] = strings.Trim(s3URL, "/")
|
||||
result[udmrepo.StoreOptionS3DisableTLSVerify] = config["insecureSkipTLSVerify"]
|
||||
result[udmrepo.StoreOptionS3DisableTLS] = strconv.FormatBool(disableTLS)
|
||||
|
||||
if backupLocation.Spec.ObjectStorage != nil && backupLocation.Spec.ObjectStorage.CACert != nil {
|
||||
result[udmrepo.StoreOptionS3CustomCA] = base64.StdEncoding.EncodeToString(backupLocation.Spec.ObjectStorage.CACert)
|
||||
}
|
||||
} else if backendType == repoconfig.AzureBackend {
|
||||
domain, err := getAzureStorageDomain(config)
|
||||
if err != nil {
|
||||
|
||||
@@ -18,6 +18,7 @@ package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
@@ -380,6 +381,42 @@ func TestGetStorageVariables(t *testing.T) {
|
||||
"skipTLSVerify": "false",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "aws, ObjectStorage section exists in BSL, s3Url exist, https, custom CA exist",
|
||||
backupLocation: velerov1api.BackupStorageLocation{
|
||||
Spec: velerov1api.BackupStorageLocationSpec{
|
||||
Provider: "velero.io/aws",
|
||||
Config: map[string]string{
|
||||
"bucket": "fake-bucket-config",
|
||||
"prefix": "fake-prefix-config",
|
||||
"region": "fake-region",
|
||||
"s3Url": "https://fake-url/",
|
||||
"insecureSkipTLSVerify": "false",
|
||||
},
|
||||
StorageType: velerov1api.StorageType{
|
||||
ObjectStorage: &velerov1api.ObjectStorageLocation{
|
||||
Bucket: "fake-bucket-object-store",
|
||||
Prefix: "fake-prefix-object-store",
|
||||
CACert: []byte{0x01, 0x02, 0x03, 0x04, 0x05},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getS3BucketRegion: func(bucket string) (string, error) {
|
||||
return "region from bucket: " + bucket, nil
|
||||
},
|
||||
repoBackend: "fake-repo-type",
|
||||
expected: map[string]string{
|
||||
"bucket": "fake-bucket-object-store",
|
||||
"prefix": "fake-prefix-object-store/fake-repo-type/",
|
||||
"region": "fake-region",
|
||||
"fspath": "",
|
||||
"endpoint": "fake-url",
|
||||
"doNotUseTLS": "false",
|
||||
"skipTLSVerify": "false",
|
||||
"customCA": base64.StdEncoding.EncodeToString([]byte{0x01, 0x02, 0x03, 0x04, 0x05}),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "azure, getAzureStorageDomain fail",
|
||||
backupLocation: velerov1api.BackupStorageLocation{
|
||||
|
||||
@@ -44,6 +44,7 @@ func (c *S3Backend) Setup(ctx context.Context, flags map[string]string) error {
|
||||
c.options.DoNotUseTLS = optionalHaveBool(ctx, udmrepo.StoreOptionS3DisableTLS, flags)
|
||||
c.options.DoNotVerifyTLS = optionalHaveBool(ctx, udmrepo.StoreOptionS3DisableTLSVerify, flags)
|
||||
c.options.SessionToken = optionalHaveString(udmrepo.StoreOptionS3Token, flags)
|
||||
c.options.RootCA = optionalHaveBase64(ctx, udmrepo.StoreOptionS3CustomCA, flags)
|
||||
|
||||
c.options.Limits = setupLimits(ctx, flags)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -84,6 +85,19 @@ func optionalHaveDuration(ctx context.Context, key string, flags map[string]stri
|
||||
return 0
|
||||
}
|
||||
|
||||
func optionalHaveBase64(ctx context.Context, key string, flags map[string]string) []byte {
|
||||
if value, exist := flags[key]; exist {
|
||||
ret, err := base64.StdEncoding.DecodeString(value)
|
||||
if err == nil {
|
||||
return ret
|
||||
}
|
||||
|
||||
backendLog()(ctx).Errorf("Ignore %s, value [%s] is invalid, err %v", key, value, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func backendLog() func(ctx context.Context) logging.Logger {
|
||||
return logging.Module("kopialib-bd")
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ const (
|
||||
StoreOptionS3Endpoint = "endpoint"
|
||||
StoreOptionS3DisableTLS = "doNotUseTLS"
|
||||
StoreOptionS3DisableTLSVerify = "skipTLSVerify"
|
||||
StoreOptionS3CustomCA = "customCA"
|
||||
|
||||
StoreOptionAzureKey = "storageKey"
|
||||
StoreOptionAzureDomain = "storageDomain"
|
||||
|
||||
@@ -55,7 +55,7 @@ func TestChangeImageRepositoryActionExecute(t *testing.T) {
|
||||
Image: "1.1.1.1:5000/abc:test",
|
||||
}).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-image-name").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
Data("case1", "1.1.1.1:5000 , 2.2.2.2:3000").
|
||||
Result(),
|
||||
freshedImageName: "2.2.2.2:3000/abc:test",
|
||||
@@ -70,7 +70,7 @@ func TestChangeImageRepositoryActionExecute(t *testing.T) {
|
||||
Image: "1.1.1.1:5000/abc:test",
|
||||
}).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-image-name").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
Data("specific", "1.1.1.1:5000,2.2.2.2:3000").
|
||||
Result(),
|
||||
freshedImageName: "2.2.2.2:3000/abc:test",
|
||||
@@ -85,7 +85,7 @@ func TestChangeImageRepositoryActionExecute(t *testing.T) {
|
||||
Image: "1.1.1.1:5000/abc:test",
|
||||
}).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-image-name").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
Data("specific", "abc:test,myproject:latest").
|
||||
Result(),
|
||||
freshedImageName: "1.1.1.1:5000/myproject:latest",
|
||||
@@ -100,7 +100,7 @@ func TestChangeImageRepositoryActionExecute(t *testing.T) {
|
||||
Image: "1.1.1.1:5000/abc:test",
|
||||
}).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-image-name").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
Data("specific", "5000,3333").
|
||||
Result(),
|
||||
freshedImageName: "1.1.1.1:5000/abc:test",
|
||||
@@ -115,7 +115,7 @@ func TestChangeImageRepositoryActionExecute(t *testing.T) {
|
||||
Image: "1.1.1.1:5000/abc:test",
|
||||
}).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-image-name").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
Data("specific", "test,latest").
|
||||
Result(),
|
||||
freshedImageName: "1.1.1.1:5000/abc:test",
|
||||
@@ -130,7 +130,7 @@ func TestChangeImageRepositoryActionExecute(t *testing.T) {
|
||||
Image: "dev/image1:dev",
|
||||
}).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-image-name").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-image-name", "RestoreItemAction")).
|
||||
Data("specific", "dev/,test/").
|
||||
Result(),
|
||||
freshedImageName: "dev/image1:dev",
|
||||
|
||||
@@ -57,7 +57,7 @@ func TestChangePVCNodeSelectorActionExecute(t *testing.T) {
|
||||
builder.WithAnnotations("volume.kubernetes.io/selected-node", "source-node"),
|
||||
).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-pvc-node").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
Data("source-node", "dest-node").
|
||||
Result(),
|
||||
newNode: builder.ForNode("dest-node").Result(),
|
||||
@@ -73,7 +73,7 @@ func TestChangePVCNodeSelectorActionExecute(t *testing.T) {
|
||||
builder.WithAnnotations("volume.kubernetes.io/selected-node", "source-node"),
|
||||
).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-pvc-node").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/some-other-plugin", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/some-other-plugin", "RestoreItemAction")).
|
||||
Data("source-noed", "dest-node").
|
||||
Result(),
|
||||
want: builder.ForPersistentVolumeClaim("source-ns", "pvc-1").Result(),
|
||||
@@ -85,7 +85,7 @@ func TestChangePVCNodeSelectorActionExecute(t *testing.T) {
|
||||
builder.WithAnnotations("volume.kubernetes.io/selected-node", "source-node"),
|
||||
).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-pvc-node").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
Result(),
|
||||
want: builder.ForPersistentVolumeClaim("source-ns", "pvc-1").Result(),
|
||||
},
|
||||
@@ -96,7 +96,7 @@ func TestChangePVCNodeSelectorActionExecute(t *testing.T) {
|
||||
builder.WithAnnotations("volume.kubernetes.io/selected-node", "source-node"),
|
||||
).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-pvc-node").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
Result(),
|
||||
// MAYANK TODO
|
||||
node: builder.ForNode("source-node").Result(),
|
||||
@@ -109,7 +109,7 @@ func TestChangePVCNodeSelectorActionExecute(t *testing.T) {
|
||||
name: "when persistent volume claim has no node selector, the item is returned as-is",
|
||||
pvc: builder.ForPersistentVolumeClaim("source-ns", "pvc-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-pvc-node").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
Data("source-node", "dest-node").
|
||||
Result(),
|
||||
want: builder.ForPersistentVolumeClaim("source-ns", "pvc-1").Result(),
|
||||
@@ -121,7 +121,7 @@ func TestChangePVCNodeSelectorActionExecute(t *testing.T) {
|
||||
builder.WithAnnotations("volume.kubernetes.io/selected-node", "source-node"),
|
||||
).Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-pvc-node").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-pvc-node-selector", "RestoreItemAction")).
|
||||
Data("source-node-1", "dest-node").
|
||||
Result(),
|
||||
want: builder.ForPersistentVolumeClaim("source-ns", "pvc-1").Result(),
|
||||
|
||||
@@ -53,7 +53,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "a valid mapping for a persistent volume is applied correctly",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolume("pv-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "storageclass-2").
|
||||
Result(),
|
||||
storageClass: builder.ForStorageClass("storageclass-2").Result(),
|
||||
@@ -63,7 +63,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "a valid mapping for a persistent volume claim is applied correctly",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolumeClaim("velero", "pvc-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "storageclass-2").
|
||||
Result(),
|
||||
storageClass: builder.ForStorageClass("storageclass-2").Result(),
|
||||
@@ -73,7 +73,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when no config map exists for the plugin, the item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolume("pv-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/some-other-plugin", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/some-other-plugin", "RestoreItemAction")).
|
||||
Data("storageclass-1", "storageclass-2").
|
||||
Result(),
|
||||
want: builder.ForPersistentVolume("pv-1").StorageClass("storageclass-1").Result(),
|
||||
@@ -82,7 +82,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when no storage class mappings exist in the plugin config map, the item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolume("pv-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Result(),
|
||||
want: builder.ForPersistentVolume("pv-1").StorageClass("storageclass-1").Result(),
|
||||
},
|
||||
@@ -90,7 +90,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when persistent volume has no storage class, the item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolume("pv-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "storageclass-2").
|
||||
Result(),
|
||||
want: builder.ForPersistentVolume("pv-1").Result(),
|
||||
@@ -99,7 +99,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when persistent volume claim has no storage class, the item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolumeClaim("velero", "pvc-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "storageclass-2").
|
||||
Result(),
|
||||
want: builder.ForPersistentVolumeClaim("velero", "pvc-1").Result(),
|
||||
@@ -108,7 +108,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when persistent volume's storage class has no mapping in the config map, the item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolume("pv-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-3", "storageclass-4").
|
||||
Result(),
|
||||
want: builder.ForPersistentVolume("pv-1").StorageClass("storageclass-1").Result(),
|
||||
@@ -117,7 +117,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when persistent volume claim's storage class has no mapping in the config map, the item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolumeClaim("velero", "pvc-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-3", "storageclass-4").
|
||||
Result(),
|
||||
want: builder.ForPersistentVolumeClaim("velero", "pvc-1").StorageClass("storageclass-1").Result(),
|
||||
@@ -126,7 +126,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when persistent volume's storage class is mapped to a nonexistent storage class, an error is returned",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolume("pv-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "nonexistent-storage-class").
|
||||
Result(),
|
||||
wantErr: errors.New("error getting storage class nonexistent-storage-class from API: storageclasses.storage.k8s.io \"nonexistent-storage-class\" not found"),
|
||||
@@ -135,7 +135,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when persistent volume claim's storage class is mapped to a nonexistent storage class, an error is returned",
|
||||
pvOrPvcOrSTS: builder.ForPersistentVolumeClaim("velero", "pvc-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "nonexistent-storage-class").
|
||||
Result(),
|
||||
wantErr: errors.New("error getting storage class nonexistent-storage-class from API: storageclasses.storage.k8s.io \"nonexistent-storage-class\" not found"),
|
||||
@@ -144,7 +144,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when statefulset's VolumeClaimTemplates has only one pvc, a valid mapping for a statefulset is applied correctly",
|
||||
pvOrPvcOrSTS: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "storageclass-2").
|
||||
Result(),
|
||||
storageClass: builder.ForStorageClass("storageclass-2").Result(),
|
||||
@@ -154,7 +154,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when statefulset's VolumeClaimTemplates has more than one same pvc's storageClassName, a valid mapping for a statefulset is applied correctly",
|
||||
pvOrPvcOrSTS: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1", "storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "storageclass-2", "storageclass-3", "storageclass-4").
|
||||
Result(),
|
||||
storageClass: builder.ForStorageClass("storageclass-2").Result(),
|
||||
@@ -164,7 +164,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when statefulset's VolumeClaimTemplates has more than one different pvc's storageClassName, a valid mapping for a statefulset is applied correctly",
|
||||
pvOrPvcOrSTS: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1", "storageclass-2", "storageclass-3").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "storageclass-a", "storageclass-2", "storageclass-b", "storageclass-3", "storageclass-c").
|
||||
Result(),
|
||||
storageClassSlice: builder.ForStorageClassSlice("storageclass-a", "storageclass-b", "storageclass-c").SliceResult(),
|
||||
@@ -174,7 +174,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when no config map exists for the plugin, the statefulset item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/some-other-plugin", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/some-other-plugin", "RestoreItemAction")).
|
||||
Data("storageclass-1", "storageclass-2").
|
||||
Result(),
|
||||
want: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1").Result(),
|
||||
@@ -183,7 +183,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when no storage class mappings exist in the plugin config map, the statefulset item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Result(),
|
||||
want: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1").Result(),
|
||||
},
|
||||
@@ -191,7 +191,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when persistent volume claim has no storage class, the statefulset item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForStatefulSet("velero", "sts-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Result(),
|
||||
want: builder.ForStatefulSet("velero", "sts-1").Result(),
|
||||
},
|
||||
@@ -199,7 +199,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when statefulset's storage class has no mapping in the config map, the item is returned as-is",
|
||||
pvOrPvcOrSTS: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-3", "storageclass-4").
|
||||
Result(),
|
||||
want: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1").Result(),
|
||||
@@ -208,7 +208,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) {
|
||||
name: "when statefulset's storage class is mapped to a nonexistent storage class, an error is returned",
|
||||
pvOrPvcOrSTS: builder.ForStatefulSet("velero", "sts-1").StorageClass("storageclass-1").Result(),
|
||||
configMap: builder.ForConfigMap("velero", "change-storage-classs").
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "true", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
ObjectMeta(builder.WithLabels("velero.io/plugin-config", "", "velero.io/change-storage-class", "RestoreItemAction")).
|
||||
Data("storageclass-1", "nonexistent-storage-class").
|
||||
Result(),
|
||||
wantErr: errors.New("error getting storage class nonexistent-storage-class from API: storageclasses.storage.k8s.io \"nonexistent-storage-class\" not found"),
|
||||
|
||||
@@ -27,12 +27,15 @@ import (
|
||||
k8sfake "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
)
|
||||
|
||||
func NewFakeControllerRuntimeClientBuilder(t *testing.T) *k8sfake.ClientBuilder {
|
||||
scheme := runtime.NewScheme()
|
||||
err := velerov1api.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
err = velerov2alpha1api.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
err = corev1api.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
err = snapshotv1api.AddToScheme(scheme)
|
||||
@@ -44,6 +47,8 @@ func NewFakeControllerRuntimeClient(t *testing.T, initObjs ...runtime.Object) cl
|
||||
scheme := runtime.NewScheme()
|
||||
err := velerov1api.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
err = velerov2alpha1api.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
err = corev1api.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
err = snapshotv1api.AddToScheme(scheme)
|
||||
|
||||
@@ -174,6 +174,7 @@ func (sr *shimRepository) NewObjectWriter(ctx context.Context, option object.Wri
|
||||
opt.Prefix = udmrepo.ID(option.Prefix)
|
||||
opt.FullPath = ""
|
||||
opt.AccessMode = udmrepo.ObjectDataAccessModeFile
|
||||
opt.AsyncWrites = option.AsyncWrites
|
||||
|
||||
if strings.HasPrefix(option.Description, "DIR:") {
|
||||
opt.DataType = udmrepo.ObjectDataTypeMetadata
|
||||
|
||||
@@ -94,6 +94,13 @@ spec:
|
||||
matchLabels:
|
||||
app: velero
|
||||
component: server
|
||||
# Individual object when matched with any of the label selector specified in the set are to be included in the backup. Optional.
|
||||
# orLabelSelectors as well as labelSelector cannot co-exist, only one of them can be specified in the backup request
|
||||
orLabelSelectors:
|
||||
- matchLabels:
|
||||
app: velero
|
||||
- matchLabels:
|
||||
app: data-protection
|
||||
# Whether to snapshot volumes. Valid values are true, false, and null/unset. If unset, Velero performs snapshots as long as
|
||||
# a persistent volume provider is configured for Velero.
|
||||
snapshotVolumes: null
|
||||
|
||||
109
site/content/posts/2023-04-26-Velero-1.11.md
Normal file
109
site/content/posts/2023-04-26-Velero-1.11.md
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: "Velero 1.11: New Actions, New Horizons"
|
||||
excerpt: In this release, we've grown the team and continue to welcome new members to our community.We're thrilled to have such significant contributions from the community and we're proud to deliver Velero 1.11.
|
||||
author_name: Orlin Vasilev
|
||||
slug: Velero-1.11
|
||||
categories: ['velero','release']
|
||||
image: /img/posts/post-1.11.jpg
|
||||
# Tag should match author to drive author pages
|
||||
tags: ['Velero Team', 'Orlin Vasilev', 'Velero Release']
|
||||
---
|
||||
|
||||
We haven't posted for while, but this deserves your attention!
|
||||
Last week during KubeCon Europe in Amsterdam we released [Velero v1.11](https://github.com/vmware-tanzu/velero/releases/tag/v1.11.0), which brings significant improvements in its functionality, flexibility, and performance. In this blog post, we will discuss the new features and changes that come with Velero v1.11 and how they can benefit users.
|
||||
|
||||
The theme of the v1.11 release is most definitely more flexibility, not only with the features added, but also in terms of the Velero contribution, development, and quality assurance processes.
|
||||
|
||||
In case you missed it we have new Product Manager - [Pradeep Kumar Chaturvedi](https://github.com/pradeepkchaturvedi) and few new contributors from companies like DELL and Microsoft.
|
||||
|
||||
### Full list of changes can be found [here](https://github.com/vmware-tanzu/velero/releases/tag/v1.11.0)
|
||||
|
||||
## Release Highlights
|
||||
|
||||
### BackupItemAction v2
|
||||
This feature implements the BackupItemAction v2. BIA v2 has two new methods: Progress() and Cancel() and modifies the Execute() return value.
|
||||
|
||||
The API change is needed to facilitate long-running BackupItemAction plugin actions that may not be complete when the Execute() method returns. This will allow long-running BackupItemAction plugin actions to continue in the background while the Velero moves to the following plugin or the next item.
|
||||
[https://github.com/vmware-tanzu/velero/pull/5442](https://github.com/vmware-tanzu/velero/pull/5442)
|
||||
|
||||
### RestoreItemAction v2
|
||||
This feature implemented the RestoreItemAction v2. RIA v2 has three new methods: Progress(), Cancel(), and AreAdditionalItemsReady(), and it modifies RestoreItemActionExecuteOutput() structure in the RIA return value.
|
||||
|
||||
The Progress() and Cancel() methods are needed to facilitate long-running RestoreItemAction plugin actions that may not be complete when the Execute() method returns. This will allow long-running RestoreItemAction plugin actions to continue in the background while the Velero moves to the following plugin or the next item. The AreAdditionalItemsReady() method is needed to allow plugins to tell Velero to wait until the returned additional items have been restored and are ready for use in the cluster before restoring the current item.
|
||||
|
||||
[https://github.com/vmware-tanzu/velero/pull/5569](https://github.com/vmware-tanzu/velero/pull/5569)
|
||||
|
||||
### Plugin Progress Monitoring
|
||||
This is intended as a replacement for the previously-approved Upload Progress Monitoring design ([Upload Progress Monitoring](https://github.com/vmware-tanzu/velero/blob/main/design/upload-progress.md)) to expand the supported use cases beyond snapshot upload to include what was previously called Async Backup/Restore Item Actions.
|
||||
|
||||
### Flexible resource policy that can filter volumes to skip in the backup
|
||||
This feature provides a flexible policy to filter volumes in the backup without requiring patching any labels or annotations to the pods or volumes. This policy is configured as k8s ConfigMap and maintained by the users themselves, and it can be extended to more scenarios in the future. By now, the policy rules out volumes from backup depending on the CSI driver, NFS setting, volume size, and StorageClass setting. Please refer to [Resource policies rules](https://velero.io/docs/v1.11/resource-filtering/#resource-policies) for the policy's ConifgMap format. It is not guaranteed to work on unofficial third-party plugins as it may not follow the existing backup workflow code logic of Velero.
|
||||
|
||||
### Resource Filters that can distinguish cluster scope and namespace scope resources
|
||||
This feature adds four new resource filters for backup. The new filters are separated into cluster scope and namespace scope. Before this feature, Velero could not filter cluster scope resources precisely. This feature provides the ability and refactors existing resource filter parameters.
|
||||
|
||||
### New parameter in installation to customize the ServiceAccount name
|
||||
The `velero install` sub-command now includes a new parameter,`--service-account-name`, which allows users to specify the ServiceAccountName for the Velero and node-agent pods. This feature may be particularly useful for users who utilize IRSA (IAM Roles for Service Accounts) in Amazon EKS (Elastic Kubernetes Service)."
|
||||
|
||||
### Add a parameter for setting the Velero server connection with the k8s API server's timeout
|
||||
In Velero, some code pieces need to communicate with the k8s API server. Before v1.11, these code pieces used hard-code timeout settings. This feature adds a resource-timeout parameter in the velero server binary to make it configurable.
|
||||
|
||||
### Add resource list in the output of the restore describe command
|
||||
Before this feature, Velero restore didn't have a restored resources list as the Velero backup. It's not convenient for users to learn what is restored. This feature adds the resources list and the handling result of the resources (including created, updated, failed, and skipped).
|
||||
|
||||
### Support JSON format output of backup describe command
|
||||
Before the Velero v1.11 release, users could not choose Velero's backup describe command's output format. The command output format is friendly for human reading, but it's not a structured output, and it's not easy for other programs to get information from it. Velero v1.11 adds a JSON format output for the backup describe command.
|
||||
|
||||
### Refactor controllers with controller-runtime
|
||||
In v1.11, Backup Controller and Restore controller are refactored with controller-runtime. Till v1.11, all Velero controllers use the controller-runtime framework.
|
||||
|
||||
### Runtime and dependencies
|
||||
To fix CVEs and keep pace with Golang, Velero made changes as follows:
|
||||
* Bump Golang runtime to v1.19.8.
|
||||
* Bump several dependent libraries to new versions.
|
||||
* Compile Restic (v0.15.0) with Golang v1.19.8 instead of packaging the official binary.
|
||||
|
||||
|
||||
## Breaking changes
|
||||
* The Velero CSI plugin now determines whether to restore Volume's data from snapshots on the restore's restorePVs setting. Before v1.11, the CSI plugin doesn't check the restorePVs parameter setting.
|
||||
|
||||
|
||||
## Limitations/Known issues
|
||||
* The Flexible resource policy that can filter volumes to skip in the backup is not guaranteed to work on unofficial third-party plugins because the plugins may not follow the existing backup workflow code logic of Velero. The ConfigMap used as the policy is supposed to be maintained by users.
|
||||
|
||||
|
||||
### Improving Developer Experience
|
||||
|
||||
As we continue to grow our community of contributors, we want to lower the barrier to entry for making contributions to the Velero project.
|
||||
We’ve made huge improvements to the developer experience during this release cycle by introducing Tilt to the developer workflow.
|
||||
Using Tilt enables developers to make changes to Velero and its plugins, and have those changes automatically built and deployed to your cluster.
|
||||
This removes the need for any manual building or pushing of images, and provides a faster and much simpler workflow.
|
||||
Our Tilt configuration also enables contributors to more easily debug the Velero process using Delve, which has integrations with many editors and IDEs.
|
||||
If you would like to try it out, please see our [documentation](https://velero.io/docs/v1.11/tilt/).
|
||||
|
||||
### Looking Forward
|
||||
|
||||
We have more exciting additions and improvements to Velero earmarked for future releases.
|
||||
For v1.12, we would like to have your input again [here](https://github.com/vmware-tanzu/velero/discussions/6217)
|
||||
See our [1.12 RoadMap](https://github.com/vmware-tanzu/velero/wiki/1.12-Roadmap) for the complete list.
|
||||
|
||||
|
||||
### Join the Community and Make Velero Better
|
||||
|
||||
Velero is better because of our contributors and maintainers.
|
||||
It is because of you that we can bring great software to the community.
|
||||
Please join us during our online [community meetings every Tuesday](https://hackmd.io/Jq6F5zqZR7S80CeDWUklkA?view) and catch up with past meetings on YouTube on the [Velero Community Meetings playlist](https://www.youtube.com/watch?v=nc48ocI-6go&list=PL7bmigfV0EqQRysvqvqOtRNk4L5S7uqwM).
|
||||
|
||||
You can always find the latest project information at [velero.io](https://velero.io).
|
||||
Look for issues on GitHub marked ["Good first issue"](https://github.com/vmware-tanzu/velero/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+first+issue%22) or ["Help wanted"](https://github.com/vmware-tanzu/velero/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+wanted%22+) if you want to roll up your sleeves and write some code with us.
|
||||
|
||||
For opportunities to help and be helped, visit our [Community Support Q&A on GitHub](https://github.com/vmware-tanzu/velero/discussions/categories/community-support-q-a).
|
||||
|
||||
You can chat with us on [Kubernetes Slack in the #velero channel](https://kubernetes.slack.com/messages/C6VCGP4MT) and follow us on Twitter at [@projectvelero](https://twitter.com/projectvelero).
|
||||
|
||||
Orlin Vasilev
|
||||
Velero Community Lead
|
||||
|
||||
|
||||
Photo by [Markus Spiske on Unsplash](https://unsplash.com/@markusspiske?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)
|
||||
|
||||
BIN
site/static/img/posts/post-1.11.jpg
Normal file
BIN
site/static/img/posts/post-1.11.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 MiB |
@@ -150,7 +150,7 @@ func runBackupDeletionTests(client TestClient, veleroCfg VeleroConfig, backupNam
|
||||
}
|
||||
var snapshotCheckPoint SnapshotCheckPoint
|
||||
if useVolumeSnapshots {
|
||||
snapshotCheckPoint, err = GetSnapshotCheckPoint(client, veleroCfg, 2, deletionTest, backupName, KibishiiPodNameList)
|
||||
snapshotCheckPoint, err = GetSnapshotCheckPoint(client, veleroCfg, 2, deletionTest, backupName, KibishiiPVCNameList)
|
||||
Expect(err).NotTo(HaveOccurred(), "Fail to get Azure CSI snapshot checkpoint")
|
||||
err = SnapshotsShouldBeCreatedInCloud(veleroCfg.CloudProvider,
|
||||
veleroCfg.CloudCredentialsFile, veleroCfg.BSLBucket, bslConfig,
|
||||
|
||||
@@ -51,7 +51,7 @@ func (b *TTL) Init() {
|
||||
b.testNS = "backup-ttl-test-" + UUIDgen.String()
|
||||
b.backupName = "backup-ttl-test-" + UUIDgen.String()
|
||||
b.restoreName = "restore-ttl-test-" + UUIDgen.String()
|
||||
b.ttl = 20 * time.Minute
|
||||
b.ttl = 10 * time.Minute
|
||||
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ func TTLTest() {
|
||||
test.testNS, 2)).To(Succeed())
|
||||
})
|
||||
}
|
||||
snapshotCheckPoint, err = GetSnapshotCheckPoint(client, veleroCfg, 2, test.testNS, test.backupName, KibishiiPodNameList)
|
||||
snapshotCheckPoint, err = GetSnapshotCheckPoint(client, veleroCfg, 2, test.testNS, test.backupName, KibishiiPVCNameList)
|
||||
Expect(err).NotTo(HaveOccurred(), "Fail to get Azure CSI snapshot checkpoint")
|
||||
|
||||
Expect(SnapshotsShouldBeCreatedInCloud(veleroCfg.CloudProvider,
|
||||
|
||||
@@ -100,7 +100,7 @@ func APIGropuVersionsTest() {
|
||||
DeleteBackups(context.Background(), *veleroCfg.ClientToInstallVelero)
|
||||
})
|
||||
if veleroCfg.InstallVelero {
|
||||
By("Uninstall Velero", func() {
|
||||
By("Uninstall Velero in api group version case", func() {
|
||||
Expect(VeleroUninstall(ctx, veleroCfg.VeleroCLI, veleroCfg.VeleroNamespace)).NotTo(HaveOccurred())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -23,12 +23,16 @@ type NamespaceMapping struct {
|
||||
|
||||
const NamespaceBaseName string = "ns-mp-"
|
||||
|
||||
var OneNamespaceMappingResticTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: NamespaceBaseName, NSIncluded: &[]string{NamespaceBaseName + "1"}, UseVolumeSnapshots: false}})
|
||||
var MultiNamespacesMappingResticTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: NamespaceBaseName, NSIncluded: &[]string{NamespaceBaseName + "2", NamespaceBaseName + "3"}, UseVolumeSnapshots: false}})
|
||||
var OneNamespaceMappingSnapshotTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: NamespaceBaseName, NSIncluded: &[]string{NamespaceBaseName + "4"}, UseVolumeSnapshots: true}})
|
||||
var MultiNamespacesMappingSnapshotTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: NamespaceBaseName, NSIncluded: &[]string{NamespaceBaseName + "5", NamespaceBaseName + "6"}, UseVolumeSnapshots: true}})
|
||||
var OneNamespaceMappingResticTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NamespacesTotal: 1, UseVolumeSnapshots: false}})
|
||||
var MultiNamespacesMappingResticTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NamespacesTotal: 2, UseVolumeSnapshots: false}})
|
||||
var OneNamespaceMappingSnapshotTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NamespacesTotal: 1, UseVolumeSnapshots: true}})
|
||||
var MultiNamespacesMappingSnapshotTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NamespacesTotal: 2, UseVolumeSnapshots: true}})
|
||||
|
||||
func (n *NamespaceMapping) Init() error {
|
||||
n.TestCase.Init()
|
||||
n.CaseBaseName = "ns-mp-" + n.UUIDgen
|
||||
n.BackupName = "backup-" + n.CaseBaseName
|
||||
n.RestoreName = "restore-" + n.CaseBaseName
|
||||
n.VeleroCfg = VeleroCfg
|
||||
n.Client = *n.VeleroCfg.ClientToInstallVelero
|
||||
n.VeleroCfg.UseVolumeSnapshots = n.UseVolumeSnapshots
|
||||
@@ -38,30 +42,25 @@ func (n *NamespaceMapping) Init() error {
|
||||
if n.UseVolumeSnapshots {
|
||||
backupType = "snapshot"
|
||||
}
|
||||
var mappedNS string
|
||||
var mappedNSList []string
|
||||
n.NSIncluded = &[]string{}
|
||||
for nsNum := 0; nsNum < n.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", n.CaseBaseName, nsNum)
|
||||
*n.NSIncluded = append(*n.NSIncluded, createNSName)
|
||||
mappedNS = mappedNS + createNSName + ":" + createNSName + "-mapped"
|
||||
mappedNSList = append(mappedNSList, createNSName+"-mapped")
|
||||
mappedNS = mappedNS + ","
|
||||
}
|
||||
mappedNS = strings.TrimRightFunc(mappedNS, func(r rune) bool {
|
||||
return r == ','
|
||||
})
|
||||
|
||||
n.TestMsg = &TestMSG{
|
||||
Desc: fmt.Sprintf("Restore namespace %s with namespace mapping by %s test", *n.NSIncluded, backupType),
|
||||
FailedMSG: "Failed to restore with namespace mapping",
|
||||
Text: fmt.Sprintf("should restore namespace %s with namespace mapping by %s", *n.NSIncluded, backupType),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NamespaceMapping) StartRun() error {
|
||||
var mappedNS string
|
||||
var mappedNSList []string
|
||||
|
||||
for index, ns := range *n.NSIncluded {
|
||||
mappedNS = mappedNS + ns + ":" + ns + UUIDgen.String()
|
||||
mappedNSList = append(mappedNSList, ns+UUIDgen.String())
|
||||
if index+1 != len(*n.NSIncluded) {
|
||||
mappedNS = mappedNS + ","
|
||||
}
|
||||
n.BackupName = n.BackupName + ns
|
||||
n.RestoreName = n.RestoreName + ns
|
||||
}
|
||||
n.BackupName = n.BackupName + UUIDgen.String()
|
||||
n.RestoreName = n.RestoreName + UUIDgen.String()
|
||||
|
||||
n.MappedNamespaceList = mappedNSList
|
||||
fmt.Println(mappedNSList)
|
||||
n.BackupArgs = []string{
|
||||
@@ -81,16 +80,16 @@ func (n *NamespaceMapping) StartRun() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NamespaceMapping) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
n.Ctx, n.CtxCancel = context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
for index, ns := range *n.NSIncluded {
|
||||
n.kibishiiData.Levels = len(*n.NSIncluded) + index
|
||||
By(fmt.Sprintf("Creating namespaces ...%s\n", ns), func() {
|
||||
Expect(CreateNamespace(ctx, n.Client, ns)).To(Succeed(), fmt.Sprintf("Failed to create namespace %s", ns))
|
||||
Expect(CreateNamespace(n.Ctx, n.Client, ns)).To(Succeed(), fmt.Sprintf("Failed to create namespace %s", ns))
|
||||
})
|
||||
By("Deploy sample workload of Kibishii", func() {
|
||||
Expect(KibishiiPrepareBeforeBackup(ctx, n.Client, VeleroCfg.CloudProvider,
|
||||
Expect(KibishiiPrepareBeforeBackup(n.Ctx, n.Client, VeleroCfg.CloudProvider,
|
||||
ns, VeleroCfg.RegistryCredentialFile, VeleroCfg.Features,
|
||||
VeleroCfg.KibishiiDirectory, false, n.kibishiiData)).To(Succeed())
|
||||
})
|
||||
@@ -99,19 +98,33 @@ func (n *NamespaceMapping) CreateResources() error {
|
||||
}
|
||||
|
||||
func (n *NamespaceMapping) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
for index, ns := range n.MappedNamespaceList {
|
||||
n.kibishiiData.Levels = len(*n.NSIncluded) + index
|
||||
By(fmt.Sprintf("Verify workload %s after restore ", ns), func() {
|
||||
Expect(KibishiiVerifyAfterRestore(n.Client, ns,
|
||||
ctx, n.kibishiiData)).To(Succeed(), "Fail to verify workload after restore")
|
||||
n.Ctx, n.kibishiiData)).To(Succeed(), "Fail to verify workload after restore")
|
||||
})
|
||||
}
|
||||
for _, ns := range *n.NSIncluded {
|
||||
By(fmt.Sprintf("Verify namespace %s for backup is no longer exist after restore with namespace mapping", ns), func() {
|
||||
Expect(NamespaceShouldNotExist(ctx, n.Client, ns)).To(Succeed())
|
||||
Expect(NamespaceShouldNotExist(n.Ctx, n.Client, ns)).To(Succeed())
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NamespaceMapping) Clean() error {
|
||||
if !n.VeleroCfg.Debug {
|
||||
if err := DeleteStorageClass(context.Background(), n.Client, "kibishii-storage-class"); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, ns := range n.MappedNamespaceList {
|
||||
if err := DeleteNamespace(context.Background(), n.Client, ns, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return n.GetTestCase().Clean()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package basic
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
@@ -20,40 +21,42 @@ import (
|
||||
|
||||
type NodePort struct {
|
||||
TestCase
|
||||
replica int32
|
||||
labels map[string]string
|
||||
containers *[]v1.Container
|
||||
serviceName string
|
||||
serviceSpec *v1.ServiceSpec
|
||||
namespaceToCollision []string
|
||||
nodePort int32
|
||||
namespaceToCollision string
|
||||
namespace string
|
||||
}
|
||||
|
||||
const NodeportBaseName string = "nodeport-"
|
||||
|
||||
var NodePortTest func() = TestFunc(&NodePort{namespace: NodeportBaseName + "1", TestCase: TestCase{NSBaseName: NodeportBaseName}})
|
||||
var NodePortTest func() = TestFunc(&NodePort{})
|
||||
|
||||
func (n *NodePort) Init() error {
|
||||
n.TestCase.Init()
|
||||
n.CaseBaseName = NodeportBaseName + n.UUIDgen
|
||||
n.BackupName = "backup-" + n.CaseBaseName
|
||||
n.RestoreName = "restore-" + n.CaseBaseName
|
||||
n.serviceName = "nginx-service-" + n.CaseBaseName
|
||||
n.VeleroCfg = VeleroCfg
|
||||
n.Client = *n.VeleroCfg.ClientToInstallVelero
|
||||
n.NSBaseName = NodeportBaseName
|
||||
n.NamespacesTotal = 1
|
||||
n.TestMsg = &TestMSG{
|
||||
Desc: fmt.Sprintf("Nodeport preservation"),
|
||||
Desc: "Nodeport preservation",
|
||||
FailedMSG: "Failed to restore with nodeport preservation",
|
||||
Text: fmt.Sprintf("Nodeport can be preserved or omit during restore"),
|
||||
Text: "Nodeport can be preserved or omit during restore",
|
||||
}
|
||||
|
||||
n.labels = map[string]string{"app": "nginx"}
|
||||
n.NSIncluded = &[]string{}
|
||||
for nsNum := 0; nsNum < n.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", n.CaseBaseName, nsNum)
|
||||
n.namespaceToCollision = append(n.namespaceToCollision, createNSName+"tmp")
|
||||
*n.NSIncluded = append(*n.NSIncluded, createNSName)
|
||||
}
|
||||
n.BackupName = "backup-nodeport-" + UUIDgen.String()
|
||||
n.RestoreName = "restore-" + UUIDgen.String()
|
||||
n.serviceName = "nginx-service-" + UUIDgen.String()
|
||||
n.labels = map[string]string{"app": "nginx"}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NodePort) StartRun() error {
|
||||
n.BackupArgs = []string{
|
||||
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", n.BackupName,
|
||||
"--include-namespaces", n.namespace, "--wait",
|
||||
"--include-namespaces", strings.Join(*n.NSIncluded, ","), "--wait",
|
||||
}
|
||||
n.RestoreArgs = []string{
|
||||
"create", "--namespace", VeleroCfg.VeleroNamespace, "restore",
|
||||
@@ -63,47 +66,45 @@ func (n *NodePort) StartRun() error {
|
||||
return nil
|
||||
}
|
||||
func (n *NodePort) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
n.Ctx, n.CtxCancel = context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
|
||||
By(fmt.Sprintf("Creating service %s in namespaces %s ......\n", n.serviceName, n.namespace), func() {
|
||||
Expect(CreateNamespace(ctx, n.Client, n.namespace)).To(Succeed(), fmt.Sprintf("Failed to create namespace %s", n.namespace))
|
||||
Expect(createServiceWithNodeport(ctx, n.Client, n.namespace, n.serviceName, n.labels, 0)).To(Succeed(), fmt.Sprintf("Failed to create service %s", n.serviceName))
|
||||
service, err := GetService(ctx, n.Client, n.namespace, n.serviceName)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(len(service.Spec.Ports)).To(Equal(1))
|
||||
n.nodePort = service.Spec.Ports[0].NodePort
|
||||
_, err = GetAllService(ctx)
|
||||
Expect(err).To(Succeed(), "fail to get service")
|
||||
})
|
||||
for _, ns := range *n.NSIncluded {
|
||||
By(fmt.Sprintf("Creating service %s in namespaces %s ......\n", n.serviceName, ns), func() {
|
||||
Expect(CreateNamespace(n.Ctx, n.Client, ns)).To(Succeed(), fmt.Sprintf("Failed to create namespace %s", ns))
|
||||
Expect(createServiceWithNodeport(n.Ctx, n.Client, ns, n.serviceName, n.labels, 0)).To(Succeed(), fmt.Sprintf("Failed to create service %s", n.serviceName))
|
||||
service, err := GetService(n.Ctx, n.Client, ns, n.serviceName)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(len(service.Spec.Ports)).To(Equal(1))
|
||||
n.nodePort = service.Spec.Ports[0].NodePort
|
||||
_, err = GetAllService(n.Ctx)
|
||||
Expect(err).To(Succeed(), "fail to get service")
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NodePort) Destroy() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
By(fmt.Sprintf("Start to destroy namespace %s......", n.NSBaseName), func() {
|
||||
Expect(CleanupNamespacesWithPoll(ctx, n.Client, NodeportBaseName)).To(Succeed(),
|
||||
fmt.Sprintf("Failed to delete namespace %s", n.NSBaseName))
|
||||
Expect(WaitForServiceDelete(n.Client, n.namespace, n.serviceName, false)).To(Succeed(), "fail to delete service")
|
||||
_, err := GetAllService(ctx)
|
||||
Expect(err).To(Succeed(), "fail to get service")
|
||||
})
|
||||
for i, ns := range *n.NSIncluded {
|
||||
By(fmt.Sprintf("Start to destroy namespace %s......", n.CaseBaseName), func() {
|
||||
Expect(CleanupNamespacesWithPoll(n.Ctx, n.Client, NodeportBaseName)).To(Succeed(),
|
||||
fmt.Sprintf("Failed to delete namespace %s", n.CaseBaseName))
|
||||
Expect(WaitForServiceDelete(n.Client, ns, n.serviceName, false)).To(Succeed(), "fail to delete service")
|
||||
_, err := GetAllService(n.Ctx)
|
||||
Expect(err).To(Succeed(), "fail to get service")
|
||||
})
|
||||
|
||||
n.namespaceToCollision = NodeportBaseName + "tmp"
|
||||
By(fmt.Sprintf("Creating a new service which has the same nodeport as backed up service has in a new namespaces for nodeport collision ...%s\n", n.namespaceToCollision), func() {
|
||||
Expect(CreateNamespace(ctx, n.Client, n.namespaceToCollision)).To(Succeed(), fmt.Sprintf("Failed to create namespace %s", n.namespaceToCollision))
|
||||
Expect(createServiceWithNodeport(ctx, n.Client, n.namespaceToCollision, n.serviceName, n.labels, n.nodePort)).To(Succeed(), fmt.Sprintf("Failed to create service %s", n.serviceName))
|
||||
_, err := GetAllService(ctx)
|
||||
Expect(err).To(Succeed(), "fail to get service")
|
||||
})
|
||||
By(fmt.Sprintf("Creating a new service which has the same nodeport as backed up service has in a new namespaces for nodeport collision ...%s\n", n.namespaceToCollision[i]), func() {
|
||||
Expect(CreateNamespace(n.Ctx, n.Client, n.namespaceToCollision[i])).To(Succeed(), fmt.Sprintf("Failed to create namespace %s", n.namespaceToCollision[i]))
|
||||
Expect(createServiceWithNodeport(n.Ctx, n.Client, n.namespaceToCollision[i], n.serviceName, n.labels, n.nodePort)).To(Succeed(), fmt.Sprintf("Failed to create service %s", n.serviceName))
|
||||
_, err := GetAllService(n.Ctx)
|
||||
Expect(err).To(Succeed(), "fail to get service")
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NodePort) Restore() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
index := 4
|
||||
restoreName1 := n.RestoreName + "-1"
|
||||
restoreName2 := restoreName1 + "-1"
|
||||
@@ -112,7 +113,7 @@ func (n *NodePort) Restore() error {
|
||||
args = append(args[:index], append([]string{n.RestoreName}, args[index:]...)...)
|
||||
args = append(args, "--preserve-nodeports=true")
|
||||
By(fmt.Sprintf("Start to restore %s with nodeports preservation when port %d is already occupied by other service", n.RestoreName, n.nodePort), func() {
|
||||
Expect(VeleroRestoreExec(ctx, n.VeleroCfg.VeleroCLI,
|
||||
Expect(VeleroRestoreExec(n.Ctx, n.VeleroCfg.VeleroCLI,
|
||||
n.VeleroCfg.VeleroNamespace, n.RestoreName,
|
||||
args, velerov1api.RestorePhasePartiallyFailed)).To(
|
||||
Succeed(),
|
||||
@@ -127,44 +128,45 @@ func (n *NodePort) Restore() error {
|
||||
args = append(args[:index], append([]string{restoreName1}, args[index:]...)...)
|
||||
args = append(args, "--preserve-nodeports=false")
|
||||
By(fmt.Sprintf("Start to restore %s without nodeports preservation ......", restoreName1), func() {
|
||||
Expect(VeleroRestoreExec(ctx, n.VeleroCfg.VeleroCLI, n.VeleroCfg.VeleroNamespace,
|
||||
Expect(VeleroRestoreExec(n.Ctx, n.VeleroCfg.VeleroCLI, n.VeleroCfg.VeleroNamespace,
|
||||
restoreName1, args, velerov1api.RestorePhaseCompleted)).To(Succeed(), func() string {
|
||||
RunDebug(context.Background(), n.VeleroCfg.VeleroCLI, n.VeleroCfg.VeleroNamespace, "", restoreName1)
|
||||
return "Fail to restore workload"
|
||||
})
|
||||
})
|
||||
|
||||
By(fmt.Sprintf("Delete service %s by deleting namespace %s", n.serviceName, n.namespace), func() {
|
||||
service, err := GetService(ctx, n.Client, n.namespace, n.serviceName)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(len(service.Spec.Ports)).To(Equal(1))
|
||||
fmt.Println(service.Spec.Ports)
|
||||
Expect(DeleteNamespace(ctx, n.Client, n.namespace, true)).To(Succeed())
|
||||
})
|
||||
|
||||
By(fmt.Sprintf("Start to delete service %s in namespace %s ......", n.serviceName, n.namespaceToCollision), func() {
|
||||
Expect(WaitForServiceDelete(n.Client, n.namespaceToCollision, n.serviceName, true)).To(Succeed(), "fail to delete service")
|
||||
_, err := GetAllService(ctx)
|
||||
Expect(err).To(Succeed(), "fail to get service")
|
||||
})
|
||||
|
||||
args = n.RestoreArgs
|
||||
args = append(args[:index], append([]string{restoreName2}, args[index:]...)...)
|
||||
args = append(args, "--preserve-nodeports=true")
|
||||
By(fmt.Sprintf("Start to restore %s with nodeports preservation ......", restoreName2), func() {
|
||||
Expect(VeleroRestoreExec(ctx, n.VeleroCfg.VeleroCLI, n.VeleroCfg.VeleroNamespace,
|
||||
restoreName2, args, velerov1api.RestorePhaseCompleted)).To(Succeed(), func() string {
|
||||
RunDebug(context.Background(), n.VeleroCfg.VeleroCLI, n.VeleroCfg.VeleroNamespace, "", restoreName2)
|
||||
return "Fail to restore workload"
|
||||
for i, ns := range *n.NSIncluded {
|
||||
By(fmt.Sprintf("Delete service %s by deleting namespace %s", n.serviceName, ns), func() {
|
||||
service, err := GetService(n.Ctx, n.Client, ns, n.serviceName)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(len(service.Spec.Ports)).To(Equal(1))
|
||||
fmt.Println(service.Spec.Ports)
|
||||
Expect(DeleteNamespace(n.Ctx, n.Client, ns, true)).To(Succeed())
|
||||
})
|
||||
})
|
||||
|
||||
By(fmt.Sprintf("Verify service %s was restore successfully with the origin nodeport.", n.namespace), func() {
|
||||
service, err := GetService(ctx, n.Client, n.namespace, n.serviceName)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(len(service.Spec.Ports)).To(Equal(1))
|
||||
Expect(service.Spec.Ports[0].NodePort).To(Equal(n.nodePort))
|
||||
})
|
||||
By(fmt.Sprintf("Start to delete service %s in namespace %s ......", n.serviceName, n.namespaceToCollision[i]), func() {
|
||||
Expect(WaitForServiceDelete(n.Client, n.namespaceToCollision[i], n.serviceName, true)).To(Succeed(), "fail to delete service")
|
||||
_, err := GetAllService(n.Ctx)
|
||||
Expect(err).To(Succeed(), "fail to get service")
|
||||
})
|
||||
args = n.RestoreArgs
|
||||
args = append(args[:index], append([]string{restoreName2}, args[index:]...)...)
|
||||
args = append(args, "--preserve-nodeports=true")
|
||||
By(fmt.Sprintf("Start to restore %s with nodeports preservation ......", restoreName2), func() {
|
||||
Expect(VeleroRestoreExec(n.Ctx, n.VeleroCfg.VeleroCLI, n.VeleroCfg.VeleroNamespace,
|
||||
restoreName2, args, velerov1api.RestorePhaseCompleted)).To(Succeed(), func() string {
|
||||
RunDebug(context.Background(), n.VeleroCfg.VeleroCLI, n.VeleroCfg.VeleroNamespace, "", restoreName2)
|
||||
return "Fail to restore workload"
|
||||
})
|
||||
})
|
||||
|
||||
By(fmt.Sprintf("Verify service %s was restore successfully with the origin nodeport.", ns), func() {
|
||||
service, err := GetService(n.Ctx, n.Client, ns, n.serviceName)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(len(service.Spec.Ports)).To(Equal(1))
|
||||
Expect(service.Spec.Ports[0].NodePort).To(Equal(n.nodePort))
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -31,24 +31,22 @@ type PVCSelectedNodeChanging struct {
|
||||
ann string
|
||||
}
|
||||
|
||||
const PSNCBaseName string = "psnc-"
|
||||
|
||||
var PVCSelectedNodeChangingTest func() = TestFunc(&PVCSelectedNodeChanging{
|
||||
namespace: PSNCBaseName + "1", TestCase: TestCase{NSBaseName: PSNCBaseName}})
|
||||
var PVCSelectedNodeChangingTest func() = TestFunc(&PVCSelectedNodeChanging{})
|
||||
|
||||
func (p *PVCSelectedNodeChanging) Init() error {
|
||||
p.TestCase.Init()
|
||||
p.CaseBaseName = "psnc-" + p.UUIDgen
|
||||
p.namespace = p.CaseBaseName
|
||||
p.mappedNS = p.namespace + "-mapped"
|
||||
p.VeleroCfg = VeleroCfg
|
||||
p.Client = *p.VeleroCfg.ClientToInstallVelero
|
||||
p.NSBaseName = PSNCBaseName
|
||||
p.namespace = p.NSBaseName + UUIDgen.String()
|
||||
p.mappedNS = p.namespace + "-mapped"
|
||||
p.TestMsg = &TestMSG{
|
||||
Desc: "Changing PVC node selector",
|
||||
FailedMSG: "Failed to changing PVC node selector",
|
||||
Text: "Change node selectors of persistent volume claims during restores",
|
||||
}
|
||||
p.BackupName = "backup-sc-" + UUIDgen.String()
|
||||
p.RestoreName = "restore-" + UUIDgen.String()
|
||||
p.BackupName = "backup-" + p.CaseBaseName
|
||||
p.RestoreName = "restore-" + p.CaseBaseName
|
||||
p.labels = map[string]string{"velero.io/plugin-config": "",
|
||||
"velero.io/change-pvc-node-selector": "RestoreItemAction"}
|
||||
p.configmaptName = "change-pvc-node-selector-config"
|
||||
@@ -56,12 +54,6 @@ func (p *PVCSelectedNodeChanging) Init() error {
|
||||
p.podName = "pod-1"
|
||||
p.pvcName = "pvc-1"
|
||||
p.ann = "volume.kubernetes.io/selected-node"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PVCSelectedNodeChanging) StartRun() error {
|
||||
p.BackupName = p.BackupName + "backup-" + UUIDgen.String()
|
||||
p.RestoreName = p.RestoreName + "restore-" + UUIDgen.String()
|
||||
p.BackupArgs = []string{
|
||||
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", p.BackupName,
|
||||
"--include-namespaces", p.namespace,
|
||||
@@ -73,14 +65,16 @@ func (p *PVCSelectedNodeChanging) StartRun() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PVCSelectedNodeChanging) CreateResources() error {
|
||||
p.Ctx, p.CtxCancel = context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
By(fmt.Sprintf("Create namespace %s", p.namespace), func() {
|
||||
Expect(CreateNamespace(context.Background(), p.Client, p.namespace)).To(Succeed(),
|
||||
Expect(CreateNamespace(p.Ctx, p.Client, p.namespace)).To(Succeed(),
|
||||
fmt.Sprintf("Failed to create namespace %s", p.namespace))
|
||||
})
|
||||
|
||||
By(fmt.Sprintf("Create pod %s in namespace %s", p.podName, p.namespace), func() {
|
||||
nodeNameList, err := GetWorkerNodes(context.Background())
|
||||
nodeNameList, err := GetWorkerNodes(p.Ctx)
|
||||
Expect(err).To(Succeed())
|
||||
for _, nodeName := range nodeNameList {
|
||||
p.oldNodeName = nodeName
|
||||
@@ -88,14 +82,14 @@ func (p *PVCSelectedNodeChanging) CreateResources() error {
|
||||
pvcAnn := map[string]string{p.ann: nodeName}
|
||||
_, err := CreatePod(p.Client, p.namespace, p.podName, "default", p.pvcName, []string{p.volume}, pvcAnn, nil)
|
||||
Expect(err).To(Succeed())
|
||||
err = WaitForPods(context.Background(), p.Client, p.namespace, []string{p.podName})
|
||||
err = WaitForPods(p.Ctx, p.Client, p.namespace, []string{p.podName})
|
||||
Expect(err).To(Succeed())
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
By("Prepare ConfigMap data", func() {
|
||||
nodeNameList, err := GetWorkerNodes(context.Background())
|
||||
nodeNameList, err := GetWorkerNodes(p.Ctx)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(len(nodeNameList) > 2).To(Equal(true))
|
||||
for _, nodeName := range nodeNameList {
|
||||
@@ -116,18 +110,16 @@ func (p *PVCSelectedNodeChanging) CreateResources() error {
|
||||
}
|
||||
|
||||
func (p *PVCSelectedNodeChanging) Destroy() error {
|
||||
By(fmt.Sprintf("Start to destroy namespace %s......", p.NSBaseName), func() {
|
||||
Expect(CleanupNamespacesWithPoll(context.Background(), p.Client, p.NSBaseName)).To(Succeed(),
|
||||
fmt.Sprintf("Failed to delete namespace %s", p.NSBaseName))
|
||||
By(fmt.Sprintf("Start to destroy namespace %s......", p.CaseBaseName), func() {
|
||||
Expect(CleanupNamespacesWithPoll(p.Ctx, p.Client, p.CaseBaseName)).To(Succeed(),
|
||||
fmt.Sprintf("Failed to delete namespace %s", p.CaseBaseName))
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PVCSelectedNodeChanging) Restore() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
By(fmt.Sprintf("Start to restore %s .....", p.RestoreName), func() {
|
||||
Expect(VeleroRestoreExec(ctx, p.VeleroCfg.VeleroCLI,
|
||||
Expect(VeleroRestoreExec(p.Ctx, p.VeleroCfg.VeleroCLI,
|
||||
p.VeleroCfg.VeleroNamespace, p.RestoreName,
|
||||
p.RestoreArgs, velerov1api.RestorePhaseCompleted)).To(
|
||||
Succeed(),
|
||||
@@ -136,19 +128,29 @@ func (p *PVCSelectedNodeChanging) Restore() error {
|
||||
p.VeleroCfg.VeleroNamespace, "", p.RestoreName)
|
||||
return "Fail to restore workload"
|
||||
})
|
||||
err := WaitForPods(ctx, p.Client, p.mappedNS, []string{p.podName})
|
||||
err := WaitForPods(p.Ctx, p.Client, p.mappedNS, []string{p.podName})
|
||||
Expect(err).To(Succeed())
|
||||
})
|
||||
return nil
|
||||
}
|
||||
func (p *PVCSelectedNodeChanging) Verify() error {
|
||||
By(fmt.Sprintf("PVC selected node should be %s", p.newNodeName), func() {
|
||||
pvcNameList, err := GetPvcByPodName(context.Background(), p.mappedNS, p.pvcName)
|
||||
pvcNameList, err := GetPvcByPodName(p.Ctx, p.mappedNS, p.pvcName)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(len(pvcNameList)).Should(Equal(1))
|
||||
pvc, err := GetPVC(context.Background(), p.Client, p.mappedNS, pvcNameList[0])
|
||||
pvc, err := GetPVC(p.Ctx, p.Client, p.mappedNS, pvcNameList[0])
|
||||
Expect(err).To(Succeed())
|
||||
Expect(pvc.Annotations[p.ann]).To(Equal(p.newNodeName))
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PVCSelectedNodeChanging) Clean() error {
|
||||
if !p.VeleroCfg.Debug {
|
||||
p.TestCase.Clean()
|
||||
By(fmt.Sprintf("Clean namespace with prefix %s after test", p.mappedNS), func() {
|
||||
CleanupNamespaces(p.Ctx, p.Client, p.mappedNS)
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -19,11 +19,9 @@ package basic
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -40,11 +38,11 @@ type MultiNSBackup struct {
|
||||
}
|
||||
|
||||
func (m *MultiNSBackup) Init() error {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
UUIDgen, _ = uuid.NewRandom()
|
||||
m.BackupName = "backup-" + UUIDgen.String()
|
||||
m.RestoreName = "restore-" + UUIDgen.String()
|
||||
m.NSBaseName = "nstest-" + UUIDgen.String()
|
||||
m.TestCase.Init()
|
||||
m.CaseBaseName = "nstest-" + m.UUIDgen
|
||||
m.BackupName = "backup-" + m.CaseBaseName
|
||||
m.RestoreName = "restore-" + m.CaseBaseName
|
||||
|
||||
m.VeleroCfg = VeleroCfg
|
||||
m.Client = *m.VeleroCfg.ClientToInstallVelero
|
||||
m.NSExcluded = &[]string{}
|
||||
@@ -64,10 +62,7 @@ func (m *MultiNSBackup) Init() error {
|
||||
FailedMSG: "Failed to successfully backup and restore multiple namespaces",
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MultiNSBackup) StartRun() error {
|
||||
// Currently it's hard to build a large list of namespaces to include and wildcards do not work so instead
|
||||
// we will exclude all of the namespaces that existed prior to the test from the backup
|
||||
namespaces, err := m.Client.ClientGo.CoreV1().Namespaces().List(context.Background(), v1.ListOptions{})
|
||||
@@ -93,15 +88,14 @@ func (m *MultiNSBackup) StartRun() error {
|
||||
}
|
||||
|
||||
func (m *MultiNSBackup) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
m.Ctx, m.CtxCancel = context.WithTimeout(context.Background(), m.TimeoutDuration)
|
||||
fmt.Printf("Creating namespaces ...\n")
|
||||
labels := map[string]string{
|
||||
"ns-test": "true",
|
||||
}
|
||||
for nsNum := 0; nsNum < m.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", m.NSBaseName, nsNum)
|
||||
if err := CreateNamespaceWithLabel(ctx, m.Client, createNSName, labels); err != nil {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", m.CaseBaseName, nsNum)
|
||||
if err := CreateNamespaceWithLabel(m.Ctx, m.Client, createNSName, labels); err != nil {
|
||||
return errors.Wrapf(err, "Failed to create namespace %s", createNSName)
|
||||
}
|
||||
}
|
||||
@@ -109,12 +103,10 @@ func (m *MultiNSBackup) CreateResources() error {
|
||||
}
|
||||
|
||||
func (m *MultiNSBackup) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), m.TimeoutDuration)
|
||||
defer ctxCancel()
|
||||
// Verify that we got back all of the namespaces we created
|
||||
for nsNum := 0; nsNum < m.NamespacesTotal; nsNum++ {
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", m.NSBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(ctx, m.Client, checkNSName)
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", m.CaseBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(m.Ctx, m.Client, checkNSName)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not retrieve test namespace %s", checkNSName)
|
||||
} else if checkNS.Name != checkNSName {
|
||||
@@ -125,11 +117,9 @@ func (m *MultiNSBackup) Verify() error {
|
||||
}
|
||||
|
||||
func (m *MultiNSBackup) Destroy() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
err := CleanupNamespaces(ctx, m.Client, m.NSBaseName)
|
||||
err := CleanupNamespaces(m.Ctx, m.Client, m.CaseBaseName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Could cleanup retrieve namespaces")
|
||||
}
|
||||
return WaitAllSelectedNSDeleted(ctx, m.Client, "ns-test=true")
|
||||
return WaitAllSelectedNSDeleted(m.Ctx, m.Client, "ns-test=true")
|
||||
}
|
||||
|
||||
@@ -19,11 +19,9 @@ package basic
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
. "github.com/vmware-tanzu/velero/test/e2e"
|
||||
@@ -36,17 +34,17 @@ type NSAnnotationCase struct {
|
||||
}
|
||||
|
||||
func (n *NSAnnotationCase) Init() error {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
UUIDgen, _ = uuid.NewRandom()
|
||||
n.BackupName = "backup-namespace-annotations" + UUIDgen.String()
|
||||
n.RestoreName = "restore-namespace-annotations" + UUIDgen.String()
|
||||
n.NSBaseName = "namespace-annotations-" + UUIDgen.String()
|
||||
n.TestCase.Init()
|
||||
n.CaseBaseName = "namespace-annotations-" + n.UUIDgen
|
||||
n.BackupName = "backup-" + n.CaseBaseName
|
||||
n.RestoreName = "restore-" + n.CaseBaseName
|
||||
|
||||
n.NamespacesTotal = 1
|
||||
n.NSIncluded = &[]string{}
|
||||
n.VeleroCfg = VeleroCfg
|
||||
n.Client = *n.VeleroCfg.ClientToInstallVelero
|
||||
for nsNum := 0; nsNum < n.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", n.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", n.CaseBaseName, nsNum)
|
||||
*n.NSIncluded = append(*n.NSIncluded, createNSName)
|
||||
}
|
||||
n.TestMsg = &TestMSG{
|
||||
@@ -68,12 +66,11 @@ func (n *NSAnnotationCase) Init() error {
|
||||
}
|
||||
|
||||
func (n *NSAnnotationCase) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
n.Ctx, n.CtxCancel = context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
for nsNum := 0; nsNum < n.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", n.NSBaseName, nsNum)
|
||||
createAnnotationName := fmt.Sprintf("annotation-%s-%00000d", n.NSBaseName, nsNum)
|
||||
if err := CreateNamespaceWithAnnotation(ctx, n.Client, createNSName, map[string]string{"testAnnotation": createAnnotationName}); err != nil {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", n.CaseBaseName, nsNum)
|
||||
createAnnotationName := fmt.Sprintf("annotation-%s-%00000d", n.CaseBaseName, nsNum)
|
||||
if err := CreateNamespaceWithAnnotation(n.Ctx, n.Client, createNSName, map[string]string{"testAnnotation": createAnnotationName}); err != nil {
|
||||
return errors.Wrapf(err, "Failed to create namespace %s", createNSName)
|
||||
}
|
||||
}
|
||||
@@ -81,12 +78,10 @@ func (n *NSAnnotationCase) CreateResources() error {
|
||||
}
|
||||
|
||||
func (n *NSAnnotationCase) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer ctxCancel()
|
||||
for nsNum := 0; nsNum < n.NamespacesTotal; nsNum++ {
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", n.NSBaseName, nsNum)
|
||||
checkAnnoName := fmt.Sprintf("annotation-%s-%00000d", n.NSBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(ctx, n.Client, checkNSName)
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", n.CaseBaseName, nsNum)
|
||||
checkAnnoName := fmt.Sprintf("annotation-%s-%00000d", n.CaseBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(n.Ctx, n.Client, checkNSName)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not retrieve test namespace %s", checkNSName)
|
||||
|
||||
@@ -35,11 +35,9 @@ package basic
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
. "github.com/vmware-tanzu/velero/test/e2e"
|
||||
@@ -52,15 +50,14 @@ type RBACCase struct {
|
||||
}
|
||||
|
||||
func (r *RBACCase) Init() error {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
UUIDgen, _ = uuid.NewRandom()
|
||||
r.BackupName = "backup-rbac" + UUIDgen.String()
|
||||
r.RestoreName = "restore-rbac" + UUIDgen.String()
|
||||
r.NSBaseName = "rabc-" + UUIDgen.String()
|
||||
r.TestCase.Init()
|
||||
r.CaseBaseName = "rabc-" + r.UUIDgen
|
||||
r.BackupName = "backup-" + r.CaseBaseName
|
||||
r.RestoreName = "restore-" + r.CaseBaseName
|
||||
r.NamespacesTotal = 1
|
||||
r.NSIncluded = &[]string{}
|
||||
for nsNum := 0; nsNum < r.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", r.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", r.CaseBaseName, nsNum)
|
||||
*r.NSIncluded = append(*r.NSIncluded, createNSName)
|
||||
}
|
||||
r.TestMsg = &TestMSG{
|
||||
@@ -84,22 +81,21 @@ func (r *RBACCase) Init() error {
|
||||
}
|
||||
|
||||
func (r *RBACCase) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
r.Ctx, r.CtxCancel = context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
for nsNum := 0; nsNum < r.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", r.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", r.CaseBaseName, nsNum)
|
||||
fmt.Printf("Creating namespaces ...%s\n", createNSName)
|
||||
if err := CreateNamespace(ctx, r.Client, createNSName); err != nil {
|
||||
if err := CreateNamespace(r.Ctx, r.Client, createNSName); err != nil {
|
||||
return errors.Wrapf(err, "Failed to create namespace %s", createNSName)
|
||||
}
|
||||
serviceAccountName := fmt.Sprintf("service-account-%s-%00000d", r.NSBaseName, nsNum)
|
||||
serviceAccountName := fmt.Sprintf("service-account-%s-%00000d", r.CaseBaseName, nsNum)
|
||||
fmt.Printf("Creating service account ...%s\n", createNSName)
|
||||
if err := CreateServiceAccount(ctx, r.Client, createNSName, serviceAccountName); err != nil {
|
||||
if err := CreateServiceAccount(r.Ctx, r.Client, createNSName, serviceAccountName); err != nil {
|
||||
return errors.Wrapf(err, "Failed to create service account %s", serviceAccountName)
|
||||
}
|
||||
clusterRoleName := fmt.Sprintf("clusterrole-%s-%00000d", r.NSBaseName, nsNum)
|
||||
clusterRoleBindingName := fmt.Sprintf("clusterrolebinding-%s-%00000d", r.NSBaseName, nsNum)
|
||||
if err := CreateRBACWithBindingSA(ctx, r.Client, createNSName, serviceAccountName, clusterRoleName, clusterRoleBindingName); err != nil {
|
||||
clusterRoleName := fmt.Sprintf("clusterrole-%s-%00000d", r.CaseBaseName, nsNum)
|
||||
clusterRoleBindingName := fmt.Sprintf("clusterrolebinding-%s-%00000d", r.CaseBaseName, nsNum)
|
||||
if err := CreateRBACWithBindingSA(r.Ctx, r.Client, createNSName, serviceAccountName, clusterRoleName, clusterRoleBindingName); err != nil {
|
||||
return errors.Wrapf(err, "Failed to create cluster role %s with role binding %s", clusterRoleName, clusterRoleBindingName)
|
||||
}
|
||||
}
|
||||
@@ -107,14 +103,12 @@ func (r *RBACCase) CreateResources() error {
|
||||
}
|
||||
|
||||
func (r *RBACCase) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
for nsNum := 0; nsNum < r.NamespacesTotal; nsNum++ {
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", r.NSBaseName, nsNum)
|
||||
checkServiceAccountName := fmt.Sprintf("service-account-%s-%00000d", r.NSBaseName, nsNum)
|
||||
checkClusterRoleName := fmt.Sprintf("clusterrole-%s-%00000d", r.NSBaseName, nsNum)
|
||||
checkClusterRoleBindingName := fmt.Sprintf("clusterrolebinding-%s-%00000d", r.NSBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(ctx, r.Client, checkNSName)
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", r.CaseBaseName, nsNum)
|
||||
checkServiceAccountName := fmt.Sprintf("service-account-%s-%00000d", r.CaseBaseName, nsNum)
|
||||
checkClusterRoleName := fmt.Sprintf("clusterrole-%s-%00000d", r.CaseBaseName, nsNum)
|
||||
checkClusterRoleBindingName := fmt.Sprintf("clusterrolebinding-%s-%00000d", r.CaseBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(r.Ctx, r.Client, checkNSName)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not retrieve test namespace %s", checkNSName)
|
||||
}
|
||||
@@ -123,7 +117,7 @@ func (r *RBACCase) Verify() error {
|
||||
}
|
||||
|
||||
//getting service account from the restore
|
||||
checkSA, err := GetServiceAccount(ctx, r.Client, checkNSName, checkServiceAccountName)
|
||||
checkSA, err := GetServiceAccount(r.Ctx, r.Client, checkNSName, checkServiceAccountName)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not retrieve test service account %s", checkSA)
|
||||
@@ -134,7 +128,7 @@ func (r *RBACCase) Verify() error {
|
||||
}
|
||||
|
||||
//getting cluster role from the restore
|
||||
checkClusterRole, err := GetClusterRole(ctx, r.Client, checkClusterRoleName)
|
||||
checkClusterRole, err := GetClusterRole(r.Ctx, r.Client, checkClusterRoleName)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not retrieve test cluster role %s", checkClusterRole)
|
||||
@@ -145,7 +139,7 @@ func (r *RBACCase) Verify() error {
|
||||
}
|
||||
|
||||
//getting cluster role binding from the restore
|
||||
checkClusterRoleBinding, err := GetClusterRoleBinding(ctx, r.Client, checkClusterRoleBindingName)
|
||||
checkClusterRoleBinding, err := GetClusterRoleBinding(r.Ctx, r.Client, checkClusterRoleBindingName)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not retrieve test cluster role binding %s", checkClusterRoleBinding)
|
||||
@@ -166,21 +160,19 @@ func (r *RBACCase) Verify() error {
|
||||
}
|
||||
|
||||
func (r *RBACCase) Destroy() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
//cleanup clusterrole
|
||||
err := CleanupClusterRole(ctx, r.Client, r.NSBaseName)
|
||||
err := CleanupClusterRole(r.Ctx, r.Client, r.CaseBaseName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Could not cleanup clusterroles")
|
||||
}
|
||||
|
||||
//cleanup cluster rolebinding
|
||||
err = CleanupClusterRoleBinding(ctx, r.Client, r.NSBaseName)
|
||||
err = CleanupClusterRoleBinding(r.Ctx, r.Client, r.CaseBaseName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Could not cleanup clusterrolebindings")
|
||||
}
|
||||
|
||||
err = CleanupNamespacesWithPoll(ctx, r.Client, r.NSBaseName)
|
||||
err = CleanupNamespacesWithPoll(r.Ctx, r.Client, r.CaseBaseName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Could cleanup retrieve namespaces")
|
||||
}
|
||||
@@ -189,5 +181,8 @@ func (r *RBACCase) Destroy() error {
|
||||
}
|
||||
|
||||
func (r *RBACCase) Clean() error {
|
||||
return r.Destroy()
|
||||
if !r.VeleroCfg.Debug {
|
||||
return r.Destroy()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -33,15 +33,14 @@ limitations under the License.
|
||||
package basic
|
||||
|
||||
import (
|
||||
. "github.com/vmware-tanzu/velero/test/e2e"
|
||||
. "github.com/vmware-tanzu/velero/test/e2e/test"
|
||||
)
|
||||
|
||||
func GetResourcesCheckTestCases() []VeleroBackupRestoreTest {
|
||||
return []VeleroBackupRestoreTest{
|
||||
&NSAnnotationCase{TestCase{VeleroCfg: VeleroCfg}},
|
||||
&MultiNSBackup{IsScalTest: false, TestCase: TestCase{VeleroCfg: VeleroCfg}},
|
||||
&RBACCase{TestCase{VeleroCfg: VeleroCfg}},
|
||||
&NSAnnotationCase{},
|
||||
&MultiNSBackup{IsScalTest: false},
|
||||
&RBACCase{},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,15 +31,17 @@ type StorageClasssChanging struct {
|
||||
|
||||
const SCCBaseName string = "scc-"
|
||||
|
||||
var StorageClasssChangingTest func() = TestFunc(&StorageClasssChanging{
|
||||
namespace: SCCBaseName + "1", TestCase: TestCase{NSBaseName: SCCBaseName}})
|
||||
var StorageClasssChangingTest func() = TestFunc(&StorageClasssChanging{})
|
||||
|
||||
func (s *StorageClasssChanging) Init() error {
|
||||
s.TestCase.Init()
|
||||
s.CaseBaseName = SCCBaseName + s.UUIDgen
|
||||
s.namespace = s.CaseBaseName
|
||||
s.BackupName = "backup-" + s.CaseBaseName
|
||||
s.RestoreName = "restore-" + s.CaseBaseName
|
||||
s.mappedNS = s.namespace + "-mapped"
|
||||
s.VeleroCfg = VeleroCfg
|
||||
s.Client = *s.VeleroCfg.ClientToInstallVelero
|
||||
s.NSBaseName = SCCBaseName
|
||||
s.namespace = s.NSBaseName + UUIDgen.String()
|
||||
s.mappedNS = s.namespace + "-mapped"
|
||||
s.TestMsg = &TestMSG{
|
||||
Desc: "Changing PV/PVC Storage Classes",
|
||||
FailedMSG: "Failed to changing PV/PVC Storage Classes",
|
||||
@@ -56,10 +58,7 @@ func (s *StorageClasssChanging) Init() error {
|
||||
s.configmaptName = "change-storage-class-config"
|
||||
s.volume = "volume-1"
|
||||
s.podName = "pod-1"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StorageClasssChanging) StartRun() error {
|
||||
s.BackupName = s.BackupName + "backup-" + UUIDgen.String()
|
||||
s.RestoreName = s.RestoreName + "restore-" + UUIDgen.String()
|
||||
s.BackupArgs = []string{
|
||||
@@ -74,14 +73,13 @@ func (s *StorageClasssChanging) StartRun() error {
|
||||
return nil
|
||||
}
|
||||
func (s *StorageClasssChanging) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
s.Ctx, s.CtxCancel = context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
By(fmt.Sprintf("Create a storage class %s", s.desStorageClass), func() {
|
||||
Expect(InstallStorageClass(context.Background(), fmt.Sprintf("testdata/storage-class/%s.yaml",
|
||||
Expect(InstallStorageClass(s.Ctx, fmt.Sprintf("testdata/storage-class/%s.yaml",
|
||||
s.VeleroCfg.CloudProvider))).To(Succeed())
|
||||
})
|
||||
By(fmt.Sprintf("Create namespace %s", s.namespace), func() {
|
||||
Expect(CreateNamespace(ctx, s.Client, s.namespace)).To(Succeed(),
|
||||
Expect(CreateNamespace(s.Ctx, s.Client, s.namespace)).To(Succeed(),
|
||||
fmt.Sprintf("Failed to create namespace %s", s.namespace))
|
||||
})
|
||||
|
||||
@@ -97,30 +95,26 @@ func (s *StorageClasssChanging) CreateResources() error {
|
||||
}
|
||||
|
||||
func (s *StorageClasssChanging) Destroy() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
By(fmt.Sprintf("Expect storage class of PV %s to be %s ", s.volume, s.srcStorageClass), func() {
|
||||
pvName, err := GetPVByPodName(s.Client, s.namespace, s.volume)
|
||||
Expect(err).To(Succeed(), fmt.Sprintf("Failed to get PV name by pod name %s", s.podName))
|
||||
pv, err := GetPersistentVolume(ctx, s.Client, s.namespace, pvName)
|
||||
pv, err := GetPersistentVolume(s.Ctx, s.Client, s.namespace, pvName)
|
||||
Expect(err).To(Succeed(), fmt.Sprintf("Failed to get PV by pod name %s", s.podName))
|
||||
fmt.Println(pv)
|
||||
Expect(pv.Spec.StorageClassName).To(Equal(s.srcStorageClass),
|
||||
fmt.Sprintf("PV storage %s is not as expected %s", pv.Spec.StorageClassName, s.srcStorageClass))
|
||||
})
|
||||
|
||||
By(fmt.Sprintf("Start to destroy namespace %s......", s.NSBaseName), func() {
|
||||
Expect(CleanupNamespacesWithPoll(ctx, s.Client, s.NSBaseName)).To(Succeed(),
|
||||
fmt.Sprintf("Failed to delete namespace %s", s.NSBaseName))
|
||||
By(fmt.Sprintf("Start to destroy namespace %s......", s.CaseBaseName), func() {
|
||||
Expect(CleanupNamespacesWithPoll(s.Ctx, s.Client, s.CaseBaseName)).To(Succeed(),
|
||||
fmt.Sprintf("Failed to delete namespace %s", s.CaseBaseName))
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StorageClasssChanging) Restore() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
By(fmt.Sprintf("Start to restore %s .....", s.RestoreName), func() {
|
||||
Expect(VeleroRestoreExec(ctx, s.VeleroCfg.VeleroCLI,
|
||||
Expect(VeleroRestoreExec(s.Ctx, s.VeleroCfg.VeleroCLI,
|
||||
s.VeleroCfg.VeleroNamespace, s.RestoreName,
|
||||
s.RestoreArgs, velerov1api.RestorePhaseCompleted)).To(
|
||||
Succeed(),
|
||||
@@ -133,13 +127,11 @@ func (s *StorageClasssChanging) Restore() error {
|
||||
return nil
|
||||
}
|
||||
func (s *StorageClasssChanging) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
By(fmt.Sprintf("Expect storage class of PV %s to be %s ", s.volume, s.desStorageClass), func() {
|
||||
time.Sleep(1 * time.Minute)
|
||||
Expect(WaitForPods(s.Ctx, s.Client, s.mappedNS, []string{s.podName})).To(Succeed(), fmt.Sprintf("Failed to wait pod ready %s", s.podName))
|
||||
pvName, err := GetPVByPodName(s.Client, s.mappedNS, s.volume)
|
||||
Expect(err).To(Succeed(), fmt.Sprintf("Failed to get PV name by pod name %s", s.podName))
|
||||
pv, err := GetPersistentVolume(ctx, s.Client, s.mappedNS, pvName)
|
||||
pv, err := GetPersistentVolume(s.Ctx, s.Client, s.mappedNS, pvName)
|
||||
Expect(err).To(Succeed(), fmt.Sprintf("Failed to get PV by pod name %s", s.podName))
|
||||
fmt.Println(pv)
|
||||
Expect(pv.Spec.StorageClassName).To(Equal(s.desStorageClass),
|
||||
@@ -147,3 +139,12 @@ func (s *StorageClasssChanging) Verify() error {
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StorageClasssChanging) Clean() error {
|
||||
if !s.VeleroCfg.Debug {
|
||||
DeleteConfigmap(s.Client.ClientGo, s.VeleroCfg.VeleroNamespace, s.configmaptName)
|
||||
DeleteStorageClass(s.Ctx, s.Client, s.desStorageClass)
|
||||
s.TestCase.Clean()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ func init() {
|
||||
|
||||
}
|
||||
|
||||
var _ = Describe("[APIGroup][Common] Velero tests with various CRD API group versions", APIGropuVersionsTest)
|
||||
var _ = Describe("[APIGroup][APIVersion] Velero tests with various CRD API group versions", APIGropuVersionsTest)
|
||||
var _ = Describe("[APIGroup][APIExtensions] CRD of apiextentions v1beta1 should be B/R successfully from cluster(k8s version < 1.22) to cluster(k8s version >= 1.22)", APIExtensionsVersionsTest)
|
||||
|
||||
// Test backup and restore of Kibishi using restic
|
||||
|
||||
@@ -208,7 +208,7 @@ func MigrationTest(useVolumeSnapshots bool, veleroCLI2Version VeleroCLI2Version)
|
||||
snapshotCheckPoint.NamespaceBackedUp = migrationNamespace
|
||||
By("Snapshot should be created in cloud object store", func() {
|
||||
snapshotCheckPoint, err := GetSnapshotCheckPoint(*veleroCfg.DefaultClient, veleroCfg, 2,
|
||||
migrationNamespace, backupName, KibishiiPodNameList)
|
||||
migrationNamespace, backupName, KibishiiPVCNameList)
|
||||
Expect(err).NotTo(HaveOccurred(), "Fail to get snapshot checkpoint")
|
||||
Expect(SnapshotsShouldBeCreatedInCloud(veleroCfg.CloudProvider,
|
||||
veleroCfg.CloudCredentialsFile, veleroCfg.BSLBucket,
|
||||
@@ -226,7 +226,7 @@ func MigrationTest(useVolumeSnapshots bool, veleroCLI2Version VeleroCLI2Version)
|
||||
// the snapshots of AWS may be still in pending status when do the restore, wait for a while
|
||||
// to avoid this https://github.com/vmware-tanzu/velero/issues/1799
|
||||
// TODO remove this after https://github.com/vmware-tanzu/velero/issues/3533 is fixed
|
||||
if (veleroCfg.CloudProvider == "aws" || veleroCfg.CloudProvider == "vsphere") && useVolumeSnapshots {
|
||||
if veleroCfg.CloudProvider == "aws" && useVolumeSnapshots {
|
||||
fmt.Println("Waiting 5 minutes to make sure the snapshots are ready...")
|
||||
time.Sleep(5 * time.Minute)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
clientset "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
|
||||
)
|
||||
|
||||
@@ -154,6 +155,7 @@ func (f *factory) KubebuilderClient() (kbclient.Client, error) {
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
velerov1api.AddToScheme(scheme)
|
||||
velerov2alpha1api.AddToScheme(scheme)
|
||||
k8scheme.AddToScheme(scheme)
|
||||
apiextv1beta1.AddToScheme(scheme)
|
||||
apiextv1.AddToScheme(scheme)
|
||||
|
||||
@@ -31,30 +31,22 @@ var OptInPVBackupTest func() = TestFunc(&PVBackupFiltering{annotation: OPT_IN_AN
|
||||
var OptOutPVBackupTest func() = TestFunc(&PVBackupFiltering{annotation: OPT_OUT_ANN, id: "opt-out"})
|
||||
|
||||
func (p *PVBackupFiltering) Init() error {
|
||||
p.TestCase.Init()
|
||||
p.CaseBaseName = "pv-filter-" + p.UUIDgen
|
||||
p.BackupName = "backup-" + p.CaseBaseName + p.id
|
||||
p.RestoreName = "restore-" + p.CaseBaseName + p.id
|
||||
p.VeleroCfg = VeleroCfg
|
||||
p.Client = *p.VeleroCfg.ClientToInstallVelero
|
||||
p.VeleroCfg.UseVolumeSnapshots = false
|
||||
p.VeleroCfg.UseNodeAgent = true
|
||||
p.NSBaseName = "ns"
|
||||
p.NSIncluded = &[]string{fmt.Sprintf("%s-%s-%d", p.NSBaseName, p.id, 1), fmt.Sprintf("%s-%s-%d", p.NSBaseName, p.id, 2)}
|
||||
p.NSIncluded = &[]string{fmt.Sprintf("%s-%s-%d", p.CaseBaseName, p.id, 1), fmt.Sprintf("%s-%s-%d", p.CaseBaseName, p.id, 2)}
|
||||
|
||||
p.TestMsg = &TestMSG{
|
||||
Desc: "Backup PVs filtering by opt-in/opt-out annotation",
|
||||
FailedMSG: "Failed to PVs filtering by opt-in/opt-out annotation",
|
||||
Text: fmt.Sprintf("Should backup PVs in namespace %s according to annotation %s", *p.NSIncluded, p.annotation),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PVBackupFiltering) StartRun() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
err := InstallStorageClass(ctx, fmt.Sprintf("testdata/storage-class/%s.yaml", VeleroCfg.CloudProvider))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.BackupName = p.BackupName + "backup-" + p.id + "-" + UUIDgen.String()
|
||||
p.RestoreName = p.RestoreName + "restore-" + p.id + "-" + UUIDgen.String()
|
||||
p.BackupArgs = []string{
|
||||
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", p.BackupName,
|
||||
"--include-namespaces", strings.Join(*p.NSIncluded, ","),
|
||||
@@ -72,12 +64,17 @@ func (p *PVBackupFiltering) StartRun() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PVBackupFiltering) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
p.Ctx, p.CtxCancel = context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
err := InstallStorageClass(p.Ctx, fmt.Sprintf("testdata/storage-class/%s.yaml", VeleroCfg.CloudProvider))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to install storage class for pv backup filtering test")
|
||||
}
|
||||
|
||||
for _, ns := range *p.NSIncluded {
|
||||
By(fmt.Sprintf("Create namespaces %s for workload\n", ns), func() {
|
||||
Expect(CreateNamespace(ctx, p.Client, ns)).To(Succeed(), fmt.Sprintf("Failed to create namespace %s", ns))
|
||||
Expect(CreateNamespace(p.Ctx, p.Client, ns)).To(Succeed(), fmt.Sprintf("Failed to create namespace %s", ns))
|
||||
})
|
||||
var pods []string
|
||||
By(fmt.Sprintf("Deploy a few pods with several PVs in namespace %s", ns), func() {
|
||||
@@ -105,7 +102,7 @@ func (p *PVBackupFiltering) CreateResources() error {
|
||||
p.annotation: volumesToAnnotation,
|
||||
}
|
||||
By(fmt.Sprintf("Add annotation to pod %s of namespace %s", pod.Name, ns), func() {
|
||||
_, err := AddAnnotationToPod(ctx, p.Client, ns, pod.Name, ann)
|
||||
_, err := AddAnnotationToPod(p.Ctx, p.Client, ns, pod.Name, ann)
|
||||
Expect(err).To(Succeed())
|
||||
})
|
||||
})
|
||||
@@ -116,17 +113,17 @@ func (p *PVBackupFiltering) CreateResources() error {
|
||||
By(fmt.Sprintf("Waiting for all pods to start %s\n", p.podsList), func() {
|
||||
for index, ns := range *p.NSIncluded {
|
||||
By(fmt.Sprintf("Waiting for all pods to start %d in namespace %s", index, ns), func() {
|
||||
WaitForPods(ctx, p.Client, ns, p.podsList[index])
|
||||
Expect(WaitForPods(p.Ctx, p.Client, ns, p.podsList[index])).To(Succeed())
|
||||
})
|
||||
}
|
||||
})
|
||||
By(fmt.Sprintf("Populate all pods %s with file %s", p.podsList, FILE_NAME), func() {
|
||||
for index, ns := range *p.NSIncluded {
|
||||
By(fmt.Sprintf("Creating file in all pods to start %d in namespace %s", index, ns), func() {
|
||||
WaitForPods(ctx, p.Client, ns, p.podsList[index])
|
||||
Expect(WaitForPods(p.Ctx, p.Client, ns, p.podsList[index])).To(Succeed())
|
||||
for i, pod := range p.podsList[index] {
|
||||
for j := range p.volumesList[i] {
|
||||
Expect(CreateFileToPod(ctx, ns, pod, pod, p.volumesList[i][j],
|
||||
Expect(CreateFileToPod(p.Ctx, ns, pod, pod, p.volumesList[i][j],
|
||||
FILE_NAME, fileContent(ns, pod, p.volumesList[i][j]))).To(Succeed())
|
||||
}
|
||||
}
|
||||
@@ -137,12 +134,10 @@ func (p *PVBackupFiltering) CreateResources() error {
|
||||
}
|
||||
|
||||
func (p *PVBackupFiltering) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), time.Minute*60)
|
||||
defer ctxCancel()
|
||||
By(fmt.Sprintf("Waiting for all pods to start %s", p.podsList), func() {
|
||||
for index, ns := range *p.NSIncluded {
|
||||
By(fmt.Sprintf("Waiting for all pods to start %d in namespace %s", index, ns), func() {
|
||||
WaitForPods(ctx, p.Client, ns, p.podsList[index])
|
||||
WaitForPods(p.Ctx, p.Client, ns, p.podsList[index])
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -155,21 +150,21 @@ func (p *PVBackupFiltering) Verify() error {
|
||||
if j%2 == 0 {
|
||||
if p.annotation == OPT_IN_ANN {
|
||||
By(fmt.Sprintf("File should exists in PV %s of pod %s under namespace %s\n", p.volumesList[i][j], p.podsList[k][i], ns), func() {
|
||||
Expect(fileExist(ctx, ns, p.podsList[k][i], p.volumesList[i][j])).To(Succeed(), "File not exist as expect")
|
||||
Expect(fileExist(p.Ctx, ns, p.podsList[k][i], p.volumesList[i][j])).To(Succeed(), "File not exist as expect")
|
||||
})
|
||||
} else {
|
||||
By(fmt.Sprintf("File should not exist in PV %s of pod %s under namespace %s\n", p.volumesList[i][j], p.podsList[k][i], ns), func() {
|
||||
Expect(fileNotExist(ctx, ns, p.podsList[k][i], p.volumesList[i][j])).To(Succeed(), "File exists, not as expect")
|
||||
Expect(fileNotExist(p.Ctx, ns, p.podsList[k][i], p.volumesList[i][j])).To(Succeed(), "File exists, not as expect")
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if p.annotation == OPT_OUT_ANN {
|
||||
By(fmt.Sprintf("File should exists in PV %s of pod %s under namespace %s\n", p.volumesList[i][j], p.podsList[k][i], ns), func() {
|
||||
Expect(fileExist(ctx, ns, p.podsList[k][i], p.volumesList[i][j])).To(Succeed(), "File not exist as expect")
|
||||
Expect(fileExist(p.Ctx, ns, p.podsList[k][i], p.volumesList[i][j])).To(Succeed(), "File not exist as expect")
|
||||
})
|
||||
} else {
|
||||
By(fmt.Sprintf("File should not exist in PV %s of pod %s under namespace %s\n", p.volumesList[i][j], p.podsList[k][i], ns), func() {
|
||||
Expect(fileNotExist(ctx, ns, p.podsList[k][i], p.volumesList[i][j])).To(Succeed(), "File exists, not as expect")
|
||||
Expect(fileNotExist(p.Ctx, ns, p.podsList[k][i], p.volumesList[i][j])).To(Succeed(), "File exists, not as expect")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,8 @@ package filtering
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -43,8 +41,8 @@ var testInBackup = FilteringCase{IsTestInBackup: true}
|
||||
var testInRestore = FilteringCase{IsTestInBackup: false}
|
||||
|
||||
func (f *FilteringCase) Init() error {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
UUIDgen, _ = uuid.NewRandom()
|
||||
f.TestCase.Init()
|
||||
|
||||
f.replica = int32(2)
|
||||
f.labels = map[string]string{"resourcefiltering": "true"}
|
||||
f.labelSelector = "resourcefiltering"
|
||||
@@ -66,26 +64,16 @@ func (f *FilteringCase) Init() error {
|
||||
}
|
||||
|
||||
func (f *FilteringCase) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
f.Ctx, f.CtxCancel = context.WithTimeout(context.Background(), 30*time.Minute)
|
||||
for nsNum := 0; nsNum < f.NamespacesTotal; nsNum++ {
|
||||
namespace := fmt.Sprintf("%s-%00000d", f.NSBaseName, nsNum)
|
||||
namespace := fmt.Sprintf("%s-%00000d", f.CaseBaseName, nsNum)
|
||||
fmt.Printf("Creating resources in namespace ...%s\n", namespace)
|
||||
if err := CreateNamespace(ctx, f.Client, namespace); err != nil {
|
||||
if err := CreateNamespace(f.Ctx, f.Client, namespace); err != nil {
|
||||
return errors.Wrapf(err, "Failed to create namespace %s", namespace)
|
||||
}
|
||||
serviceAccountName := "default"
|
||||
// wait until the service account is created before patch the image pull secret
|
||||
if err := WaitUntilServiceAccountCreated(ctx, f.Client, namespace, serviceAccountName, 10*time.Minute); err != nil {
|
||||
return errors.Wrapf(err, "failed to wait the service account %q created under the namespace %q", serviceAccountName, namespace)
|
||||
}
|
||||
// add the image pull secret to avoid the image pull limit issue of Docker Hub
|
||||
if err := PatchServiceAccountWithImagePullSecret(ctx, f.Client, namespace, serviceAccountName, VeleroCfg.RegistryCredentialFile); err != nil {
|
||||
return errors.Wrapf(err, "failed to patch the service account %q under the namespace %q", serviceAccountName, namespace)
|
||||
}
|
||||
//Create deployment
|
||||
fmt.Printf("Creating deployment in namespaces ...%s\n", namespace)
|
||||
deployment := NewDeployment(f.NSBaseName, namespace, f.replica, f.labels, nil).Result()
|
||||
deployment := NewDeployment(f.CaseBaseName, namespace, f.replica, f.labels, nil).Result()
|
||||
deployment, err := CreateDeployment(f.Client.ClientGo, namespace, deployment)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to delete the namespace %q", namespace))
|
||||
@@ -95,7 +83,7 @@ func (f *FilteringCase) CreateResources() error {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to ensure job completion in namespace: %q", namespace))
|
||||
}
|
||||
//Create Secret
|
||||
secretName := f.NSBaseName
|
||||
secretName := f.CaseBaseName
|
||||
fmt.Printf("Creating secret %s in namespaces ...%s\n", secretName, namespace)
|
||||
_, err = CreateSecret(f.Client.ClientGo, namespace, secretName, f.labels)
|
||||
if err != nil {
|
||||
@@ -106,7 +94,7 @@ func (f *FilteringCase) CreateResources() error {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to ensure secret completion in namespace: %q", namespace))
|
||||
}
|
||||
//Create Configmap
|
||||
configmaptName := f.NSBaseName
|
||||
configmaptName := f.CaseBaseName
|
||||
fmt.Printf("Creating configmap %s in namespaces ...%s\n", configmaptName, namespace)
|
||||
_, err = CreateConfigMap(f.Client.ClientGo, namespace, configmaptName, f.labels, nil)
|
||||
if err != nil {
|
||||
@@ -121,13 +109,11 @@ func (f *FilteringCase) CreateResources() error {
|
||||
}
|
||||
|
||||
func (f *FilteringCase) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
for nsNum := 0; nsNum < f.NamespacesTotal; nsNum++ {
|
||||
namespace := fmt.Sprintf("%s-%00000d", f.NSBaseName, nsNum)
|
||||
namespace := fmt.Sprintf("%s-%00000d", f.CaseBaseName, nsNum)
|
||||
fmt.Printf("Checking resources in namespaces ...%s\n", namespace)
|
||||
//Check namespace
|
||||
checkNS, err := GetNamespace(ctx, f.Client, namespace)
|
||||
checkNS, err := GetNamespace(f.Ctx, f.Client, namespace)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not retrieve test namespace %s", namespace)
|
||||
}
|
||||
@@ -135,7 +121,7 @@ func (f *FilteringCase) Verify() error {
|
||||
return errors.Errorf("Retrieved namespace for %s has name %s instead", namespace, checkNS.Name)
|
||||
}
|
||||
//Check deployment
|
||||
_, err = GetDeployment(f.Client.ClientGo, namespace, f.NSBaseName)
|
||||
_, err = GetDeployment(f.Client.ClientGo, namespace, f.CaseBaseName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to list deployment in namespace: %q", namespace))
|
||||
}
|
||||
|
||||
@@ -45,16 +45,17 @@ var ExcludeFromBackupTest func() = TestFunc(&ExcludeFromBackup{testInBackup})
|
||||
|
||||
func (e *ExcludeFromBackup) Init() error {
|
||||
e.FilteringCase.Init()
|
||||
e.BackupName = "backup-exclude-from-backup-" + UUIDgen.String()
|
||||
e.RestoreName = "restore-" + UUIDgen.String()
|
||||
e.NSBaseName = "exclude-from-backup-" + UUIDgen.String()
|
||||
e.CaseBaseName = "exclude-from-backup-" + e.UUIDgen
|
||||
e.BackupName = "backup-" + e.CaseBaseName
|
||||
e.RestoreName = "restore-" + e.CaseBaseName
|
||||
|
||||
e.TestMsg = &TestMSG{
|
||||
Desc: "Backup with the label velero.io/exclude-from-backup=true are not included test",
|
||||
Text: "Should not backup resources with the label velero.io/exclude-from-backup=true",
|
||||
FailedMSG: "Failed to backup resources with the label velero.io/exclude-from-backup=true",
|
||||
}
|
||||
for nsNum := 0; nsNum < e.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", e.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", e.CaseBaseName, nsNum)
|
||||
*e.NSIncluded = append(*e.NSIncluded, createNSName)
|
||||
}
|
||||
e.labels = map[string]string{
|
||||
@@ -64,7 +65,7 @@ func (e *ExcludeFromBackup) Init() error {
|
||||
|
||||
e.BackupArgs = []string{
|
||||
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", e.BackupName,
|
||||
"--include-namespaces", e.NSBaseName,
|
||||
"--include-namespaces", e.CaseBaseName,
|
||||
"--default-volumes-to-fs-backup", "--wait",
|
||||
}
|
||||
|
||||
@@ -76,9 +77,8 @@ func (e *ExcludeFromBackup) Init() error {
|
||||
}
|
||||
|
||||
func (e *ExcludeFromBackup) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
namespace := e.NSBaseName
|
||||
e.Ctx, e.CtxCancel = context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
namespace := e.CaseBaseName
|
||||
// These 2 labels for resources to be included
|
||||
label1 := map[string]string{
|
||||
"meaningless-label-resource-to-include": "true",
|
||||
@@ -87,21 +87,12 @@ func (e *ExcludeFromBackup) CreateResources() error {
|
||||
"velero.io/exclude-from-backup": "false",
|
||||
}
|
||||
fmt.Printf("Creating resources in namespace ...%s\n", namespace)
|
||||
if err := CreateNamespace(ctx, e.Client, namespace); err != nil {
|
||||
if err := CreateNamespace(e.Ctx, e.Client, namespace); err != nil {
|
||||
return errors.Wrapf(err, "Failed to create namespace %s", namespace)
|
||||
}
|
||||
serviceAccountName := "default"
|
||||
// wait until the service account is created before patch the image pull secret
|
||||
if err := WaitUntilServiceAccountCreated(ctx, e.Client, namespace, serviceAccountName, 10*time.Minute); err != nil {
|
||||
return errors.Wrapf(err, "failed to wait the service account %q created under the namespace %q", serviceAccountName, namespace)
|
||||
}
|
||||
// add the image pull secret to avoid the image pull limit issue of Docker Hub
|
||||
if err := PatchServiceAccountWithImagePullSecret(ctx, e.Client, namespace, serviceAccountName, VeleroCfg.RegistryCredentialFile); err != nil {
|
||||
return errors.Wrapf(err, "failed to patch the service account %q under the namespace %q", serviceAccountName, namespace)
|
||||
}
|
||||
//Create deployment: to be included
|
||||
fmt.Printf("Creating deployment in namespaces ...%s\n", namespace)
|
||||
deployment := NewDeployment(e.NSBaseName, namespace, e.replica, label2, nil).Result()
|
||||
deployment := NewDeployment(e.CaseBaseName, namespace, e.replica, label2, nil).Result()
|
||||
deployment, err := CreateDeployment(e.Client.ClientGo, namespace, deployment)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to delete the namespace %q", namespace))
|
||||
@@ -111,7 +102,7 @@ func (e *ExcludeFromBackup) CreateResources() error {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to ensure job completion in namespace: %q", namespace))
|
||||
}
|
||||
//Create Secret
|
||||
secretName := e.NSBaseName
|
||||
secretName := e.CaseBaseName
|
||||
fmt.Printf("Creating secret %s in namespaces ...%s\n", secretName, namespace)
|
||||
_, err = CreateSecret(e.Client.ClientGo, namespace, secretName, e.labels)
|
||||
if err != nil {
|
||||
@@ -122,11 +113,11 @@ func (e *ExcludeFromBackup) CreateResources() error {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to ensure secret completion in namespace: %q", namespace))
|
||||
}
|
||||
By(fmt.Sprintf("Checking secret %s should exists in namespaces ...%s\n", secretName, namespace), func() {
|
||||
_, err = GetSecret(e.Client.ClientGo, namespace, e.NSBaseName)
|
||||
_, err = GetSecret(e.Client.ClientGo, namespace, e.CaseBaseName)
|
||||
Expect(err).ShouldNot(HaveOccurred(), fmt.Sprintf("failed to list deployment in namespace: %q", namespace))
|
||||
})
|
||||
//Create Configmap: to be included
|
||||
configmaptName := e.NSBaseName
|
||||
configmaptName := e.CaseBaseName
|
||||
fmt.Printf("Creating configmap %s in namespaces ...%s\n", configmaptName, namespace)
|
||||
_, err = CreateConfigMap(e.Client.ClientGo, namespace, configmaptName, label1, nil)
|
||||
if err != nil {
|
||||
@@ -140,26 +131,24 @@ func (e *ExcludeFromBackup) CreateResources() error {
|
||||
}
|
||||
|
||||
func (e *ExcludeFromBackup) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
namespace := e.NSBaseName
|
||||
namespace := e.CaseBaseName
|
||||
By(fmt.Sprintf("Checking resources in namespaces ...%s\n", namespace), func() {
|
||||
//Check namespace
|
||||
checkNS, err := GetNamespace(ctx, e.Client, namespace)
|
||||
checkNS, err := GetNamespace(e.Ctx, e.Client, namespace)
|
||||
Expect(err).ShouldNot(HaveOccurred(), fmt.Sprintf("Could not retrieve test namespace %s", namespace))
|
||||
Expect(checkNS.Name == namespace).To(Equal(true), fmt.Sprintf("Retrieved namespace for %s has name %s instead", namespace, checkNS.Name))
|
||||
|
||||
//Check deployment: should be included
|
||||
_, err = GetDeployment(e.Client.ClientGo, namespace, e.NSBaseName)
|
||||
_, err = GetDeployment(e.Client.ClientGo, namespace, e.CaseBaseName)
|
||||
Expect(err).ShouldNot(HaveOccurred(), fmt.Sprintf("failed to list deployment in namespace: %q", namespace))
|
||||
|
||||
//Check secrets: secrets should not be included
|
||||
_, err = GetSecret(e.Client.ClientGo, namespace, e.NSBaseName)
|
||||
_, err = GetSecret(e.Client.ClientGo, namespace, e.CaseBaseName)
|
||||
Expect(err).Should(HaveOccurred(), fmt.Sprintf("failed to list deployment in namespace: %q", namespace))
|
||||
Expect(apierrors.IsNotFound(err)).To(Equal(true))
|
||||
|
||||
//Check configmap: should be included
|
||||
_, err = GetConfigmap(e.Client.ClientGo, namespace, e.NSBaseName)
|
||||
_, err = GetConfigmap(e.Client.ClientGo, namespace, e.CaseBaseName)
|
||||
Expect(err).ShouldNot(HaveOccurred(), fmt.Sprintf("failed to list configmap in namespace: %q", namespace))
|
||||
})
|
||||
return nil
|
||||
|
||||
@@ -50,19 +50,20 @@ var RestoreWithExcludeNamespaces func() = TestFunc(&ExcludeNamespaces{FilteringC
|
||||
|
||||
func (e *ExcludeNamespaces) Init() error {
|
||||
e.FilteringCase.Init()
|
||||
e.CaseBaseName = "exclude-namespaces-" + e.UUIDgen
|
||||
e.namespacesExcluded = e.NamespacesTotal / 2
|
||||
e.NSBaseName = "exclude-namespaces-" + UUIDgen.String()
|
||||
|
||||
if e.IsTestInBackup {
|
||||
e.BackupName = "backup-exclude-namespaces-" + UUIDgen.String()
|
||||
e.RestoreName = "restore-" + UUIDgen.String()
|
||||
e.BackupName = "backup-" + e.CaseBaseName
|
||||
e.RestoreName = "restore-" + e.UUIDgen
|
||||
e.TestMsg = &TestMSG{
|
||||
Desc: "Backup resources with exclude namespace test",
|
||||
FailedMSG: "Failed to backup and restore with namespace include",
|
||||
Text: fmt.Sprintf("should not backup %d namespaces of %d", e.namespacesExcluded, e.NamespacesTotal),
|
||||
}
|
||||
} else {
|
||||
e.BackupName = "backup-" + UUIDgen.String()
|
||||
e.RestoreName = "restore-exclude-namespaces-" + UUIDgen.String()
|
||||
e.BackupName = "backup-" + e.UUIDgen
|
||||
e.RestoreName = "restore-" + e.CaseBaseName
|
||||
e.TestMsg = &TestMSG{
|
||||
Desc: "Restore resources with exclude namespace test",
|
||||
FailedMSG: "Failed to restore with namespace exclude",
|
||||
@@ -71,7 +72,7 @@ func (e *ExcludeNamespaces) Init() error {
|
||||
}
|
||||
e.nsExcluded = &[]string{}
|
||||
for nsNum := 0; nsNum < e.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", e.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", e.CaseBaseName, nsNum)
|
||||
if nsNum < e.namespacesExcluded {
|
||||
*e.nsExcluded = append(*e.nsExcluded, createNSName)
|
||||
} else {
|
||||
@@ -109,12 +110,11 @@ func (e *ExcludeNamespaces) Init() error {
|
||||
}
|
||||
|
||||
func (e *ExcludeNamespaces) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
e.Ctx, e.CtxCancel = context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
for nsNum := 0; nsNum < e.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", e.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", e.CaseBaseName, nsNum)
|
||||
fmt.Printf("Creating namespaces ...%s\n", createNSName)
|
||||
if err := CreateNamespace(ctx, e.Client, createNSName); err != nil {
|
||||
if err := CreateNamespace(e.Ctx, e.Client, createNSName); err != nil {
|
||||
return errors.Wrapf(err, "Failed to create namespace %s", createNSName)
|
||||
}
|
||||
}
|
||||
@@ -122,12 +122,10 @@ func (e *ExcludeNamespaces) CreateResources() error {
|
||||
}
|
||||
|
||||
func (e *ExcludeNamespaces) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
// Verify that we got back all of the namespaces we created
|
||||
for nsNum := 0; nsNum < e.namespacesExcluded; nsNum++ {
|
||||
excludeNSName := fmt.Sprintf("%s-%00000d", e.NSBaseName, nsNum)
|
||||
_, err := GetNamespace(ctx, e.Client, excludeNSName)
|
||||
excludeNSName := fmt.Sprintf("%s-%00000d", e.CaseBaseName, nsNum)
|
||||
_, err := GetNamespace(e.Ctx, e.Client, excludeNSName)
|
||||
if err == nil {
|
||||
return errors.Wrapf(err, "Resource filtering with exclude namespace but exclude namespace %s exist", excludeNSName)
|
||||
}
|
||||
@@ -138,8 +136,8 @@ func (e *ExcludeNamespaces) Verify() error {
|
||||
}
|
||||
|
||||
for nsNum := e.namespacesExcluded; nsNum < e.NamespacesTotal; nsNum++ {
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", e.NSBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(ctx, e.Client, checkNSName)
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", e.CaseBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(e.Ctx, e.Client, checkNSName)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not retrieve test namespace %s", checkNSName)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
package filtering
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -49,9 +48,9 @@ var RestoreWithExcludeResources func() = TestFunc(&ExcludeResources{testInRestor
|
||||
|
||||
func (e *ExcludeResources) Init() error {
|
||||
e.FilteringCase.Init()
|
||||
e.NSBaseName = "exclude-resources-" + UUIDgen.String()
|
||||
e.CaseBaseName = "exclude-resources-" + e.UUIDgen
|
||||
for nsNum := 0; nsNum < e.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", e.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", e.CaseBaseName, nsNum)
|
||||
*e.NSIncluded = append(*e.NSIncluded, createNSName)
|
||||
}
|
||||
if e.IsTestInBackup { // testing case backup with exclude-resources option
|
||||
@@ -60,7 +59,7 @@ func (e *ExcludeResources) Init() error {
|
||||
Text: "Should not backup resources which is excluded others should be backup",
|
||||
FailedMSG: "Failed to backup with resource exclude",
|
||||
}
|
||||
e.BackupName = "backup-exclude-resources-" + UUIDgen.String()
|
||||
e.BackupName = "backup-" + e.CaseBaseName
|
||||
e.RestoreName = "restore-" + UUIDgen.String()
|
||||
e.BackupArgs = []string{
|
||||
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", e.BackupName,
|
||||
@@ -74,15 +73,13 @@ func (e *ExcludeResources) Init() error {
|
||||
"--from-backup", e.BackupName, "--wait",
|
||||
}
|
||||
} else { // testing case restore with exclude-resources option
|
||||
e.BackupName = "backup-" + UUIDgen.String()
|
||||
e.RestoreName = "restore-exclude-resources-" + UUIDgen.String()
|
||||
e.BackupName = "backup-" + e.UUIDgen
|
||||
e.RestoreName = "restore-" + e.CaseBaseName
|
||||
e.TestMsg = &TestMSG{
|
||||
Desc: "Restore resources with resources included test",
|
||||
Text: "Should not restore resources which is excluded others should be backup",
|
||||
FailedMSG: "Failed to restore with resource exclude",
|
||||
}
|
||||
e.BackupName = "backup-exclude-resources-" + UUIDgen.String()
|
||||
e.RestoreName = "restore-exclude-resources-" + UUIDgen.String()
|
||||
e.BackupArgs = []string{
|
||||
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", e.BackupName,
|
||||
"--include-namespaces", strings.Join(*e.NSIncluded, ","),
|
||||
@@ -99,15 +96,15 @@ func (e *ExcludeResources) Init() error {
|
||||
|
||||
func (e *ExcludeResources) Verify() error {
|
||||
for nsNum := 0; nsNum < e.NamespacesTotal; nsNum++ {
|
||||
namespace := fmt.Sprintf("%s-%00000d", e.NSBaseName, nsNum)
|
||||
namespace := fmt.Sprintf("%s-%00000d", e.CaseBaseName, nsNum)
|
||||
fmt.Printf("Checking resources in namespaces ...%s\n", namespace)
|
||||
//Check deployment
|
||||
_, err := GetDeployment(e.Client.ClientGo, namespace, e.NSBaseName)
|
||||
_, err := GetDeployment(e.Client.ClientGo, namespace, e.CaseBaseName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to list deployment in namespace: %q", namespace))
|
||||
}
|
||||
//Check secrets
|
||||
secretsList, err := e.Client.ClientGo.CoreV1().Secrets(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: e.labelSelector})
|
||||
secretsList, err := e.Client.ClientGo.CoreV1().Secrets(namespace).List(e.Ctx, metav1.ListOptions{LabelSelector: e.labelSelector})
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) { //resource should be excluded
|
||||
return nil
|
||||
@@ -118,7 +115,7 @@ func (e *ExcludeResources) Verify() error {
|
||||
}
|
||||
|
||||
//Check configmap
|
||||
configmapList, err := e.Client.ClientGo.CoreV1().ConfigMaps(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: e.labelSelector})
|
||||
configmapList, err := e.Client.ClientGo.CoreV1().ConfigMaps(namespace).List(e.Ctx, metav1.ListOptions{LabelSelector: e.labelSelector})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to list configmap in namespace: %q", namespace))
|
||||
} else if len(configmapList.Items) == 0 {
|
||||
|
||||
@@ -51,11 +51,11 @@ var RestoreWithIncludeNamespaces func() = TestFunc(&IncludeNamespaces{FilteringC
|
||||
|
||||
func (i *IncludeNamespaces) Init() error {
|
||||
i.FilteringCase.Init()
|
||||
i.CaseBaseName = "include-namespaces-" + i.UUIDgen
|
||||
i.namespacesIncluded = i.NamespacesTotal / 2
|
||||
i.allTestNamespaces = &[]string{}
|
||||
i.NSBaseName = "include-namespaces-" + UUIDgen.String()
|
||||
for nsNum := 0; nsNum < i.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", i.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", i.CaseBaseName, nsNum)
|
||||
if nsNum < i.namespacesIncluded {
|
||||
*i.NSIncluded = append(*i.NSIncluded, createNSName)
|
||||
}
|
||||
@@ -63,8 +63,8 @@ func (i *IncludeNamespaces) Init() error {
|
||||
}
|
||||
|
||||
if i.IsTestInBackup {
|
||||
i.BackupName = "backup-include-namespaces-" + UUIDgen.String()
|
||||
i.RestoreName = "restore-" + UUIDgen.String()
|
||||
i.BackupName = "backup-" + i.CaseBaseName
|
||||
i.RestoreName = "restore-" + i.UUIDgen
|
||||
i.TestMsg = &TestMSG{
|
||||
Desc: "Backup resources with include namespace test",
|
||||
FailedMSG: "Failed to backup with namespace include",
|
||||
@@ -82,8 +82,8 @@ func (i *IncludeNamespaces) Init() error {
|
||||
}
|
||||
|
||||
} else {
|
||||
i.BackupName = "backup-" + UUIDgen.String()
|
||||
i.RestoreName = "restore-include-namespaces-" + UUIDgen.String()
|
||||
i.BackupName = "backup-" + i.UUIDgen
|
||||
i.RestoreName = "restore-" + i.CaseBaseName
|
||||
i.TestMsg = &TestMSG{
|
||||
Desc: "Restore resources with include namespace test",
|
||||
FailedMSG: "Failed to restore with namespace include",
|
||||
@@ -105,12 +105,11 @@ func (i *IncludeNamespaces) Init() error {
|
||||
}
|
||||
|
||||
func (i *IncludeNamespaces) CreateResources() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
i.Ctx, i.CtxCancel = context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
for nsNum := 0; nsNum < i.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", i.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", i.CaseBaseName, nsNum)
|
||||
fmt.Printf("Creating namespaces ...%s\n", createNSName)
|
||||
if err := CreateNamespace(ctx, i.Client, createNSName); err != nil {
|
||||
if err := CreateNamespace(i.Ctx, i.Client, createNSName); err != nil {
|
||||
return errors.Wrapf(err, "Failed to create namespace %s", createNSName)
|
||||
}
|
||||
}
|
||||
@@ -118,12 +117,10 @@ func (i *IncludeNamespaces) CreateResources() error {
|
||||
}
|
||||
|
||||
func (i *IncludeNamespaces) Verify() error {
|
||||
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer ctxCancel()
|
||||
// Verify that we got back all of the namespaces we created
|
||||
for nsNum := 0; nsNum < i.namespacesIncluded; nsNum++ {
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", i.NSBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(ctx, i.Client, checkNSName)
|
||||
checkNSName := fmt.Sprintf("%s-%00000d", i.CaseBaseName, nsNum)
|
||||
checkNS, err := GetNamespace(i.Ctx, i.Client, checkNSName)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not retrieve test namespace %s", checkNSName)
|
||||
}
|
||||
@@ -133,8 +130,8 @@ func (i *IncludeNamespaces) Verify() error {
|
||||
}
|
||||
|
||||
for nsNum := i.namespacesIncluded; nsNum < i.NamespacesTotal; nsNum++ {
|
||||
excludeNSName := fmt.Sprintf("%s-%00000d", i.NSBaseName, nsNum)
|
||||
_, err := GetNamespace(ctx, i.Client, excludeNSName)
|
||||
excludeNSName := fmt.Sprintf("%s-%00000d", i.CaseBaseName, nsNum)
|
||||
_, err := GetNamespace(i.Ctx, i.Client, excludeNSName)
|
||||
if err == nil {
|
||||
return errors.Wrapf(err, "Resource filtering with include namespace but exclude namespace %s exist", excludeNSName)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
package filtering
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -47,9 +46,9 @@ var RestoreWithIncludeResources func() = TestFunc(&IncludeResources{testInRestor
|
||||
|
||||
func (i *IncludeResources) Init() error {
|
||||
i.FilteringCase.Init()
|
||||
i.NSBaseName = "include-resources-" + UUIDgen.String()
|
||||
i.CaseBaseName = "include-resources-" + i.UUIDgen
|
||||
for nsNum := 0; nsNum < i.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", i.NSBaseName, nsNum)
|
||||
createNSName := fmt.Sprintf("%s-%00000d", i.CaseBaseName, nsNum)
|
||||
*i.NSIncluded = append(*i.NSIncluded, createNSName)
|
||||
}
|
||||
if i.IsTestInBackup { // testing case backup with include-resources option
|
||||
@@ -58,8 +57,8 @@ func (i *IncludeResources) Init() error {
|
||||
Text: "Should backup resources which is included others should not be backup",
|
||||
FailedMSG: "Failed to backup with resource include",
|
||||
}
|
||||
i.BackupName = "backup-include-resources-" + UUIDgen.String()
|
||||
i.RestoreName = "restore-" + UUIDgen.String()
|
||||
i.BackupName = "backup-" + i.CaseBaseName
|
||||
i.RestoreName = "restore-" + i.UUIDgen
|
||||
i.BackupArgs = []string{
|
||||
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", i.BackupName,
|
||||
"--include-resources", "deployments,configmaps",
|
||||
@@ -76,8 +75,8 @@ func (i *IncludeResources) Init() error {
|
||||
Text: "Should restore resources which is included others should not be backup",
|
||||
FailedMSG: "Failed to restore with resource include",
|
||||
}
|
||||
i.BackupName = "backup-" + UUIDgen.String()
|
||||
i.RestoreName = "restore-include-resources-" + UUIDgen.String()
|
||||
i.BackupName = "backup-" + i.UUIDgen
|
||||
i.RestoreName = "restore-" + i.CaseBaseName
|
||||
i.BackupArgs = []string{
|
||||
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", i.BackupName,
|
||||
"--include-namespaces", strings.Join(*i.NSIncluded, ","),
|
||||
@@ -94,15 +93,15 @@ func (i *IncludeResources) Init() error {
|
||||
|
||||
func (i *IncludeResources) Verify() error {
|
||||
for nsNum := 0; nsNum < i.NamespacesTotal; nsNum++ {
|
||||
namespace := fmt.Sprintf("%s-%00000d", i.NSBaseName, nsNum)
|
||||
namespace := fmt.Sprintf("%s-%00000d", i.CaseBaseName, nsNum)
|
||||
fmt.Printf("Checking resources in namespaces ...%s\n", namespace)
|
||||
//Check deployment
|
||||
_, err := GetDeployment(i.Client.ClientGo, namespace, i.NSBaseName)
|
||||
_, err := GetDeployment(i.Client.ClientGo, namespace, i.CaseBaseName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to list deployment in namespace: %q", namespace))
|
||||
}
|
||||
//Check secrets
|
||||
secretsList, err := i.Client.ClientGo.CoreV1().Secrets(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: i.labelSelector})
|
||||
secretsList, err := i.Client.ClientGo.CoreV1().Secrets(namespace).List(i.Ctx, metav1.ListOptions{LabelSelector: i.labelSelector})
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) { //resource should be excluded
|
||||
return nil
|
||||
@@ -113,7 +112,7 @@ func (i *IncludeResources) Verify() error {
|
||||
}
|
||||
|
||||
//Check configmap
|
||||
configmapList, err := i.Client.ClientGo.CoreV1().ConfigMaps(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: i.labelSelector})
|
||||
configmapList, err := i.Client.ClientGo.CoreV1().ConfigMaps(namespace).List(i.Ctx, metav1.ListOptions{LabelSelector: i.labelSelector})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("failed to list configmap in namespace: %q", namespace))
|
||||
} else if len(configmapList.Items) == 0 {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user