mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-09-13 11:34:54 +00:00
@@ -286,7 +286,8 @@ func (e *genericRestoreExposer) Expose(ctx context.Context, ownerObject corev1ap
|
||||
|
||||
selectedNode = ""
|
||||
|
||||
restorePV, err := kube.WaitPVCBound(ctx, e.kubeClient.CoreV1(), e.kubeClient.CoreV1(), restorePVC.Name, restorePVC.Namespace, param.ExposeTimeout)
|
||||
var restorePV *corev1api.PersistentVolume
|
||||
restorePV, err = kube.WaitPVCBound(ctx, e.kubeClient.CoreV1(), e.kubeClient.CoreV1(), restorePVC.Name, restorePVC.Namespace, param.ExposeTimeout)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error waiting for restore PVC bound")
|
||||
}
|
||||
@@ -309,7 +310,8 @@ func (e *genericRestoreExposer) Expose(ctx context.Context, ownerObject corev1ap
|
||||
return errors.Wrapf(err, "error to get volume snapshot %s/%s", param.CSI.Snapshot.VolumeSnapshotNamespace, param.CSI.Snapshot.VolumeSnapshot)
|
||||
}
|
||||
|
||||
vsc, err := csi.GetVSCForVS(ctx, vs, e.ctrlClient)
|
||||
var vsc *snapshotv1api.VolumeSnapshotContent
|
||||
vsc, err = csi.GetVSCForVS(ctx, vs, e.ctrlClient)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error to get volume snapshot content for volume snapshot %s/%s", vs.Namespace, vs.Name)
|
||||
}
|
||||
|
||||
@@ -188,20 +188,22 @@ func TestRestoreExpose(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
kubeClientObj []runtime.Object
|
||||
ownerRestore *velerov1.Restore
|
||||
targetPVCName string
|
||||
targetNamespace string
|
||||
targetPVName string
|
||||
kubeReactors []reactor
|
||||
cacheVolume *CacheConfigs
|
||||
dataMover string
|
||||
expectBackupPod bool
|
||||
expectBackupPVC bool
|
||||
expectCachePVC bool
|
||||
expectBackupPV bool
|
||||
err string
|
||||
name string
|
||||
kubeClientObj []runtime.Object
|
||||
ownerRestore *velerov1.Restore
|
||||
targetPVCName string
|
||||
targetNamespace string
|
||||
targetPVName string
|
||||
kubeReactors []reactor
|
||||
cacheVolume *CacheConfigs
|
||||
dataMover string
|
||||
expectBackupPod bool
|
||||
expectBackupPVC bool
|
||||
expectCachePVC bool
|
||||
expectBackupPV bool
|
||||
expectedNodeSelector map[string]string
|
||||
expectedNodeAffinity *corev1api.NodeAffinity
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "wait target pvc consumed fail",
|
||||
@@ -339,8 +341,29 @@ func TestRestoreExpose(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectBackupPod: true,
|
||||
expectBackupPVC: true,
|
||||
expectBackupPod: true,
|
||||
expectBackupPVC: true,
|
||||
expectedNodeSelector: map[string]string{},
|
||||
expectedNodeAffinity: &corev1api.NodeAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{
|
||||
NodeSelectorTerms: []corev1api.NodeSelectorTerm{
|
||||
{
|
||||
MatchExpressions: []corev1api.NodeSelectorRequirement{
|
||||
{
|
||||
Key: "topology.kubernetes.io/zone",
|
||||
Operator: corev1api.NodeSelectorOpIn,
|
||||
Values: []string{"zone-1"},
|
||||
},
|
||||
{
|
||||
Key: "kubernetes.io/os",
|
||||
Operator: corev1api.NodeSelectorOpNotIn,
|
||||
Values: []string{"windows"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "create temporary PV fail",
|
||||
@@ -559,9 +582,16 @@ func TestRestoreExpose(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
_, err = exposer.kubeClient.CoreV1().Pods(ownerObject.Namespace).Get(t.Context(), ownerObject.Name, metav1.GetOptions{})
|
||||
pod, err := exposer.kubeClient.CoreV1().Pods(ownerObject.Namespace).Get(t.Context(), ownerObject.Name, metav1.GetOptions{})
|
||||
if test.expectBackupPod {
|
||||
require.NoError(t, err)
|
||||
if test.expectedNodeSelector != nil {
|
||||
assert.Equal(t, test.expectedNodeSelector, pod.Spec.NodeSelector)
|
||||
}
|
||||
if test.expectedNodeAffinity != nil {
|
||||
require.NotNil(t, pod.Spec.Affinity)
|
||||
assert.Equal(t, test.expectedNodeAffinity, pod.Spec.Affinity.NodeAffinity)
|
||||
}
|
||||
} else {
|
||||
require.True(t, apierrors.IsNotFound(err), "expected IsNotFound, got %v", err)
|
||||
}
|
||||
@@ -1608,6 +1638,115 @@ end diagnose restore exposer`,
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateSelectedNode(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
node string
|
||||
dataMover string
|
||||
kubeClientObj []runtime.Object
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "empty node",
|
||||
node: "",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "node os is linux",
|
||||
node: "fake-node",
|
||||
kubeClientObj: []runtime.Object{
|
||||
&corev1api.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-node",
|
||||
Labels: map[string]string{
|
||||
corev1api.LabelOSStable: kube.NodeOSLinux,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "node os is windows",
|
||||
node: "fake-node",
|
||||
kubeClientObj: []runtime.Object{
|
||||
&corev1api.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-node",
|
||||
Labels: map[string]string{
|
||||
corev1api.LabelOSStable: kube.NodeOSWindows,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "node without os label",
|
||||
node: "fake-node",
|
||||
kubeClientObj: []runtime.Object{
|
||||
&corev1api.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-node",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "node not found",
|
||||
node: "fake-node",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "block data mover with linux node",
|
||||
node: "fake-node",
|
||||
dataMover: datamover.DataMoverTypeVeleroBlock,
|
||||
kubeClientObj: []runtime.Object{
|
||||
&corev1api.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-node",
|
||||
Labels: map[string]string{
|
||||
corev1api.LabelOSStable: kube.NodeOSLinux,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "block data mover with windows node",
|
||||
node: "fake-node",
|
||||
dataMover: datamover.DataMoverTypeVeleroBlock,
|
||||
kubeClientObj: []runtime.Object{
|
||||
&corev1api.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-node",
|
||||
Labels: map[string]string{
|
||||
corev1api.LabelOSStable: kube.NodeOSWindows,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fakeKubeClient := fake.NewSimpleClientset(test.kubeClientObj...)
|
||||
|
||||
exposer := genericRestoreExposer{
|
||||
kubeClient: fakeKubeClient,
|
||||
log: velerotest.NewLogger(),
|
||||
}
|
||||
|
||||
actual := exposer.validateSelectedNode(t.Context(), test.node, test.dataMover, exposer.log)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateRestorePod(t *testing.T) {
|
||||
scName := "storage-class-01"
|
||||
|
||||
@@ -1744,28 +1883,28 @@ func TestCreateRestorePod(t *testing.T) {
|
||||
log: velerotest.NewLogger(),
|
||||
}
|
||||
|
||||
pod, err := exposer.createRestorePod(
|
||||
t.Context(),
|
||||
corev1api.ObjectReference{
|
||||
Namespace: velerov1.DefaultNamespace,
|
||||
Name: "data-download",
|
||||
},
|
||||
targetPVCObj,
|
||||
time.Second*3,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
test.selectedNode,
|
||||
corev1api.ResourceRequirements{},
|
||||
test.nodeOS,
|
||||
test.affinity,
|
||||
"", // priority class name
|
||||
nil,
|
||||
"", // volumeSnapshotNamespace
|
||||
"", // volumeID
|
||||
nil,
|
||||
nil, // volumeTopology
|
||||
)
|
||||
pod, err := exposer.createRestorePod(
|
||||
t.Context(),
|
||||
corev1api.ObjectReference{
|
||||
Namespace: velerov1.DefaultNamespace,
|
||||
Name: "data-download",
|
||||
},
|
||||
targetPVCObj,
|
||||
time.Second*3,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
test.selectedNode,
|
||||
corev1api.ResourceRequirements{},
|
||||
test.nodeOS,
|
||||
test.affinity,
|
||||
"", // priority class name
|
||||
nil,
|
||||
"", // volumeSnapshotNamespace
|
||||
"", // volumeID
|
||||
nil,
|
||||
nil, // volumeTopology
|
||||
)
|
||||
|
||||
require.NoError(t, err)
|
||||
if test.expectedPod != nil {
|
||||
|
||||
Reference in New Issue
Block a user