mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-09-07 08:37:19 +00:00
Merge branch 'main' into data-mover-generic-data-path
This commit is contained in:
+6
-4
@@ -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
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
@@ -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"`
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
)
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -635,7 +635,11 @@ func (kb *kubernetesBackupper) FinalizeBackup(log logrus.FieldLogger,
|
||||
}
|
||||
|
||||
// write new tar archive replacing files in original with content updateFiles for matches
|
||||
buildFinalTarball(tr, tw, updateFiles)
|
||||
if err := buildFinalTarball(tr, tw, updateFiles); err != nil {
|
||||
log.Errorf("Error building final tarball: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
log.WithField("progress", "").Infof("Updated a total of %d items", len(backupRequest.BackedUpItems))
|
||||
|
||||
return nil
|
||||
|
||||
+16
-4
@@ -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"
|
||||
)
|
||||
|
||||
@@ -153,10 +154,21 @@ func (f *factory) KubebuilderClient() (kbclient.Client, error) {
|
||||
}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
velerov1api.AddToScheme(scheme)
|
||||
k8scheme.AddToScheme(scheme)
|
||||
apiextv1beta1.AddToScheme(scheme)
|
||||
apiextv1.AddToScheme(scheme)
|
||||
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
|
||||
}
|
||||
if err := apiextv1beta1.AddToScheme(scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := apiextv1.AddToScheme(scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kubebuilderClient, err := kbclient.New(clientConfig, kbclient.Options{
|
||||
Scheme: scheme,
|
||||
})
|
||||
|
||||
@@ -162,7 +162,9 @@ func getKubectlVersion() (string, error) {
|
||||
case <-time.After(kubectlTimeout):
|
||||
// we don't care about the possible error returned from Kill() here,
|
||||
// just return an empty string
|
||||
kubectlCmd.Process.Kill()
|
||||
if err := kubectlCmd.Process.Kill(); err != nil {
|
||||
return "", fmt.Errorf("error killing kubectl process: %w", err)
|
||||
}
|
||||
return "", errors.New("timeout waiting for kubectl version")
|
||||
|
||||
case err := <-done:
|
||||
|
||||
@@ -64,7 +64,10 @@ $ velero completion fish > ~/.config/fish/completions/velero.fish
|
||||
shell := args[0]
|
||||
switch shell {
|
||||
case "bash":
|
||||
cmd.Root().GenBashCompletion(os.Stdout)
|
||||
if err := cmd.Root().GenBashCompletion(os.Stdout); err != nil {
|
||||
fmt.Println("fail to generate bash completion script", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
case "zsh":
|
||||
// # fix #4912
|
||||
// cobra does not support zsh completion ouptput used by source command
|
||||
@@ -72,11 +75,20 @@ $ velero completion fish > ~/.config/fish/completions/velero.fish
|
||||
// Need to append compdef manually to do that.
|
||||
zshHead := "#compdef velero\ncompdef _velero velero\n"
|
||||
out := os.Stdout
|
||||
out.Write([]byte(zshHead))
|
||||
if _, err := out.Write([]byte(zshHead)); err != nil {
|
||||
fmt.Println("fail to append compdef command into zsh completion script: ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cmd.Root().GenZshCompletion(out)
|
||||
if err := cmd.Root().GenZshCompletion(out); err != nil {
|
||||
fmt.Println("fail to generate zsh completion script: ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
case "fish":
|
||||
cmd.Root().GenFishCompletion(os.Stdout, true)
|
||||
if err := cmd.Root().GenFishCompletion(os.Stdout, true); err != nil {
|
||||
fmt.Println("fail to generate fish completion script: ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
default:
|
||||
fmt.Println("Invalid shell specified, specify bash, zsh, or fish")
|
||||
os.Exit(1)
|
||||
|
||||
@@ -44,6 +44,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"
|
||||
@@ -134,9 +135,22 @@ func newNodeAgentServer(logger logrus.FieldLogger, factory client.Factory, confi
|
||||
|
||||
ctrl.SetLogger(zap.New(zap.UseDevMode(true)))
|
||||
|
||||
velerov1api.AddToScheme(scheme)
|
||||
v1.AddToScheme(scheme)
|
||||
storagev1api.AddToScheme(scheme)
|
||||
if err := velerov1api.AddToScheme(scheme); err != nil {
|
||||
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
|
||||
}
|
||||
if err := storagev1api.AddToScheme(scheme); err != nil {
|
||||
cancelFunc()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeName := os.Getenv("NODE_NAME")
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -313,9 +314,22 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s
|
||||
}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
velerov1api.AddToScheme(scheme)
|
||||
corev1api.AddToScheme(scheme)
|
||||
snapshotv1api.AddToScheme(scheme)
|
||||
if err := velerov1api.AddToScheme(scheme); err != nil {
|
||||
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
|
||||
}
|
||||
if err := snapshotv1api.AddToScheme(scheme); err != nil {
|
||||
cancelFunc()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctrl.SetLogger(logrusr.New(logger))
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -61,7 +61,9 @@ func ClearOutputFlagDefault(cmd *cobra.Command) {
|
||||
return
|
||||
}
|
||||
f.DefValue = ""
|
||||
f.Value.Set("")
|
||||
if err := f.Value.Set(""); err != nil {
|
||||
fmt.Printf("error clear the default value of output flag: %s\n", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// GetOutputFlagValue returns the value of the "output" flag
|
||||
|
||||
@@ -561,8 +561,7 @@ func (b *backupReconciler) validateAndGetSnapshotLocations(backup *velerov1api.B
|
||||
continue
|
||||
}
|
||||
location := &velerov1api.VolumeSnapshotLocation{}
|
||||
b.kbClient.Get(context.Background(), kbclient.ObjectKey{Namespace: backup.Namespace, Name: defaultLocation}, location)
|
||||
if err != nil {
|
||||
if err := b.kbClient.Get(context.Background(), kbclient.ObjectKey{Namespace: backup.Namespace, Name: defaultLocation}, location); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("error getting volume snapshot location named %s: %v", defaultLocation, err))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -96,7 +96,9 @@ func (r *BackupRepoReconciler) invalidateBackupReposForBSL(bslObj client.Object)
|
||||
|
||||
for i := range list.Items {
|
||||
r.logger.WithField("BSL", bsl.Name).Infof("Invalidating Backup Repository %s", list.Items[i].Name)
|
||||
r.patchBackupRepository(context.Background(), &list.Items[i], repoNotReady("re-establish on BSL change"))
|
||||
if err := r.patchBackupRepository(context.Background(), &list.Items[i], repoNotReady("re-establish on BSL change")); err != nil {
|
||||
r.logger.WithField("BSL", bsl.Name).WithError(err).Errorf("fail to patch BackupRepository %s", list.Items[i].Name)
|
||||
}
|
||||
}
|
||||
|
||||
return []reconcile.Request{}
|
||||
|
||||
@@ -18,6 +18,7 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
|
||||
@@ -397,7 +398,10 @@ func backupSyncSourceOrderFunc(objList client.ObjectList) client.ObjectList {
|
||||
cpBsl := bsl
|
||||
bslArray = append(bslArray, &cpBsl)
|
||||
}
|
||||
meta.SetList(resultBSLList, bslArray)
|
||||
if err := meta.SetList(resultBSLList, bslArray); err != nil {
|
||||
fmt.Printf("fail to sort BSL list: %s", err.Error())
|
||||
return &velerov1api.BackupStorageLocationList{}
|
||||
}
|
||||
|
||||
return resultBSLList
|
||||
}
|
||||
|
||||
@@ -33,6 +33,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/datapath"
|
||||
"github.com/vmware-tanzu/velero/pkg/exposer"
|
||||
@@ -264,7 +265,7 @@ func (r *PodVolumeBackupReconciler) OnDataPathProgress(ctx context.Context, name
|
||||
}
|
||||
|
||||
original := pvb.DeepCopy()
|
||||
pvb.Status.Progress = velerov1api.PodVolumeOperationProgress{TotalBytes: progress.TotalBytes, BytesDone: progress.BytesDone}
|
||||
pvb.Status.Progress = veleroapishared.DataMoveOperationProgress{TotalBytes: progress.TotalBytes, BytesDone: progress.BytesDone}
|
||||
|
||||
if err := r.Client.Patch(ctx, &pvb, client.MergeFrom(original)); err != nil {
|
||||
log.WithError(err).Error("Failed to update progress")
|
||||
@@ -358,10 +359,10 @@ func UpdatePVBStatusToFailed(ctx context.Context, c client.Client, pvb *velerov1
|
||||
pvb.Status.Message = errString
|
||||
pvb.Status.CompletionTimestamp = &metav1.Time{Time: time}
|
||||
|
||||
if err := c.Patch(ctx, pvb, client.MergeFrom(original)); err != nil {
|
||||
err := c.Patch(ctx, pvb, client.MergeFrom(original))
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error updating PodVolumeBackup status")
|
||||
return err
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -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/datapath"
|
||||
"github.com/vmware-tanzu/velero/pkg/exposer"
|
||||
@@ -167,12 +168,12 @@ func UpdatePVRStatusToFailed(ctx context.Context, c client.Client, pvb *velerov1
|
||||
pvb.Status.Message = errString
|
||||
pvb.Status.CompletionTimestamp = &metav1.Time{Time: time}
|
||||
|
||||
if err := c.Patch(ctx, pvb, client.MergeFrom(original)); err != nil {
|
||||
err := c.Patch(ctx, pvb, client.MergeFrom(original))
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error updating PodVolumeRestore status")
|
||||
return err
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *PodVolumeRestoreReconciler) shouldProcess(ctx context.Context, log logrus.FieldLogger, pvr *velerov1api.PodVolumeRestore) (bool, *corev1api.Pod, error) {
|
||||
@@ -357,7 +358,7 @@ func (c *PodVolumeRestoreReconciler) OnDataPathProgress(ctx context.Context, nam
|
||||
}
|
||||
|
||||
original := pvr.DeepCopy()
|
||||
pvr.Status.Progress = velerov1api.PodVolumeOperationProgress{TotalBytes: progress.TotalBytes, BytesDone: progress.BytesDone}
|
||||
pvr.Status.Progress = veleroapishared.DataMoveOperationProgress{TotalBytes: progress.TotalBytes, BytesDone: progress.BytesDone}
|
||||
|
||||
if err := c.Client.Patch(ctx, &pvr, client.MergeFrom(original)); err != nil {
|
||||
log.WithError(err).Error("Failed to update progress")
|
||||
|
||||
@@ -305,10 +305,7 @@ func (r *restoreReconciler) validateAndComplete(restore *api.Restore) backupInfo
|
||||
}))
|
||||
|
||||
backupList := &api.BackupList{}
|
||||
r.kbClient.List(context.Background(), backupList, &client.ListOptions{
|
||||
LabelSelector: selector,
|
||||
})
|
||||
if err != nil {
|
||||
if err := r.kbClient.List(context.Background(), backupList, &client.ListOptions{LabelSelector: selector}); err != nil {
|
||||
restore.Status.ValidationErrors = append(restore.Status.ValidationErrors, "Unable to list backups for schedule")
|
||||
return backupInfo{}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,6 @@ func (r *restoreOperationsReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=restores,verbs=get;list;watch;update
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=restores/status,verbs=get
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=restorestoragelocations,verbs=get
|
||||
|
||||
func (r *restoreOperationsReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
log := r.logger.WithField("restore operations for restore", req.String())
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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{}
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package install
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -27,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"
|
||||
)
|
||||
|
||||
@@ -250,7 +252,16 @@ func AllCRDs() *unstructured.UnstructuredList {
|
||||
|
||||
for _, crd := range v1crds.CRDs {
|
||||
crd.SetLabels(Labels())
|
||||
appendUnstructured(resources, crd)
|
||||
if err := appendUnstructured(resources, crd); err != nil {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
return resources
|
||||
@@ -262,32 +273,44 @@ func AllResources(o *VeleroOptions) *unstructured.UnstructuredList {
|
||||
resources := AllCRDs()
|
||||
|
||||
ns := Namespace(o.Namespace)
|
||||
appendUnstructured(resources, ns)
|
||||
if err := appendUnstructured(resources, ns); err != nil {
|
||||
fmt.Printf("error appending Namespace %s: %s\n", ns.GetName(), err.Error())
|
||||
}
|
||||
|
||||
serviceAccountName := defaultServiceAccountName
|
||||
if o.ServiceAccountName == "" {
|
||||
crb := ClusterRoleBinding(o.Namespace)
|
||||
appendUnstructured(resources, crb)
|
||||
if err := appendUnstructured(resources, crb); err != nil {
|
||||
fmt.Printf("error appending ClusterRoleBinding %s: %s\n", crb.GetName(), err.Error())
|
||||
}
|
||||
sa := ServiceAccount(o.Namespace, o.ServiceAccountAnnotations)
|
||||
appendUnstructured(resources, sa)
|
||||
if err := appendUnstructured(resources, sa); err != nil {
|
||||
fmt.Printf("error appending ServiceAccount %s: %s\n", sa.GetName(), err.Error())
|
||||
}
|
||||
} else {
|
||||
serviceAccountName = o.ServiceAccountName
|
||||
}
|
||||
|
||||
if o.SecretData != nil {
|
||||
sec := Secret(o.Namespace, o.SecretData)
|
||||
appendUnstructured(resources, sec)
|
||||
if err := appendUnstructured(resources, sec); err != nil {
|
||||
fmt.Printf("error appending Secret %s: %s\n", sec.GetName(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if !o.NoDefaultBackupLocation {
|
||||
bsl := BackupStorageLocation(o.Namespace, o.ProviderName, o.Bucket, o.Prefix, o.BSLConfig, o.CACertData)
|
||||
appendUnstructured(resources, bsl)
|
||||
if err := appendUnstructured(resources, bsl); err != nil {
|
||||
fmt.Printf("error appending BackupStorageLocation %s: %s\n", bsl.GetName(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// A snapshot location may not be desirable for users relying on pod volume backup/restore
|
||||
if o.UseVolumeSnapshots {
|
||||
vsl := VolumeSnapshotLocation(o.Namespace, o.ProviderName, o.VSLConfig)
|
||||
appendUnstructured(resources, vsl)
|
||||
if err := appendUnstructured(resources, vsl); err != nil {
|
||||
fmt.Printf("error appending VolumeSnapshotLocation %s: %s\n", vsl.GetName(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
secretPresent := o.SecretData != nil
|
||||
@@ -322,7 +345,9 @@ func AllResources(o *VeleroOptions) *unstructured.UnstructuredList {
|
||||
|
||||
deploy := Deployment(o.Namespace, deployOpts...)
|
||||
|
||||
appendUnstructured(resources, deploy)
|
||||
if err := appendUnstructured(resources, deploy); err != nil {
|
||||
fmt.Printf("error appending Deployment %s: %s\n", deploy.GetName(), err.Error())
|
||||
}
|
||||
|
||||
if o.UseNodeAgent {
|
||||
dsOpts := []podTemplateOption{
|
||||
@@ -337,7 +362,9 @@ func AllResources(o *VeleroOptions) *unstructured.UnstructuredList {
|
||||
dsOpts = append(dsOpts, WithFeatures(o.Features))
|
||||
}
|
||||
ds := DaemonSet(o.Namespace, dsOpts...)
|
||||
appendUnstructured(resources, ds)
|
||||
if err := appendUnstructured(resources, ds); err != nil {
|
||||
fmt.Printf("error appending DaemonSet %s: %s\n", ds.GetName(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return resources
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
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 common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
)
|
||||
|
||||
func PluginConfigLabelSelector(kind PluginKind, name string) string {
|
||||
return fmt.Sprintf("velero.io/plugin-config,%s=%s", name, kind)
|
||||
}
|
||||
|
||||
func GetPluginConfig(kind PluginKind, name string, client corev1client.ConfigMapInterface) (*corev1.ConfigMap, error) {
|
||||
opts := metav1.ListOptions{
|
||||
// velero.io/plugin-config: true
|
||||
// velero.io/pod-volume-restore: RestoreItemAction
|
||||
LabelSelector: PluginConfigLabelSelector(kind, name),
|
||||
}
|
||||
|
||||
list, err := client.List(context.Background(), opts)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if len(list.Items) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if len(list.Items) > 1 {
|
||||
var items []string
|
||||
for _, item := range list.Items {
|
||||
items = append(items, item.Name)
|
||||
}
|
||||
return nil, errors.Errorf("found more than one ConfigMap matching label selector %q: %v", opts.LabelSelector, items)
|
||||
}
|
||||
|
||||
return &list.Items[0], nil
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
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 common
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
)
|
||||
|
||||
func TestGetPluginConfig(t *testing.T) {
|
||||
type args struct {
|
||||
kind PluginKind
|
||||
name string
|
||||
objects []runtime.Object
|
||||
}
|
||||
pluginLabelsMap := map[string]string{"velero.io/plugin-config": "", "foo": "RestoreItemAction"}
|
||||
testConfigMap := &corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo-config",
|
||||
Namespace: velerov1.DefaultNamespace,
|
||||
Labels: pluginLabelsMap,
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *corev1.ConfigMap
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "should return nil if no config map found",
|
||||
args: args{
|
||||
kind: PluginKindRestoreItemAction,
|
||||
name: "foo",
|
||||
objects: []runtime.Object{},
|
||||
},
|
||||
want: nil,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should return error if more than one config map found",
|
||||
args: args{
|
||||
kind: PluginKindRestoreItemAction,
|
||||
name: "foo",
|
||||
objects: []runtime.Object{
|
||||
&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo-config",
|
||||
Namespace: velerov1.DefaultNamespace,
|
||||
Labels: pluginLabelsMap,
|
||||
},
|
||||
},
|
||||
&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo-config-duplicate",
|
||||
Namespace: velerov1.DefaultNamespace,
|
||||
Labels: pluginLabelsMap,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "should return pointer to configmap if only one config map with label found",
|
||||
args: args{
|
||||
kind: PluginKindRestoreItemAction,
|
||||
name: "foo",
|
||||
objects: []runtime.Object{
|
||||
testConfigMap,
|
||||
},
|
||||
},
|
||||
want: testConfigMap,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
fakeClient := fake.NewSimpleClientset(tt.args.objects...)
|
||||
got, err := GetPluginConfig(tt.args.kind, tt.args.name, fakeClient.CoreV1().ConfigMaps(velerov1.DefaultNamespace))
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetPluginConfig() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("GetPluginConfig() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,9 @@ func (c *ObjectStoreGRPCClient) PutObject(bucket, key string, body io.Reader) er
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
stream.CloseSend()
|
||||
if err := stream.CloseSend(); err != nil {
|
||||
return common.FromGRPCError(err)
|
||||
}
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -232,7 +232,10 @@ func getNames(command string, kind common.PluginKind, plugin Interface) []Plugin
|
||||
func (s *server) Serve() {
|
||||
if s.flagSet != nil && !s.flagSet.Parsed() {
|
||||
s.log.Debugf("Parsing flags")
|
||||
s.flagSet.Parse(os.Args[1:])
|
||||
if err := s.flagSet.Parse(os.Args[1:]); err != nil {
|
||||
s.log.Errorf("fail to parse the flags: %s", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
s.log.Level = s.logLevelFlag.Parse()
|
||||
|
||||
@@ -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)
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
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 mockery v2.22.1. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
@@ -64,11 +50,39 @@ func (_m *RepositoryWriter) Close(ctx context.Context) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// ConcatenateObjects provides a mock function with given fields: ctx, objectIDs
|
||||
func (_m *RepositoryWriter) ConcatenateObjects(ctx context.Context, objectIDs []object.ID) (object.ID, error) {
|
||||
ret := _m.Called(ctx, objectIDs)
|
||||
|
||||
var r0 object.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID) (object.ID, error)); ok {
|
||||
return rf(ctx, objectIDs)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID) object.ID); ok {
|
||||
r0 = rf(ctx, objectIDs)
|
||||
} else {
|
||||
r0 = ret.Get(0).(object.ID)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, []object.ID) error); ok {
|
||||
r1 = rf(ctx, objectIDs)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ContentInfo provides a mock function with given fields: ctx, contentID
|
||||
func (_m *RepositoryWriter) ContentInfo(ctx context.Context, contentID index.ID) (index.Info, error) {
|
||||
ret := _m.Called(ctx, contentID)
|
||||
|
||||
var r0 index.Info
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, index.ID) (index.Info, error)); ok {
|
||||
return rf(ctx, contentID)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, index.ID) index.Info); ok {
|
||||
r0 = rf(ctx, contentID)
|
||||
} else {
|
||||
@@ -77,7 +91,6 @@ func (_m *RepositoryWriter) ContentInfo(ctx context.Context, contentID index.ID)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, index.ID) error); ok {
|
||||
r1 = rf(ctx, contentID)
|
||||
} else {
|
||||
@@ -106,6 +119,10 @@ func (_m *RepositoryWriter) FindManifests(ctx context.Context, labels map[string
|
||||
ret := _m.Called(ctx, labels)
|
||||
|
||||
var r0 []*manifest.EntryMetadata
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) ([]*manifest.EntryMetadata, error)); ok {
|
||||
return rf(ctx, labels)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) []*manifest.EntryMetadata); ok {
|
||||
r0 = rf(ctx, labels)
|
||||
} else {
|
||||
@@ -114,7 +131,6 @@ func (_m *RepositoryWriter) FindManifests(ctx context.Context, labels map[string
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, map[string]string) error); ok {
|
||||
r1 = rf(ctx, labels)
|
||||
} else {
|
||||
@@ -143,6 +159,10 @@ func (_m *RepositoryWriter) GetManifest(ctx context.Context, id manifest.ID, dat
|
||||
ret := _m.Called(ctx, id, data)
|
||||
|
||||
var r0 *manifest.EntryMetadata
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) (*manifest.EntryMetadata, error)); ok {
|
||||
return rf(ctx, id, data)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) *manifest.EntryMetadata); ok {
|
||||
r0 = rf(ctx, id, data)
|
||||
} else {
|
||||
@@ -151,7 +171,6 @@ func (_m *RepositoryWriter) GetManifest(ctx context.Context, id manifest.ID, dat
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, manifest.ID, interface{}) error); ok {
|
||||
r1 = rf(ctx, id, data)
|
||||
} else {
|
||||
@@ -182,6 +201,11 @@ func (_m *RepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteSession
|
||||
ret := _m.Called(ctx, opt)
|
||||
|
||||
var r0 context.Context
|
||||
var r1 repo.RepositoryWriter
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.RepositoryWriter, error)); ok {
|
||||
return rf(ctx, opt)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
|
||||
r0 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -190,7 +214,6 @@ func (_m *RepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteSession
|
||||
}
|
||||
}
|
||||
|
||||
var r1 repo.RepositoryWriter
|
||||
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.RepositoryWriter); ok {
|
||||
r1 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -199,7 +222,6 @@ func (_m *RepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteSession
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
|
||||
r2 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -209,11 +231,20 @@ func (_m *RepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteSession
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// OnSuccessfulFlush provides a mock function with given fields: callback
|
||||
func (_m *RepositoryWriter) OnSuccessfulFlush(callback repo.RepositoryWriterCallback) {
|
||||
_m.Called(callback)
|
||||
}
|
||||
|
||||
// OpenObject provides a mock function with given fields: ctx, id
|
||||
func (_m *RepositoryWriter) OpenObject(ctx context.Context, id object.ID) (object.Reader, error) {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
var r0 object.Reader
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) (object.Reader, error)); ok {
|
||||
return rf(ctx, id)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) object.Reader); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -222,7 +253,6 @@ func (_m *RepositoryWriter) OpenObject(ctx context.Context, id object.ID) (objec
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -253,6 +283,10 @@ func (_m *RepositoryWriter) PrefetchObjects(ctx context.Context, objectIDs []obj
|
||||
ret := _m.Called(ctx, objectIDs, hint)
|
||||
|
||||
var r0 []index.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) ([]index.ID, error)); ok {
|
||||
return rf(ctx, objectIDs, hint)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) []index.ID); ok {
|
||||
r0 = rf(ctx, objectIDs, hint)
|
||||
} else {
|
||||
@@ -261,7 +295,6 @@ func (_m *RepositoryWriter) PrefetchObjects(ctx context.Context, objectIDs []obj
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, []object.ID, string) error); ok {
|
||||
r1 = rf(ctx, objectIDs, hint)
|
||||
} else {
|
||||
@@ -276,13 +309,16 @@ func (_m *RepositoryWriter) PutManifest(ctx context.Context, labels map[string]s
|
||||
ret := _m.Called(ctx, labels, payload)
|
||||
|
||||
var r0 manifest.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) (manifest.ID, error)); ok {
|
||||
return rf(ctx, labels, payload)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) manifest.ID); ok {
|
||||
r0 = rf(ctx, labels, payload)
|
||||
} else {
|
||||
r0 = ret.Get(0).(manifest.ID)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, map[string]string, interface{}) error); ok {
|
||||
r1 = rf(ctx, labels, payload)
|
||||
} else {
|
||||
@@ -306,6 +342,30 @@ func (_m *RepositoryWriter) Refresh(ctx context.Context) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// ReplaceManifests provides a mock function with given fields: ctx, labels, payload
|
||||
func (_m *RepositoryWriter) ReplaceManifests(ctx context.Context, labels map[string]string, payload interface{}) (manifest.ID, error) {
|
||||
ret := _m.Called(ctx, labels, payload)
|
||||
|
||||
var r0 manifest.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) (manifest.ID, error)); ok {
|
||||
return rf(ctx, labels, payload)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) manifest.ID); ok {
|
||||
r0 = rf(ctx, labels, payload)
|
||||
} else {
|
||||
r0 = ret.Get(0).(manifest.ID)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, map[string]string, interface{}) error); ok {
|
||||
r1 = rf(ctx, labels, payload)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Time provides a mock function with given fields:
|
||||
func (_m *RepositoryWriter) Time() time.Time {
|
||||
ret := _m.Called()
|
||||
@@ -330,6 +390,10 @@ func (_m *RepositoryWriter) VerifyObject(ctx context.Context, id object.ID) ([]i
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
var r0 []index.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) ([]index.ID, error)); ok {
|
||||
return rf(ctx, id)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) []index.ID); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -338,7 +402,6 @@ func (_m *RepositoryWriter) VerifyObject(ctx context.Context, id object.ID) ([]i
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -347,3 +410,18 @@ func (_m *RepositoryWriter) VerifyObject(ctx context.Context, id object.ID) ([]i
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewRepositoryWriter interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewRepositoryWriter creates a new instance of RepositoryWriter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewRepositoryWriter(t mockConstructorTestingTNewRepositoryWriter) *RepositoryWriter {
|
||||
mock := &RepositoryWriter{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -496,6 +497,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"
|
||||
|
||||
@@ -366,6 +367,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{
|
||||
|
||||
@@ -56,5 +56,5 @@ func (c *AzureBackend) Setup(ctx context.Context, flags map[string]string) error
|
||||
}
|
||||
|
||||
func (c *AzureBackend) Connect(ctx context.Context, isCreate bool) (blob.Storage, error) {
|
||||
return azure.New(ctx, &c.options)
|
||||
return azure.New(ctx, &c.options, false)
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ import (
|
||||
"github.com/kopia/kopia/repo/blob/throttling"
|
||||
"github.com/kopia/kopia/repo/content"
|
||||
"github.com/kopia/kopia/repo/encryption"
|
||||
"github.com/kopia/kopia/repo/format"
|
||||
"github.com/kopia/kopia/repo/hashing"
|
||||
"github.com/kopia/kopia/repo/object"
|
||||
"github.com/kopia/kopia/repo/splitter"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/repository/udmrepo"
|
||||
@@ -51,12 +51,12 @@ func setupLimits(ctx context.Context, flags map[string]string) throttling.Limits
|
||||
// SetupNewRepositoryOptions setups the options when creating a new Kopia repository
|
||||
func SetupNewRepositoryOptions(ctx context.Context, flags map[string]string) repo.NewRepositoryOptions {
|
||||
return repo.NewRepositoryOptions{
|
||||
BlockFormat: content.FormattingOptions{
|
||||
BlockFormat: format.ContentFormat{
|
||||
Hash: optionalHaveStringWithDefault(udmrepo.StoreOptionGenHashAlgo, flags, hashing.DefaultAlgorithm),
|
||||
Encryption: optionalHaveStringWithDefault(udmrepo.StoreOptionGenEncryptAlgo, flags, encryption.DefaultAlgorithm),
|
||||
},
|
||||
|
||||
ObjectFormat: object.Format{
|
||||
ObjectFormat: format.ObjectFormat{
|
||||
Splitter: optionalHaveStringWithDefault(udmrepo.StoreOptionGenSplitAlgo, flags, splitter.DefaultAlgorithm),
|
||||
},
|
||||
|
||||
|
||||
@@ -50,5 +50,5 @@ func (c *GCSBackend) Setup(ctx context.Context, flags map[string]string) error {
|
||||
}
|
||||
|
||||
func (c *GCSBackend) Connect(ctx context.Context, isCreate bool) (blob.Storage, error) {
|
||||
return gcs.New(ctx, &c.options)
|
||||
return gcs.New(ctx, &c.options, false)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.14.0. DO NOT EDIT.
|
||||
// Code generated by mockery v2.22.1. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
@@ -8,8 +8,12 @@ import (
|
||||
|
||||
context "context"
|
||||
|
||||
format "github.com/kopia/kopia/repo/format"
|
||||
|
||||
index "github.com/kopia/kopia/repo/content/index"
|
||||
|
||||
indexblob "github.com/kopia/kopia/repo/content/indexblob"
|
||||
|
||||
manifest "github.com/kopia/kopia/repo/manifest"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
@@ -44,20 +48,6 @@ func (_m *DirectRepository) AlsoLogToContentLog(ctx context.Context) context.Con
|
||||
return r0
|
||||
}
|
||||
|
||||
// BlobCfg provides a mock function with given fields:
|
||||
func (_m *DirectRepository) BlobCfg() content.BlobCfgBlob {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 content.BlobCfgBlob
|
||||
if rf, ok := ret.Get(0).(func() content.BlobCfgBlob); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(content.BlobCfgBlob)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// BlobReader provides a mock function with given fields:
|
||||
func (_m *DirectRepository) BlobReader() blob.Reader {
|
||||
ret := _m.Called()
|
||||
@@ -137,6 +127,10 @@ func (_m *DirectRepository) ContentInfo(ctx context.Context, contentID index.ID)
|
||||
ret := _m.Called(ctx, contentID)
|
||||
|
||||
var r0 index.Info
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, index.ID) (index.Info, error)); ok {
|
||||
return rf(ctx, contentID)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, index.ID) index.Info); ok {
|
||||
r0 = rf(ctx, contentID)
|
||||
} else {
|
||||
@@ -145,7 +139,6 @@ func (_m *DirectRepository) ContentInfo(ctx context.Context, contentID index.ID)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, index.ID) error); ok {
|
||||
r1 = rf(ctx, contentID)
|
||||
} else {
|
||||
@@ -171,22 +164,6 @@ func (_m *DirectRepository) ContentReader() content.Reader {
|
||||
return r0
|
||||
}
|
||||
|
||||
// Crypter provides a mock function with given fields:
|
||||
func (_m *DirectRepository) Crypter() *content.Crypter {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 *content.Crypter
|
||||
if rf, ok := ret.Get(0).(func() *content.Crypter); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*content.Crypter)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeriveKey provides a mock function with given fields: purpose, keyLength
|
||||
func (_m *DirectRepository) DeriveKey(purpose []byte, keyLength int) []byte {
|
||||
ret := _m.Called(purpose, keyLength)
|
||||
@@ -213,6 +190,10 @@ func (_m *DirectRepository) FindManifests(ctx context.Context, labels map[string
|
||||
ret := _m.Called(ctx, labels)
|
||||
|
||||
var r0 []*manifest.EntryMetadata
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) ([]*manifest.EntryMetadata, error)); ok {
|
||||
return rf(ctx, labels)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) []*manifest.EntryMetadata); ok {
|
||||
r0 = rf(ctx, labels)
|
||||
} else {
|
||||
@@ -221,7 +202,6 @@ func (_m *DirectRepository) FindManifests(ctx context.Context, labels map[string
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, map[string]string) error); ok {
|
||||
r1 = rf(ctx, labels)
|
||||
} else {
|
||||
@@ -231,11 +211,31 @@ func (_m *DirectRepository) FindManifests(ctx context.Context, labels map[string
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// FormatManager provides a mock function with given fields:
|
||||
func (_m *DirectRepository) FormatManager() *format.Manager {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 *format.Manager
|
||||
if rf, ok := ret.Get(0).(func() *format.Manager); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*format.Manager)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetManifest provides a mock function with given fields: ctx, id, data
|
||||
func (_m *DirectRepository) GetManifest(ctx context.Context, id manifest.ID, data interface{}) (*manifest.EntryMetadata, error) {
|
||||
ret := _m.Called(ctx, id, data)
|
||||
|
||||
var r0 *manifest.EntryMetadata
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) (*manifest.EntryMetadata, error)); ok {
|
||||
return rf(ctx, id, data)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) *manifest.EntryMetadata); ok {
|
||||
r0 = rf(ctx, id, data)
|
||||
} else {
|
||||
@@ -244,7 +244,6 @@ func (_m *DirectRepository) GetManifest(ctx context.Context, id manifest.ID, dat
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, manifest.ID, interface{}) error); ok {
|
||||
r1 = rf(ctx, id, data)
|
||||
} else {
|
||||
@@ -255,19 +254,22 @@ func (_m *DirectRepository) GetManifest(ctx context.Context, id manifest.ID, dat
|
||||
}
|
||||
|
||||
// IndexBlobs provides a mock function with given fields: ctx, includeInactive
|
||||
func (_m *DirectRepository) IndexBlobs(ctx context.Context, includeInactive bool) ([]content.IndexBlobInfo, error) {
|
||||
func (_m *DirectRepository) IndexBlobs(ctx context.Context, includeInactive bool) ([]indexblob.Metadata, error) {
|
||||
ret := _m.Called(ctx, includeInactive)
|
||||
|
||||
var r0 []content.IndexBlobInfo
|
||||
if rf, ok := ret.Get(0).(func(context.Context, bool) []content.IndexBlobInfo); ok {
|
||||
var r0 []indexblob.Metadata
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, bool) ([]indexblob.Metadata, error)); ok {
|
||||
return rf(ctx, includeInactive)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, bool) []indexblob.Metadata); ok {
|
||||
r0 = rf(ctx, includeInactive)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]content.IndexBlobInfo)
|
||||
r0 = ret.Get(0).([]indexblob.Metadata)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, bool) error); ok {
|
||||
r1 = rf(ctx, includeInactive)
|
||||
} else {
|
||||
@@ -282,6 +284,11 @@ func (_m *DirectRepository) NewDirectWriter(ctx context.Context, opt repo.WriteS
|
||||
ret := _m.Called(ctx, opt)
|
||||
|
||||
var r0 context.Context
|
||||
var r1 repo.DirectRepositoryWriter
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.DirectRepositoryWriter, error)); ok {
|
||||
return rf(ctx, opt)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
|
||||
r0 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -290,7 +297,6 @@ func (_m *DirectRepository) NewDirectWriter(ctx context.Context, opt repo.WriteS
|
||||
}
|
||||
}
|
||||
|
||||
var r1 repo.DirectRepositoryWriter
|
||||
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.DirectRepositoryWriter); ok {
|
||||
r1 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -299,7 +305,6 @@ func (_m *DirectRepository) NewDirectWriter(ctx context.Context, opt repo.WriteS
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
|
||||
r2 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -314,6 +319,11 @@ func (_m *DirectRepository) NewWriter(ctx context.Context, opt repo.WriteSession
|
||||
ret := _m.Called(ctx, opt)
|
||||
|
||||
var r0 context.Context
|
||||
var r1 repo.RepositoryWriter
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.RepositoryWriter, error)); ok {
|
||||
return rf(ctx, opt)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
|
||||
r0 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -322,7 +332,6 @@ func (_m *DirectRepository) NewWriter(ctx context.Context, opt repo.WriteSession
|
||||
}
|
||||
}
|
||||
|
||||
var r1 repo.RepositoryWriter
|
||||
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.RepositoryWriter); ok {
|
||||
r1 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -331,7 +340,6 @@ func (_m *DirectRepository) NewWriter(ctx context.Context, opt repo.WriteSession
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
|
||||
r2 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -342,14 +350,14 @@ func (_m *DirectRepository) NewWriter(ctx context.Context, opt repo.WriteSession
|
||||
}
|
||||
|
||||
// ObjectFormat provides a mock function with given fields:
|
||||
func (_m *DirectRepository) ObjectFormat() object.Format {
|
||||
func (_m *DirectRepository) ObjectFormat() format.ObjectFormat {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 object.Format
|
||||
if rf, ok := ret.Get(0).(func() object.Format); ok {
|
||||
var r0 format.ObjectFormat
|
||||
if rf, ok := ret.Get(0).(func() format.ObjectFormat); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(object.Format)
|
||||
r0 = ret.Get(0).(format.ObjectFormat)
|
||||
}
|
||||
|
||||
return r0
|
||||
@@ -360,6 +368,10 @@ func (_m *DirectRepository) OpenObject(ctx context.Context, id object.ID) (objec
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
var r0 object.Reader
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) (object.Reader, error)); ok {
|
||||
return rf(ctx, id)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) object.Reader); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -368,7 +380,6 @@ func (_m *DirectRepository) OpenObject(ctx context.Context, id object.ID) (objec
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -399,6 +410,10 @@ func (_m *DirectRepository) PrefetchObjects(ctx context.Context, objectIDs []obj
|
||||
ret := _m.Called(ctx, objectIDs, hint)
|
||||
|
||||
var r0 []index.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) ([]index.ID, error)); ok {
|
||||
return rf(ctx, objectIDs, hint)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) []index.ID); ok {
|
||||
r0 = rf(ctx, objectIDs, hint)
|
||||
} else {
|
||||
@@ -407,7 +422,6 @@ func (_m *DirectRepository) PrefetchObjects(ctx context.Context, objectIDs []obj
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, []object.ID, string) error); ok {
|
||||
r1 = rf(ctx, objectIDs, hint)
|
||||
} else {
|
||||
@@ -466,13 +480,16 @@ func (_m *DirectRepository) Token(password string) (string, error) {
|
||||
ret := _m.Called(password)
|
||||
|
||||
var r0 string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(string) (string, error)); ok {
|
||||
return rf(password)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(string) string); ok {
|
||||
r0 = rf(password)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(password)
|
||||
} else {
|
||||
@@ -508,6 +525,10 @@ func (_m *DirectRepository) VerifyObject(ctx context.Context, id object.ID) ([]i
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
var r0 []index.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) ([]index.ID, error)); ok {
|
||||
return rf(ctx, id)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) []index.ID); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -516,7 +537,6 @@ func (_m *DirectRepository) VerifyObject(ctx context.Context, id object.ID) ([]i
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.14.0. DO NOT EDIT.
|
||||
// Code generated by mockery v2.22.1. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
@@ -8,8 +8,12 @@ import (
|
||||
|
||||
context "context"
|
||||
|
||||
format "github.com/kopia/kopia/repo/format"
|
||||
|
||||
index "github.com/kopia/kopia/repo/content/index"
|
||||
|
||||
indexblob "github.com/kopia/kopia/repo/content/indexblob"
|
||||
|
||||
manifest "github.com/kopia/kopia/repo/manifest"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
@@ -44,20 +48,6 @@ func (_m *DirectRepositoryWriter) AlsoLogToContentLog(ctx context.Context) conte
|
||||
return r0
|
||||
}
|
||||
|
||||
// BlobCfg provides a mock function with given fields:
|
||||
func (_m *DirectRepositoryWriter) BlobCfg() content.BlobCfgBlob {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 content.BlobCfgBlob
|
||||
if rf, ok := ret.Get(0).(func() content.BlobCfgBlob); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(content.BlobCfgBlob)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// BlobReader provides a mock function with given fields:
|
||||
func (_m *DirectRepositoryWriter) BlobReader() blob.Reader {
|
||||
ret := _m.Called()
|
||||
@@ -106,20 +96,6 @@ func (_m *DirectRepositoryWriter) BlobVolume() blob.Volume {
|
||||
return r0
|
||||
}
|
||||
|
||||
// ChangePassword provides a mock function with given fields: ctx, newPassword
|
||||
func (_m *DirectRepositoryWriter) ChangePassword(ctx context.Context, newPassword string) error {
|
||||
ret := _m.Called(ctx, newPassword)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
|
||||
r0 = rf(ctx, newPassword)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// ClientOptions provides a mock function with given fields:
|
||||
func (_m *DirectRepositoryWriter) ClientOptions() repo.ClientOptions {
|
||||
ret := _m.Called()
|
||||
@@ -148,18 +124,28 @@ func (_m *DirectRepositoryWriter) Close(ctx context.Context) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// CommitUpgrade provides a mock function with given fields: ctx
|
||||
func (_m *DirectRepositoryWriter) CommitUpgrade(ctx context.Context) error {
|
||||
ret := _m.Called(ctx)
|
||||
// ConcatenateObjects provides a mock function with given fields: ctx, objectIDs
|
||||
func (_m *DirectRepositoryWriter) ConcatenateObjects(ctx context.Context, objectIDs []object.ID) (object.ID, error) {
|
||||
ret := _m.Called(ctx, objectIDs)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context) error); ok {
|
||||
r0 = rf(ctx)
|
||||
var r0 object.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID) (object.ID, error)); ok {
|
||||
return rf(ctx, objectIDs)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID) object.ID); ok {
|
||||
r0 = rf(ctx, objectIDs)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
r0 = ret.Get(0).(object.ID)
|
||||
}
|
||||
|
||||
return r0
|
||||
if rf, ok := ret.Get(1).(func(context.Context, []object.ID) error); ok {
|
||||
r1 = rf(ctx, objectIDs)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ConfigFilename provides a mock function with given fields:
|
||||
@@ -181,6 +167,10 @@ func (_m *DirectRepositoryWriter) ContentInfo(ctx context.Context, contentID ind
|
||||
ret := _m.Called(ctx, contentID)
|
||||
|
||||
var r0 index.Info
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, index.ID) (index.Info, error)); ok {
|
||||
return rf(ctx, contentID)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, index.ID) index.Info); ok {
|
||||
r0 = rf(ctx, contentID)
|
||||
} else {
|
||||
@@ -189,7 +179,6 @@ func (_m *DirectRepositoryWriter) ContentInfo(ctx context.Context, contentID ind
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, index.ID) error); ok {
|
||||
r1 = rf(ctx, contentID)
|
||||
} else {
|
||||
@@ -231,22 +220,6 @@ func (_m *DirectRepositoryWriter) ContentReader() content.Reader {
|
||||
return r0
|
||||
}
|
||||
|
||||
// Crypter provides a mock function with given fields:
|
||||
func (_m *DirectRepositoryWriter) Crypter() *content.Crypter {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 *content.Crypter
|
||||
if rf, ok := ret.Get(0).(func() *content.Crypter); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*content.Crypter)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteManifest provides a mock function with given fields: ctx, id
|
||||
func (_m *DirectRepositoryWriter) DeleteManifest(ctx context.Context, id manifest.ID) error {
|
||||
ret := _m.Called(ctx, id)
|
||||
@@ -287,6 +260,10 @@ func (_m *DirectRepositoryWriter) FindManifests(ctx context.Context, labels map[
|
||||
ret := _m.Called(ctx, labels)
|
||||
|
||||
var r0 []*manifest.EntryMetadata
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) ([]*manifest.EntryMetadata, error)); ok {
|
||||
return rf(ctx, labels)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) []*manifest.EntryMetadata); ok {
|
||||
r0 = rf(ctx, labels)
|
||||
} else {
|
||||
@@ -295,7 +272,6 @@ func (_m *DirectRepositoryWriter) FindManifests(ctx context.Context, labels map[
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, map[string]string) error); ok {
|
||||
r1 = rf(ctx, labels)
|
||||
} else {
|
||||
@@ -319,11 +295,31 @@ func (_m *DirectRepositoryWriter) Flush(ctx context.Context) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// FormatManager provides a mock function with given fields:
|
||||
func (_m *DirectRepositoryWriter) FormatManager() *format.Manager {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 *format.Manager
|
||||
if rf, ok := ret.Get(0).(func() *format.Manager); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*format.Manager)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetManifest provides a mock function with given fields: ctx, id, data
|
||||
func (_m *DirectRepositoryWriter) GetManifest(ctx context.Context, id manifest.ID, data interface{}) (*manifest.EntryMetadata, error) {
|
||||
ret := _m.Called(ctx, id, data)
|
||||
|
||||
var r0 *manifest.EntryMetadata
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) (*manifest.EntryMetadata, error)); ok {
|
||||
return rf(ctx, id, data)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) *manifest.EntryMetadata); ok {
|
||||
r0 = rf(ctx, id, data)
|
||||
} else {
|
||||
@@ -332,7 +328,6 @@ func (_m *DirectRepositoryWriter) GetManifest(ctx context.Context, id manifest.I
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, manifest.ID, interface{}) error); ok {
|
||||
r1 = rf(ctx, id, data)
|
||||
} else {
|
||||
@@ -343,19 +338,22 @@ func (_m *DirectRepositoryWriter) GetManifest(ctx context.Context, id manifest.I
|
||||
}
|
||||
|
||||
// IndexBlobs provides a mock function with given fields: ctx, includeInactive
|
||||
func (_m *DirectRepositoryWriter) IndexBlobs(ctx context.Context, includeInactive bool) ([]content.IndexBlobInfo, error) {
|
||||
func (_m *DirectRepositoryWriter) IndexBlobs(ctx context.Context, includeInactive bool) ([]indexblob.Metadata, error) {
|
||||
ret := _m.Called(ctx, includeInactive)
|
||||
|
||||
var r0 []content.IndexBlobInfo
|
||||
if rf, ok := ret.Get(0).(func(context.Context, bool) []content.IndexBlobInfo); ok {
|
||||
var r0 []indexblob.Metadata
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, bool) ([]indexblob.Metadata, error)); ok {
|
||||
return rf(ctx, includeInactive)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, bool) []indexblob.Metadata); ok {
|
||||
r0 = rf(ctx, includeInactive)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]content.IndexBlobInfo)
|
||||
r0 = ret.Get(0).([]indexblob.Metadata)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, bool) error); ok {
|
||||
r1 = rf(ctx, includeInactive)
|
||||
} else {
|
||||
@@ -370,6 +368,11 @@ func (_m *DirectRepositoryWriter) NewDirectWriter(ctx context.Context, opt repo.
|
||||
ret := _m.Called(ctx, opt)
|
||||
|
||||
var r0 context.Context
|
||||
var r1 repo.DirectRepositoryWriter
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.DirectRepositoryWriter, error)); ok {
|
||||
return rf(ctx, opt)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
|
||||
r0 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -378,7 +381,6 @@ func (_m *DirectRepositoryWriter) NewDirectWriter(ctx context.Context, opt repo.
|
||||
}
|
||||
}
|
||||
|
||||
var r1 repo.DirectRepositoryWriter
|
||||
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.DirectRepositoryWriter); ok {
|
||||
r1 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -387,7 +389,6 @@ func (_m *DirectRepositoryWriter) NewDirectWriter(ctx context.Context, opt repo.
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
|
||||
r2 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -418,6 +419,11 @@ func (_m *DirectRepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteS
|
||||
ret := _m.Called(ctx, opt)
|
||||
|
||||
var r0 context.Context
|
||||
var r1 repo.RepositoryWriter
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.RepositoryWriter, error)); ok {
|
||||
return rf(ctx, opt)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
|
||||
r0 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -426,7 +432,6 @@ func (_m *DirectRepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteS
|
||||
}
|
||||
}
|
||||
|
||||
var r1 repo.RepositoryWriter
|
||||
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.RepositoryWriter); ok {
|
||||
r1 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -435,7 +440,6 @@ func (_m *DirectRepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteS
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
|
||||
r2 = rf(ctx, opt)
|
||||
} else {
|
||||
@@ -446,24 +450,33 @@ func (_m *DirectRepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteS
|
||||
}
|
||||
|
||||
// ObjectFormat provides a mock function with given fields:
|
||||
func (_m *DirectRepositoryWriter) ObjectFormat() object.Format {
|
||||
func (_m *DirectRepositoryWriter) ObjectFormat() format.ObjectFormat {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 object.Format
|
||||
if rf, ok := ret.Get(0).(func() object.Format); ok {
|
||||
var r0 format.ObjectFormat
|
||||
if rf, ok := ret.Get(0).(func() format.ObjectFormat); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(object.Format)
|
||||
r0 = ret.Get(0).(format.ObjectFormat)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// OnSuccessfulFlush provides a mock function with given fields: callback
|
||||
func (_m *DirectRepositoryWriter) OnSuccessfulFlush(callback repo.RepositoryWriterCallback) {
|
||||
_m.Called(callback)
|
||||
}
|
||||
|
||||
// OpenObject provides a mock function with given fields: ctx, id
|
||||
func (_m *DirectRepositoryWriter) OpenObject(ctx context.Context, id object.ID) (object.Reader, error) {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
var r0 object.Reader
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) (object.Reader, error)); ok {
|
||||
return rf(ctx, id)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) object.Reader); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -472,7 +485,6 @@ func (_m *DirectRepositoryWriter) OpenObject(ctx context.Context, id object.ID)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -503,6 +515,10 @@ func (_m *DirectRepositoryWriter) PrefetchObjects(ctx context.Context, objectIDs
|
||||
ret := _m.Called(ctx, objectIDs, hint)
|
||||
|
||||
var r0 []index.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) ([]index.ID, error)); ok {
|
||||
return rf(ctx, objectIDs, hint)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) []index.ID); ok {
|
||||
r0 = rf(ctx, objectIDs, hint)
|
||||
} else {
|
||||
@@ -511,7 +527,6 @@ func (_m *DirectRepositoryWriter) PrefetchObjects(ctx context.Context, objectIDs
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, []object.ID, string) error); ok {
|
||||
r1 = rf(ctx, objectIDs, hint)
|
||||
} else {
|
||||
@@ -526,13 +541,16 @@ func (_m *DirectRepositoryWriter) PutManifest(ctx context.Context, labels map[st
|
||||
ret := _m.Called(ctx, labels, payload)
|
||||
|
||||
var r0 manifest.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) (manifest.ID, error)); ok {
|
||||
return rf(ctx, labels, payload)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) manifest.ID); ok {
|
||||
r0 = rf(ctx, labels, payload)
|
||||
} else {
|
||||
r0 = ret.Get(0).(manifest.ID)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, map[string]string, interface{}) error); ok {
|
||||
r1 = rf(ctx, labels, payload)
|
||||
} else {
|
||||
@@ -556,50 +574,23 @@ func (_m *DirectRepositoryWriter) Refresh(ctx context.Context) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// RollbackUpgrade provides a mock function with given fields: ctx
|
||||
func (_m *DirectRepositoryWriter) RollbackUpgrade(ctx context.Context) error {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context) error); ok {
|
||||
r0 = rf(ctx)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetParameters provides a mock function with given fields: ctx, m, blobcfg
|
||||
func (_m *DirectRepositoryWriter) SetParameters(ctx context.Context, m content.MutableParameters, blobcfg content.BlobCfgBlob) error {
|
||||
ret := _m.Called(ctx, m, blobcfg)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, content.MutableParameters, content.BlobCfgBlob) error); ok {
|
||||
r0 = rf(ctx, m, blobcfg)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetUpgradeLockIntent provides a mock function with given fields: ctx, l
|
||||
func (_m *DirectRepositoryWriter) SetUpgradeLockIntent(ctx context.Context, l content.UpgradeLock) (*content.UpgradeLock, error) {
|
||||
ret := _m.Called(ctx, l)
|
||||
|
||||
var r0 *content.UpgradeLock
|
||||
if rf, ok := ret.Get(0).(func(context.Context, content.UpgradeLock) *content.UpgradeLock); ok {
|
||||
r0 = rf(ctx, l)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*content.UpgradeLock)
|
||||
}
|
||||
}
|
||||
// ReplaceManifests provides a mock function with given fields: ctx, labels, payload
|
||||
func (_m *DirectRepositoryWriter) ReplaceManifests(ctx context.Context, labels map[string]string, payload interface{}) (manifest.ID, error) {
|
||||
ret := _m.Called(ctx, labels, payload)
|
||||
|
||||
var r0 manifest.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, content.UpgradeLock) error); ok {
|
||||
r1 = rf(ctx, l)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) (manifest.ID, error)); ok {
|
||||
return rf(ctx, labels, payload)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) manifest.ID); ok {
|
||||
r0 = rf(ctx, labels, payload)
|
||||
} else {
|
||||
r0 = ret.Get(0).(manifest.ID)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, map[string]string, interface{}) error); ok {
|
||||
r1 = rf(ctx, labels, payload)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -642,13 +633,16 @@ func (_m *DirectRepositoryWriter) Token(password string) (string, error) {
|
||||
ret := _m.Called(password)
|
||||
|
||||
var r0 string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(string) (string, error)); ok {
|
||||
return rf(password)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(string) string); ok {
|
||||
r0 = rf(password)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(password)
|
||||
} else {
|
||||
@@ -684,6 +678,10 @@ func (_m *DirectRepositoryWriter) VerifyObject(ctx context.Context, id object.ID
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
var r0 []index.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) ([]index.ID, error)); ok {
|
||||
return rf(ctx, id)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, object.ID) []index.ID); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
@@ -692,7 +690,6 @@ func (_m *DirectRepositoryWriter) VerifyObject(ctx context.Context, id object.ID
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
|
||||
@@ -1,62 +1,99 @@
|
||||
// Code generated by mockery v2.14.0. DO NOT EDIT.
|
||||
// Code generated by mockery v2.22.1. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
zapcore "go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// Logger is an autogenerated mock type for the Logger type
|
||||
type Logger struct {
|
||||
// Core is an autogenerated mock type for the Core type
|
||||
type Core struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Debugf provides a mock function with given fields: msg, args
|
||||
func (_m *Logger) Debugf(msg string, args ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, msg)
|
||||
_ca = append(_ca, args...)
|
||||
_m.Called(_ca...)
|
||||
// Check provides a mock function with given fields: _a0, _a1
|
||||
func (_m *Core) Check(_a0 zapcore.Entry, _a1 *zapcore.CheckedEntry) *zapcore.CheckedEntry {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
var r0 *zapcore.CheckedEntry
|
||||
if rf, ok := ret.Get(0).(func(zapcore.Entry, *zapcore.CheckedEntry) *zapcore.CheckedEntry); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*zapcore.CheckedEntry)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Debugw provides a mock function with given fields: msg, keyValuePairs
|
||||
func (_m *Logger) Debugw(msg string, keyValuePairs ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, msg)
|
||||
_ca = append(_ca, keyValuePairs...)
|
||||
_m.Called(_ca...)
|
||||
// Enabled provides a mock function with given fields: _a0
|
||||
func (_m *Core) Enabled(_a0 zapcore.Level) bool {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(zapcore.Level) bool); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Errorf provides a mock function with given fields: msg, args
|
||||
func (_m *Logger) Errorf(msg string, args ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, msg)
|
||||
_ca = append(_ca, args...)
|
||||
_m.Called(_ca...)
|
||||
// Sync provides a mock function with given fields:
|
||||
func (_m *Core) Sync() error {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Infof provides a mock function with given fields: msg, args
|
||||
func (_m *Logger) Infof(msg string, args ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, msg)
|
||||
_ca = append(_ca, args...)
|
||||
_m.Called(_ca...)
|
||||
// With provides a mock function with given fields: _a0
|
||||
func (_m *Core) With(_a0 []zapcore.Field) zapcore.Core {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 zapcore.Core
|
||||
if rf, ok := ret.Get(0).(func([]zapcore.Field) zapcore.Core); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(zapcore.Core)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Warnf provides a mock function with given fields: msg, args
|
||||
func (_m *Logger) Warnf(msg string, args ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, msg)
|
||||
_ca = append(_ca, args...)
|
||||
_m.Called(_ca...)
|
||||
// Write provides a mock function with given fields: _a0, _a1
|
||||
func (_m *Core) Write(_a0 zapcore.Entry, _a1 []zapcore.Field) error {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(zapcore.Entry, []zapcore.Field) error); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewLogger interface {
|
||||
type mockConstructorTestingTNewCore interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewLogger creates a new instance of Logger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewLogger(t mockConstructorTestingTNewLogger) *Logger {
|
||||
mock := &Logger{}
|
||||
// NewCore creates a new instance of Core. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewCore(t mockConstructorTestingTNewCore) *Core {
|
||||
mock := &Core{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
@@ -52,6 +52,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)
|
||||
|
||||
@@ -59,5 +60,5 @@ func (c *S3Backend) Setup(ctx context.Context, flags map[string]string) error {
|
||||
}
|
||||
|
||||
func (c *S3Backend) Connect(ctx context.Context, isCreate bool) (blob.Storage, error) {
|
||||
return s3.New(ctx, &c.options)
|
||||
return s3.New(ctx, &c.options, false)
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -18,12 +18,13 @@ package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/kopia/kopia/repo/logging"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
storagemocks "github.com/vmware-tanzu/velero/pkg/repository/udmrepo/kopialib/backend/mocks"
|
||||
)
|
||||
@@ -31,13 +32,13 @@ import (
|
||||
func TestOptionalHaveBool(t *testing.T) {
|
||||
var expectMsg string
|
||||
testCases := []struct {
|
||||
name string
|
||||
key string
|
||||
flags map[string]string
|
||||
logger *storagemocks.Logger
|
||||
retFuncErrorf func(mock.Arguments)
|
||||
expectMsg string
|
||||
retValue bool
|
||||
name string
|
||||
key string
|
||||
flags map[string]string
|
||||
logger *storagemocks.Core
|
||||
retFuncCheck func(mock.Arguments)
|
||||
expectMsg string
|
||||
retValue bool
|
||||
}{
|
||||
{
|
||||
name: "key not exist",
|
||||
@@ -59,9 +60,12 @@ func TestOptionalHaveBool(t *testing.T) {
|
||||
flags: map[string]string{
|
||||
"fake-key": "fake-value",
|
||||
},
|
||||
logger: new(storagemocks.Logger),
|
||||
retFuncErrorf: func(args mock.Arguments) {
|
||||
expectMsg = fmt.Sprintf(args[0].(string), args[1].(string), args[2].(string), args[3].(error))
|
||||
logger: new(storagemocks.Core),
|
||||
retFuncCheck: func(args mock.Arguments) {
|
||||
ent := args[0].(zapcore.Entry)
|
||||
if ent.Level == zapcore.ErrorLevel {
|
||||
expectMsg = ent.Message
|
||||
}
|
||||
},
|
||||
expectMsg: "Ignore fake-key, value [fake-value] is invalid, err strconv.ParseBool: parsing \"fake-value\": invalid syntax",
|
||||
retValue: false,
|
||||
@@ -71,11 +75,12 @@ func TestOptionalHaveBool(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.logger != nil {
|
||||
tc.logger.On("Errorf", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Run(tc.retFuncErrorf)
|
||||
tc.logger.On("Enabled", mock.Anything).Return(true)
|
||||
tc.logger.On("Check", mock.Anything, mock.Anything).Run(tc.retFuncCheck).Return(&zapcore.CheckedEntry{})
|
||||
}
|
||||
|
||||
ctx := logging.WithLogger(context.Background(), func(module string) logging.Logger {
|
||||
return tc.logger
|
||||
return zap.New(tc.logger).Sugar()
|
||||
})
|
||||
|
||||
retValue := optionalHaveBool(ctx, tc.key, tc.flags)
|
||||
|
||||
@@ -19,7 +19,6 @@ package kopialib
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@@ -234,7 +233,12 @@ func (kr *kopiaRepository) OpenObject(ctx context.Context, id udmrepo.ID) (udmre
|
||||
return nil, errors.New("repo is closed or not open")
|
||||
}
|
||||
|
||||
reader, err := kr.rawRepo.OpenObject(logging.SetupKopiaLog(ctx, kr.logger), object.ID(id))
|
||||
objID, err := object.ParseID(string(id))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error to parse object ID from %v", id)
|
||||
}
|
||||
|
||||
reader, err := kr.rawRepo.OpenObject(logging.SetupKopiaLog(ctx, kr.logger), objID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error to open object")
|
||||
}
|
||||
@@ -309,8 +313,8 @@ func (kr *kopiaRepository) NewObjectWriter(ctx context.Context, opt udmrepo.Obje
|
||||
|
||||
writer := kr.rawWriter.NewObjectWriter(logging.SetupKopiaLog(ctx, kr.logger), object.WriterOptions{
|
||||
Description: opt.Description,
|
||||
Prefix: index.ID(opt.Prefix),
|
||||
AsyncWrites: getAsyncWrites(),
|
||||
Prefix: index.IDPrefix(opt.Prefix),
|
||||
AsyncWrites: opt.AsyncWrites,
|
||||
Compressor: getCompressorForObject(opt),
|
||||
})
|
||||
|
||||
@@ -438,7 +442,7 @@ func (kow *kopiaObjectWriter) Checkpoint() (udmrepo.ID, error) {
|
||||
return udmrepo.ID(""), errors.Wrap(err, "error to checkpoint object")
|
||||
}
|
||||
|
||||
return udmrepo.ID(id), nil
|
||||
return udmrepo.ID(id.String()), nil
|
||||
}
|
||||
|
||||
func (kow *kopiaObjectWriter) Result() (udmrepo.ID, error) {
|
||||
@@ -451,7 +455,7 @@ func (kow *kopiaObjectWriter) Result() (udmrepo.ID, error) {
|
||||
return udmrepo.ID(""), errors.Wrap(err, "error to wait object")
|
||||
}
|
||||
|
||||
return udmrepo.ID(id), nil
|
||||
return udmrepo.ID(id.String()), nil
|
||||
}
|
||||
|
||||
func (kow *kopiaObjectWriter) Close() error {
|
||||
@@ -469,11 +473,6 @@ func (kow *kopiaObjectWriter) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// getAsyncWrites returns the number of concurrent async writes
|
||||
func getAsyncWrites() int {
|
||||
return runtime.NumCPU()
|
||||
}
|
||||
|
||||
// getCompressorForObject returns the compressor for an object, at present, we don't support compression
|
||||
func getCompressorForObject(opt udmrepo.ObjectWriteOptions) compression.Name {
|
||||
return ""
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/kopia/kopia/repo"
|
||||
"github.com/kopia/kopia/repo/manifest"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
@@ -262,14 +263,14 @@ func TestMaintain(t *testing.T) {
|
||||
func TestWriteInitParameters(t *testing.T) {
|
||||
var directRpo *repomocks.DirectRepository
|
||||
testCases := []struct {
|
||||
name string
|
||||
repoOptions udmrepo.RepoOptions
|
||||
returnRepo *repomocks.DirectRepository
|
||||
returnRepoWriter *repomocks.DirectRepositoryWriter
|
||||
repoOpen func(context.Context, string, string, *repo.Options) (repo.Repository, error)
|
||||
newRepoWriterError error
|
||||
findManifestError error
|
||||
expectedErr string
|
||||
name string
|
||||
repoOptions udmrepo.RepoOptions
|
||||
returnRepo *repomocks.DirectRepository
|
||||
returnRepoWriter *repomocks.DirectRepositoryWriter
|
||||
repoOpen func(context.Context, string, string, *repo.Options) (repo.Repository, error)
|
||||
newRepoWriterError error
|
||||
replaceManifestError error
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "repo open fail, repo not exist",
|
||||
@@ -315,10 +316,10 @@ func TestWriteInitParameters(t *testing.T) {
|
||||
repoOpen: func(context.Context, string, string, *repo.Options) (repo.Repository, error) {
|
||||
return directRpo, nil
|
||||
},
|
||||
returnRepo: new(repomocks.DirectRepository),
|
||||
returnRepoWriter: new(repomocks.DirectRepositoryWriter),
|
||||
findManifestError: errors.New("fake-find-manifest-error"),
|
||||
expectedErr: "error to init write repo parameters: error to set maintenance params: error looking for maintenance manifest: fake-find-manifest-error",
|
||||
returnRepo: new(repomocks.DirectRepository),
|
||||
returnRepoWriter: new(repomocks.DirectRepositoryWriter),
|
||||
replaceManifestError: errors.New("fake-replace-manifest-error"),
|
||||
expectedErr: "error to init write repo parameters: error to set maintenance params: put manifest: fake-replace-manifest-error",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -343,7 +344,7 @@ func TestWriteInitParameters(t *testing.T) {
|
||||
|
||||
if tc.returnRepoWriter != nil {
|
||||
tc.returnRepoWriter.On("Close", mock.Anything).Return(nil)
|
||||
tc.returnRepoWriter.On("FindManifests", mock.Anything, mock.Anything).Return(nil, tc.findManifestError)
|
||||
tc.returnRepoWriter.On("ReplaceManifests", mock.Anything, mock.Anything, mock.Anything).Return(manifest.ID(""), tc.replaceManifestError)
|
||||
}
|
||||
|
||||
err := writeInitParameters(ctx, tc.repoOptions, logger)
|
||||
|
||||
@@ -68,6 +68,7 @@ type ObjectWriteOptions struct {
|
||||
Prefix ID // A prefix of the name used to save the object
|
||||
AccessMode int // OBJECT_DATA_ACCESS_*
|
||||
BackupMode int // OBJECT_DATA_BACKUP_*
|
||||
AsyncWrites int // Num of async writes for the object, 0 means no async write
|
||||
}
|
||||
|
||||
// BackupRepoService is used to initialize, open or maintain a backup repository
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -140,7 +140,7 @@ func (p *ChangePVCNodeSelectorAction) Execute(input *velero.RestoreItemActionExe
|
||||
|
||||
func getNewNodeFromConfigMap(client corev1client.ConfigMapInterface, node string) (string, error) {
|
||||
// fetch node mapping from configMap
|
||||
config, err := getPluginConfig(common.PluginKindRestoreItemAction, "velero.io/change-pvc-node-selector", client)
|
||||
config, err := common.GetPluginConfig(common.PluginKindRestoreItemAction, "velero.io/change-pvc-node-selector", client)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -69,7 +69,7 @@ func (a *ChangeStorageClassAction) Execute(input *velero.RestoreItemActionExecut
|
||||
defer a.logger.Info("Done executing ChangeStorageClassAction")
|
||||
|
||||
a.logger.Debug("Getting plugin config")
|
||||
config, err := getPluginConfig(common.PluginKindRestoreItemAction, "velero.io/change-storage-class", a.configMapClient)
|
||||
config, err := common.GetPluginConfig(common.PluginKindRestoreItemAction, "velero.io/change-storage-class", a.configMapClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
@@ -108,7 +107,7 @@ func (a *PodVolumeRestoreAction) Execute(input *velero.RestoreItemActionExecuteI
|
||||
// TODO we might want/need to get plugin config at the top of this method at some point; for now, wait
|
||||
// until we know we're doing a restore before getting config.
|
||||
log.Debugf("Getting plugin config")
|
||||
config, err := getPluginConfig(common.PluginKindRestoreItemAction, "velero.io/pod-volume-restore", a.client)
|
||||
config, err := common.GetPluginConfig(common.PluginKindRestoreItemAction, "velero.io/pod-volume-restore", a.client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -259,35 +258,6 @@ func getSecurityContext(log logrus.FieldLogger, config *corev1.ConfigMap) (strin
|
||||
config.Data["secCtx"]
|
||||
}
|
||||
|
||||
// TODO eventually this can move to pkg/plugin/framework since it'll be used across multiple
|
||||
// plugins.
|
||||
func getPluginConfig(kind common.PluginKind, name string, client corev1client.ConfigMapInterface) (*corev1.ConfigMap, error) {
|
||||
opts := metav1.ListOptions{
|
||||
// velero.io/plugin-config: true
|
||||
// velero.io/pod-volume-restore: RestoreItemAction
|
||||
LabelSelector: fmt.Sprintf("velero.io/plugin-config,%s=%s", name, kind),
|
||||
}
|
||||
|
||||
list, err := client.List(context.TODO(), opts)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if len(list.Items) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if len(list.Items) > 1 {
|
||||
var items []string
|
||||
for _, item := range list.Items {
|
||||
items = append(items, item.Name)
|
||||
}
|
||||
return nil, errors.Errorf("found more than one ConfigMap matching label selector %q: %v", opts.LabelSelector, items)
|
||||
}
|
||||
|
||||
return &list.Items[0], nil
|
||||
}
|
||||
|
||||
func newRestoreInitContainerBuilder(image, restoreUID string) *builder.ContainerBuilder {
|
||||
return builder.ForContainer(restorehelper.WaitInitContainer, image).
|
||||
Args(restoreUID).
|
||||
|
||||
@@ -401,7 +401,11 @@ func (ctx *restoreContext) execute() (results.Result, results.Result) {
|
||||
errs.AddVeleroError(err)
|
||||
return warnings, errs
|
||||
}
|
||||
defer ctx.fileSystem.RemoveAll(dir)
|
||||
defer func() {
|
||||
if err := ctx.fileSystem.RemoveAll(dir); err != nil {
|
||||
ctx.log.Errorf("error removing temporary directory %s: %s", dir, err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
// Need to set this for additionalItems to be restored.
|
||||
ctx.restoreDir = dir
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -81,7 +81,7 @@ func (fs *FakeFileSystem) Stat(path string) (os.FileInfo, error) {
|
||||
|
||||
func (fs *FakeFileSystem) WithFile(path string, data []byte) *FakeFileSystem {
|
||||
file, _ := fs.fs.Create(path)
|
||||
file.Write(data)
|
||||
_, _ = file.Write(data)
|
||||
file.Close()
|
||||
|
||||
return fs
|
||||
@@ -89,14 +89,14 @@ func (fs *FakeFileSystem) WithFile(path string, data []byte) *FakeFileSystem {
|
||||
|
||||
func (fs *FakeFileSystem) WithFileAndMode(path string, data []byte, mode os.FileMode) *FakeFileSystem {
|
||||
file, _ := fs.fs.OpenFile(path, os.O_CREATE|os.O_RDWR, mode)
|
||||
file.Write(data)
|
||||
_, _ = file.Write(data)
|
||||
file.Close()
|
||||
|
||||
return fs
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) WithDirectory(path string) *FakeFileSystem {
|
||||
fs.fs.MkdirAll(path, 0755)
|
||||
_ = fs.fs.MkdirAll(path, 0755)
|
||||
return fs
|
||||
}
|
||||
|
||||
|
||||
@@ -27,3 +27,10 @@ func NewLogger() logrus.FieldLogger {
|
||||
logger.Out = io.Discard
|
||||
return logrus.NewEntry(logger)
|
||||
}
|
||||
|
||||
func NewLoggerWithLevel(level logrus.Level) logrus.FieldLogger {
|
||||
logger := logrus.New()
|
||||
logger.Out = io.Discard
|
||||
logger.Level = level
|
||||
return logrus.NewEntry(logger)
|
||||
}
|
||||
|
||||
@@ -151,3 +151,5 @@ func (p *Progress) ProgressBytes(processedBytes int64, totalBytes int64) {
|
||||
atomic.StoreInt64(&p.estimatedTotalBytes, totalBytes)
|
||||
p.UpdateProgress()
|
||||
}
|
||||
|
||||
func (p *Progress) FinishedFile(fname string, err error) {}
|
||||
|
||||
@@ -55,7 +55,7 @@ func NewShimRepo(repo udmrepo.BackupRepo) repo.RepositoryWriter {
|
||||
|
||||
// OpenObject open specific object
|
||||
func (sr *shimRepository) OpenObject(ctx context.Context, id object.ID) (object.Reader, error) {
|
||||
reader, err := sr.udmRepo.OpenObject(ctx, udmrepo.ID(id))
|
||||
reader, err := sr.udmRepo.OpenObject(ctx, udmrepo.ID(id.String()))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to open object with id %v", id)
|
||||
}
|
||||
@@ -70,7 +70,7 @@ func (sr *shimRepository) OpenObject(ctx context.Context, id object.ID) (object.
|
||||
|
||||
// VerifyObject not supported
|
||||
func (sr *shimRepository) VerifyObject(ctx context.Context, id object.ID) ([]content.ID, error) {
|
||||
return nil, errors.New("not supported")
|
||||
return nil, errors.New("VerifyObject is not supported")
|
||||
}
|
||||
|
||||
// Get one or more manifest data that match the specific manifest id
|
||||
@@ -135,12 +135,12 @@ func (sr *shimRepository) ClientOptions() repo.ClientOptions {
|
||||
|
||||
// Refresh not supported
|
||||
func (sr *shimRepository) Refresh(ctx context.Context) error {
|
||||
return errors.New("not supported")
|
||||
return errors.New("Refresh is not supported")
|
||||
}
|
||||
|
||||
// ContentInfo not supported
|
||||
func (sr *shimRepository) ContentInfo(ctx context.Context, contentID content.ID) (content.Info, error) {
|
||||
return nil, errors.New("not supported")
|
||||
return nil, errors.New("ContentInfo is not supported")
|
||||
}
|
||||
|
||||
// PrefetchContents is not supported by unified repo
|
||||
@@ -150,7 +150,7 @@ func (sr *shimRepository) PrefetchContents(ctx context.Context, contentIDs []con
|
||||
|
||||
// PrefetchObjects is not supported by unified repo
|
||||
func (sr *shimRepository) PrefetchObjects(ctx context.Context, objectIDs []object.ID, hint string) ([]content.ID, error) {
|
||||
return nil, errors.New("not supported")
|
||||
return nil, errors.New("PrefetchObjects is not supported")
|
||||
}
|
||||
|
||||
// UpdateDescription is not supported by unified repo
|
||||
@@ -159,7 +159,7 @@ func (sr *shimRepository) UpdateDescription(d string) {
|
||||
|
||||
// NewWriter is not supported by unified repo
|
||||
func (sr *shimRepository) NewWriter(ctx context.Context, option repo.WriteSessionOptions) (context.Context, repo.RepositoryWriter, error) {
|
||||
return nil, nil, errors.New("not supported")
|
||||
return nil, nil, errors.New("NewWriter is not supported")
|
||||
}
|
||||
|
||||
// Close will close unified repo
|
||||
@@ -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
|
||||
@@ -208,11 +209,22 @@ func (sr *shimRepository) DeleteManifest(ctx context.Context, id manifest.ID) er
|
||||
return sr.udmRepo.DeleteManifest(ctx, udmrepo.ID(id))
|
||||
}
|
||||
|
||||
func (sr *shimRepository) ReplaceManifests(ctx context.Context, labels map[string]string, payload interface{}) (manifest.ID, error) {
|
||||
return manifest.ID(""), errors.New("ReplaceManifests is not supported")
|
||||
}
|
||||
|
||||
// Flush all the unifited repository data
|
||||
func (sr *shimRepository) Flush(ctx context.Context) error {
|
||||
return sr.udmRepo.Flush(ctx)
|
||||
}
|
||||
|
||||
func (sr *shimRepository) ConcatenateObjects(ctx context.Context, objectIDs []object.ID) (object.ID, error) {
|
||||
return object.ID{}, errors.New("ConcatenateObjects is not supported")
|
||||
}
|
||||
|
||||
func (sr *shimRepository) OnSuccessfulFlush(callback repo.RepositoryWriterCallback) {
|
||||
}
|
||||
|
||||
// Flush all the unifited repository data
|
||||
func (sr *shimObjectReader) Read(p []byte) (n int, err error) {
|
||||
return sr.repoReader.Read(p)
|
||||
@@ -240,13 +252,31 @@ func (sr *shimObjectWriter) Write(p []byte) (n int, err error) {
|
||||
// Periodically called to preserve the state of data written to the repo so far.
|
||||
func (sr *shimObjectWriter) Checkpoint() (object.ID, error) {
|
||||
id, err := sr.repoWriter.Checkpoint()
|
||||
return object.ID(id), err
|
||||
if err != nil {
|
||||
return object.ID{}, err
|
||||
}
|
||||
|
||||
objID, err := object.ParseID(string(id))
|
||||
if err != nil {
|
||||
return object.ID{}, errors.Wrapf(err, "error to parse object ID from %v", id)
|
||||
}
|
||||
|
||||
return objID, err
|
||||
}
|
||||
|
||||
// Result returns the object's unified identifier after the write completes.
|
||||
func (sr *shimObjectWriter) Result() (object.ID, error) {
|
||||
id, err := sr.repoWriter.Result()
|
||||
return object.ID(id), err
|
||||
if err != nil {
|
||||
return object.ID{}, err
|
||||
}
|
||||
|
||||
objID, err := object.ParseID(string(id))
|
||||
if err != nil {
|
||||
return object.ID{}, errors.Wrapf(err, "error to parse object ID from %v", id)
|
||||
}
|
||||
|
||||
return objID, err
|
||||
}
|
||||
|
||||
// Close closes the repository and releases all resources.
|
||||
|
||||
@@ -44,9 +44,7 @@ import (
|
||||
)
|
||||
|
||||
// All function mainly used to make testing more convenient
|
||||
var treeForSourceFunc = policy.TreeForSource
|
||||
var applyRetentionPolicyFunc = policy.ApplyRetentionPolicy
|
||||
var setPolicyFunc = policy.SetPolicy
|
||||
var saveSnapshotFunc = snapshot.SaveSnapshot
|
||||
var loadSnapshotFunc = snapshot.LoadSnapshot
|
||||
|
||||
@@ -72,24 +70,17 @@ func newOptionalBool(b bool) *policy.OptionalBool {
|
||||
}
|
||||
|
||||
// setupDefaultPolicy set default policy for kopia
|
||||
func setupDefaultPolicy(ctx context.Context, rep repo.RepositoryWriter, sourceInfo snapshot.SourceInfo) error {
|
||||
return setPolicyFunc(ctx, rep, sourceInfo, &policy.Policy{
|
||||
RetentionPolicy: policy.RetentionPolicy{
|
||||
KeepLatest: newOptionalInt(math.MaxInt32),
|
||||
},
|
||||
CompressionPolicy: policy.CompressionPolicy{
|
||||
CompressorName: "none",
|
||||
},
|
||||
UploadPolicy: policy.UploadPolicy{
|
||||
MaxParallelFileReads: newOptionalInt(runtime.NumCPU()),
|
||||
},
|
||||
SchedulingPolicy: policy.SchedulingPolicy{
|
||||
Manual: true,
|
||||
},
|
||||
ErrorHandlingPolicy: policy.ErrorHandlingPolicy{
|
||||
IgnoreUnknownTypes: newOptionalBool(true),
|
||||
},
|
||||
})
|
||||
func setupDefaultPolicy() *policy.Tree {
|
||||
defaultPolicy := *policy.DefaultPolicy
|
||||
|
||||
defaultPolicy.RetentionPolicy.KeepLatest = newOptionalInt(math.MaxInt32)
|
||||
defaultPolicy.CompressionPolicy.CompressorName = "none"
|
||||
defaultPolicy.UploadPolicy.MaxParallelFileReads = newOptionalInt(runtime.NumCPU())
|
||||
defaultPolicy.UploadPolicy.ParallelUploadAboveSize = nil
|
||||
defaultPolicy.SchedulingPolicy.Manual = true
|
||||
defaultPolicy.ErrorHandlingPolicy.IgnoreUnknownTypes = newOptionalBool(true)
|
||||
|
||||
return policy.BuildTree(nil, &defaultPolicy)
|
||||
}
|
||||
|
||||
// Backup backup specific sourcePath and update progress
|
||||
@@ -198,17 +189,9 @@ func SnapshotSource(
|
||||
}
|
||||
}
|
||||
|
||||
var manifest *snapshot.Manifest
|
||||
if err := setupDefaultPolicy(ctx, rep, sourceInfo); err != nil {
|
||||
return "", 0, errors.Wrapf(err, "unable to set policy for si %v", sourceInfo)
|
||||
}
|
||||
policyTree := setupDefaultPolicy()
|
||||
|
||||
policyTree, err := treeForSourceFunc(ctx, rep, sourceInfo)
|
||||
if err != nil {
|
||||
return "", 0, errors.Wrapf(err, "unable to create policy getter for si %v", sourceInfo)
|
||||
}
|
||||
|
||||
manifest, err = u.Upload(ctx, rootDir, policyTree, sourceInfo, previous...)
|
||||
manifest, err := u.Upload(ctx, rootDir, policyTree, sourceInfo, previous...)
|
||||
if err != nil {
|
||||
return "", 0, errors.Wrapf(err, "Failed to upload the kopia snapshot for si %v", sourceInfo)
|
||||
}
|
||||
@@ -254,7 +237,7 @@ func reportSnapshotStatus(manifest *snapshot.Manifest, policyTree *policy.Tree)
|
||||
|
||||
// findPreviousSnapshotManifest returns the list of previous snapshots for a given source, including
|
||||
// last complete snapshot following it.
|
||||
func findPreviousSnapshotManifest(ctx context.Context, rep repo.Repository, sourceInfo snapshot.SourceInfo, snapshotTags map[string]string, noLaterThan *time.Time) ([]*snapshot.Manifest, error) {
|
||||
func findPreviousSnapshotManifest(ctx context.Context, rep repo.Repository, sourceInfo snapshot.SourceInfo, snapshotTags map[string]string, noLaterThan *fs.UTCTimestamp) ([]*snapshot.Manifest, error) {
|
||||
man, err := snapshot.ListSnapshots(ctx, rep, sourceInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -313,6 +296,11 @@ func Restore(ctx context.Context, rep repo.RepositoryWriter, progress *Progress,
|
||||
IgnorePermissionErrors: true,
|
||||
}
|
||||
|
||||
err = output.Init(ctx)
|
||||
if err != nil {
|
||||
return 0, 0, errors.Wrap(err, "error to init output")
|
||||
}
|
||||
|
||||
stat, err := restore.Entry(kopiaCtx, rep, output, rootEntry, restore.Options{
|
||||
Parallel: runtime.NumCPU(),
|
||||
RestoreDirEntryAtDepth: math.MaxInt32,
|
||||
|
||||
@@ -50,8 +50,6 @@ func injectSnapshotFuncs() *snapshotMockes {
|
||||
repoWriterMock: &repomocks.RepositoryWriter{},
|
||||
}
|
||||
|
||||
setPolicyFunc = s.policyMock.SetPolicy
|
||||
treeForSourceFunc = s.policyMock.TreeForSource
|
||||
applyRetentionPolicyFunc = s.policyMock.ApplyRetentionPolicy
|
||||
loadSnapshotFunc = s.snapshotMock.LoadSnapshot
|
||||
saveSnapshotFunc = s.snapshotMock.SaveSnapshot
|
||||
@@ -141,19 +139,6 @@ func TestSnapshotSource(t *testing.T) {
|
||||
},
|
||||
notError: false,
|
||||
},
|
||||
{
|
||||
name: "failed to set policy",
|
||||
args: []mockArgs{
|
||||
{methodName: "LoadSnapshot", returns: []interface{}{manifest, nil}},
|
||||
{methodName: "SaveSnapshot", returns: []interface{}{manifest.ID, nil}},
|
||||
{methodName: "TreeForSource", returns: []interface{}{nil, nil}},
|
||||
{methodName: "ApplyRetentionPolicy", returns: []interface{}{nil, nil}},
|
||||
{methodName: "SetPolicy", returns: []interface{}{errors.New("failed to set policy")}},
|
||||
{methodName: "Upload", returns: []interface{}{manifest, nil}},
|
||||
{methodName: "Flush", returns: []interface{}{nil}},
|
||||
},
|
||||
notError: false,
|
||||
},
|
||||
{
|
||||
name: "failed to upload snapshot",
|
||||
args: []mockArgs{
|
||||
|
||||
+106
-34
@@ -21,6 +21,8 @@ import (
|
||||
|
||||
"github.com/kopia/kopia/repo/logging"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
type kopiaLog struct {
|
||||
@@ -32,59 +34,129 @@ type kopiaLog struct {
|
||||
// call the logger in the context to write logs
|
||||
func SetupKopiaLog(ctx context.Context, logger logrus.FieldLogger) context.Context {
|
||||
return logging.WithLogger(ctx, func(module string) logging.Logger {
|
||||
return &kopiaLog{
|
||||
module: module,
|
||||
logger: logger,
|
||||
}
|
||||
kpLog := &kopiaLog{module, logger}
|
||||
return zap.New(kpLog).Sugar()
|
||||
})
|
||||
}
|
||||
|
||||
func (kl *kopiaLog) Debugf(msg string, args ...interface{}) {
|
||||
logger := kl.logger.WithField("logModule", kl.getLogModule())
|
||||
logger.Debugf(msg, args...)
|
||||
// Enabled decides whether a given logging level is enabled when logging a message
|
||||
func (kl *kopiaLog) Enabled(level zapcore.Level) bool {
|
||||
entry := kl.logger.WithField("null", "null")
|
||||
switch level {
|
||||
case zapcore.DebugLevel:
|
||||
return (entry.Logger.GetLevel() >= logrus.DebugLevel)
|
||||
case zapcore.InfoLevel:
|
||||
return (entry.Logger.GetLevel() >= logrus.InfoLevel)
|
||||
case zapcore.WarnLevel:
|
||||
return (entry.Logger.GetLevel() >= logrus.WarnLevel)
|
||||
case zapcore.ErrorLevel:
|
||||
return (entry.Logger.GetLevel() >= logrus.ErrorLevel)
|
||||
case zapcore.DPanicLevel:
|
||||
return (entry.Logger.GetLevel() >= logrus.PanicLevel)
|
||||
case zapcore.PanicLevel:
|
||||
return (entry.Logger.GetLevel() >= logrus.PanicLevel)
|
||||
case zapcore.FatalLevel:
|
||||
return (entry.Logger.GetLevel() >= logrus.FatalLevel)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (kl *kopiaLog) Debugw(msg string, keyValuePairs ...interface{}) {
|
||||
logger := kl.logger.WithField("logModule", kl.getLogModule())
|
||||
logger.WithFields(getLogFields(keyValuePairs...)).Debug(msg)
|
||||
// With adds structured context to the Core.
|
||||
func (kl *kopiaLog) With(fields []zapcore.Field) zapcore.Core {
|
||||
copied := kl.logrusFields(fields)
|
||||
|
||||
return &kopiaLog{
|
||||
module: kl.module,
|
||||
logger: kl.logger.WithFields(copied),
|
||||
}
|
||||
}
|
||||
|
||||
func (kl *kopiaLog) Infof(msg string, args ...interface{}) {
|
||||
logger := kl.logger.WithField("logModule", kl.getLogModule())
|
||||
logger.Infof(msg, args...)
|
||||
// Check determines whether the supplied Entry should be logged. If the entry
|
||||
// should be logged, the Core adds itself to the CheckedEntry and returns the result.
|
||||
func (kl *kopiaLog) Check(ent zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry {
|
||||
if kl.Enabled(ent.Level) {
|
||||
return ce.AddCore(ent, kl)
|
||||
}
|
||||
|
||||
return ce
|
||||
}
|
||||
|
||||
func (kl *kopiaLog) Warnf(msg string, args ...interface{}) {
|
||||
logger := kl.logger.WithField("logModule", kl.getLogModule())
|
||||
logger.Warnf(msg, args...)
|
||||
// Write serializes the Entry and any Fields supplied at the log site and writes them to their destination.
|
||||
func (kl *kopiaLog) Write(ent zapcore.Entry, fields []zapcore.Field) error {
|
||||
copied := kl.logrusFieldsForWrite(ent, fields)
|
||||
logger := kl.logger.WithFields(copied)
|
||||
|
||||
switch ent.Level {
|
||||
case zapcore.DebugLevel:
|
||||
logger.Debug(ent.Message)
|
||||
case zapcore.InfoLevel:
|
||||
logger.Info(ent.Message)
|
||||
case zapcore.WarnLevel:
|
||||
logger.Warn(ent.Message)
|
||||
case zapcore.ErrorLevel:
|
||||
// We see Kopia generates error logs for some normal cases or non-critical
|
||||
// cases. So Kopia's error logs are regarded as warning logs so that they don't
|
||||
// affect Velero's workflow.
|
||||
logger.Warn(ent.Message)
|
||||
case zapcore.DPanicLevel:
|
||||
logger.Panic(ent.Message)
|
||||
case zapcore.PanicLevel:
|
||||
logger.Panic(ent.Message)
|
||||
case zapcore.FatalLevel:
|
||||
logger.Fatal(ent.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// We see Kopia generates error logs for some normal cases or non-critical
|
||||
// cases. So Kopia's error logs are regarded as warning logs so that they don't
|
||||
// affect Velero's workflow.
|
||||
func (kl *kopiaLog) Errorf(msg string, args ...interface{}) {
|
||||
logger := kl.logger.WithFields(logrus.Fields{
|
||||
"logModule": kl.getLogModule(),
|
||||
"sublevel": "error",
|
||||
})
|
||||
// Sync flushes buffered logs (if any).
|
||||
func (kl *kopiaLog) Sync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Warnf(msg, args...)
|
||||
func (kl *kopiaLog) logrusFields(fields []zapcore.Field) logrus.Fields {
|
||||
if fields == nil {
|
||||
return logrus.Fields{}
|
||||
}
|
||||
|
||||
m := zapcore.NewMapObjectEncoder()
|
||||
for _, field := range fields {
|
||||
field.AddTo(m)
|
||||
}
|
||||
|
||||
return m.Fields
|
||||
}
|
||||
|
||||
func (kl *kopiaLog) getLogModule() string {
|
||||
return "kopia/" + kl.module
|
||||
}
|
||||
|
||||
func getLogFields(keyValuePairs ...interface{}) map[string]interface{} {
|
||||
m := map[string]interface{}{}
|
||||
for i := 0; i+1 < len(keyValuePairs); i += 2 {
|
||||
s, ok := keyValuePairs[i].(string)
|
||||
if !ok {
|
||||
s = "non-string-key"
|
||||
}
|
||||
func (kl *kopiaLog) logrusFieldsForWrite(ent zapcore.Entry, fields []zapcore.Field) logrus.Fields {
|
||||
copied := kl.logrusFields(fields)
|
||||
|
||||
m[s] = keyValuePairs[i+1]
|
||||
copied["logModule"] = kl.getLogModule()
|
||||
|
||||
if ent.Caller.Function != "" {
|
||||
copied["function"] = ent.Caller.Function
|
||||
}
|
||||
|
||||
return m
|
||||
path := ent.Caller.FullPath()
|
||||
if path != "undefined" {
|
||||
copied["path"] = path
|
||||
}
|
||||
|
||||
if ent.LoggerName != "" {
|
||||
copied["logger name"] = ent.LoggerName
|
||||
}
|
||||
|
||||
if ent.Stack != "" {
|
||||
copied["stack"] = ent.Stack
|
||||
}
|
||||
|
||||
if ent.Level == zap.ErrorLevel {
|
||||
copied["sublevel"] = "error"
|
||||
}
|
||||
|
||||
return copied
|
||||
}
|
||||
|
||||
@@ -19,66 +19,147 @@ package logging
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/test"
|
||||
)
|
||||
|
||||
func TestGetLogFields(t *testing.T) {
|
||||
func TestEnabled(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
pairs []interface{}
|
||||
expected map[string]interface{}
|
||||
level logrus.Level
|
||||
zapLevel zapcore.Level
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "normal",
|
||||
pairs: []interface{}{
|
||||
"fake-key1",
|
||||
"fake-value1",
|
||||
"fake-key2",
|
||||
10,
|
||||
"fake-key3",
|
||||
struct{ v int }{v: 10},
|
||||
name: "check debug again debug",
|
||||
level: logrus.DebugLevel,
|
||||
zapLevel: zapcore.DebugLevel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "check debug again info",
|
||||
level: logrus.InfoLevel,
|
||||
zapLevel: zapcore.DebugLevel,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "check info again debug",
|
||||
level: logrus.DebugLevel,
|
||||
zapLevel: zapcore.InfoLevel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "check info again info",
|
||||
level: logrus.InfoLevel,
|
||||
zapLevel: zapcore.InfoLevel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "check info again error",
|
||||
level: logrus.ErrorLevel,
|
||||
zapLevel: zapcore.InfoLevel,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "check error again error",
|
||||
level: logrus.ErrorLevel,
|
||||
zapLevel: zapcore.ErrorLevel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "check panic again error",
|
||||
level: logrus.ErrorLevel,
|
||||
zapLevel: zapcore.PanicLevel,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
log := kopiaLog{
|
||||
logger: test.NewLoggerWithLevel(tc.level),
|
||||
}
|
||||
m := log.Enabled(tc.zapLevel)
|
||||
|
||||
require.Equal(t, tc.expected, m)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrite(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
module string
|
||||
zapEntry zapcore.Entry
|
||||
zapFields []zapcore.Field
|
||||
expected logrus.Fields
|
||||
}{
|
||||
{
|
||||
name: "debug with nil fields",
|
||||
module: "module-01",
|
||||
zapEntry: zapcore.Entry{
|
||||
Level: zapcore.DebugLevel,
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"fake-key1": "fake-value1",
|
||||
"fake-key2": 10,
|
||||
"fake-key3": struct{ v int }{v: 10},
|
||||
zapFields: nil,
|
||||
expected: logrus.Fields{
|
||||
"logModule": "kopia/module-01",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non string key",
|
||||
pairs: []interface{}{
|
||||
"fake-key1",
|
||||
"fake-value1",
|
||||
10,
|
||||
10,
|
||||
"fake-key3",
|
||||
struct{ v int }{v: 10},
|
||||
name: "error with nil fields",
|
||||
module: "module-02",
|
||||
zapEntry: zapcore.Entry{
|
||||
Level: zapcore.ErrorLevel,
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"fake-key1": "fake-value1",
|
||||
"non-string-key": 10,
|
||||
"fake-key3": struct{ v int }{v: 10},
|
||||
zapFields: nil,
|
||||
expected: logrus.Fields{
|
||||
"logModule": "kopia/module-02",
|
||||
"sublevel": "error",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing value",
|
||||
pairs: []interface{}{
|
||||
"fake-key1",
|
||||
"fake-value1",
|
||||
"fake-key2",
|
||||
10,
|
||||
"fake-key3",
|
||||
name: "info with nil string filed",
|
||||
module: "module-03",
|
||||
zapEntry: zapcore.Entry{
|
||||
Level: zapcore.InfoLevel,
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"fake-key1": "fake-value1",
|
||||
"fake-key2": 10,
|
||||
zapFields: []zapcore.Field{
|
||||
{
|
||||
Key: "key-01",
|
||||
Type: zapcore.StringType,
|
||||
String: "value-01",
|
||||
},
|
||||
},
|
||||
expected: logrus.Fields{
|
||||
"logModule": "kopia/module-03",
|
||||
"key-01": "value-01",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "info with logger name",
|
||||
module: "module-04",
|
||||
zapEntry: zapcore.Entry{
|
||||
Level: zapcore.InfoLevel,
|
||||
LoggerName: "logger-name-01",
|
||||
},
|
||||
zapFields: nil,
|
||||
expected: logrus.Fields{
|
||||
"logModule": "kopia/module-04",
|
||||
"logger name": "logger-name-01",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
m := getLogFields(tc.pairs...)
|
||||
log := kopiaLog{
|
||||
module: tc.module,
|
||||
logger: test.NewLogger(),
|
||||
}
|
||||
m := log.logrusFieldsForWrite(tc.zapEntry, tc.zapFields)
|
||||
|
||||
require.Equal(t, tc.expected, m)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user