Skip to content
191 changes: 10 additions & 181 deletions controllers/restic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ func TestVeleroReconciler_buildResticDaemonset(t *testing.T) {
},
},
{
name: "Valid velero and daemonset for aws as bsl with non-default secret name",
name: "Valid velero with annotation and daemonset for aws as bsl with default secret name",
args: args{
&oadpv1alpha1.Velero{
Spec: oadpv1alpha1.VeleroSpec{
Expand All @@ -409,178 +409,7 @@ func TestVeleroReconciler_buildResticDaemonset(t *testing.T) {
},
Credential: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "aws-creds",
},
},
},
},
},
}, &appsv1.DaemonSet{
ObjectMeta: getResticObjectMeta(r),
},
},
wantErr: false,
want: &appsv1.DaemonSet{
ObjectMeta: getResticObjectMeta(r),
TypeMeta: metav1.TypeMeta{
Kind: "DaemonSet",
APIVersion: appsv1.SchemeGroupVersion.String(),
},
Spec: appsv1.DaemonSetSpec{
UpdateStrategy: appsv1.DaemonSetUpdateStrategy{
Type: appsv1.RollingUpdateDaemonSetStrategyType,
},
Selector: resticLabelSelector,
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"component": common.Velero,
"name": common.Restic,
},
},
Spec: corev1.PodSpec{
NodeSelector: velero.Spec.ResticNodeSelector,
ServiceAccountName: common.Velero,
SecurityContext: &corev1.PodSecurityContext{
RunAsUser: pointer.Int64(0),
SupplementalGroups: velero.Spec.ResticSupplementalGroups,
},
Volumes: []corev1.Volume{
// Cloud Provider volumes are dynamically added in the for loop below
{
Name: HostPods,
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: resticPvHostPath,
},
},
},
{
Name: "scratch",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
{
Name: "certs",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
{
Name: "aws-creds",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: "aws-creds",
},
},
},
},
Tolerations: velero.Spec.ResticTolerations,
Containers: []corev1.Container{
{
Name: common.Restic,
SecurityContext: &corev1.SecurityContext{
Privileged: pointer.Bool(true),
},
Image: getVeleroImage(&velero),
ImagePullPolicy: corev1.PullAlways,
Resources: r.getVeleroResourceReqs(&velero), //setting default.
Command: []string{
"/velero",
},
Args: []string{
"restic",
"server",
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "host-pods",
MountPath: "/host_pods",
MountPropagation: &mountPropagationToHostContainer,
},
{
Name: "scratch",
MountPath: "/scratch",
},
{
Name: "certs",
MountPath: "/etc/ssl/certs",
},
{
Name: "aws-creds",
MountPath: "/credentials",
},
},
Env: []corev1.EnvVar{
{
Name: "NODE_NAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: "spec.nodeName",
},
},
},
{
Name: "VELERO_NAMESPACE",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: "metadata.namespace",
},
},
},
{
Name: "VELERO_SCRATCH_DIR",
Value: "/scratch",
},
{
Name: "HTTP_PROXY",
Value: os.Getenv("HTTP_PROXY"),
},
{
Name: "HTTPS_PROXY",
Value: os.Getenv("HTTPS_PROXY"),
},
{
Name: "NO_PROXY",
Value: os.Getenv("NO_PROXY"),
},
{
Name: common.AWSSharedCredentialsFileEnvKey,
Value: "/credentials/cloud",
},
},
},
},
},
},
},
},
},
{
name: "Valid velero with annotation and daemonset for aws as bsl with non-default secret name",
args: args{
&oadpv1alpha1.Velero{
Spec: oadpv1alpha1.VeleroSpec{
DefaultVeleroPlugins: []oadpv1alpha1.DefaultPlugin{
oadpv1alpha1.DefaultPluginAWS,
},
BackupStorageLocations: []velerov1.BackupStorageLocationSpec{
{
Provider: AWSProvider,
StorageType: velerov1.StorageType{
ObjectStorage: &velerov1.ObjectStorageLocation{
Bucket: "aws-bucket",
},
},
Config: map[string]string{
Region: "aws-region",
S3URL: "https://sr-url-aws-domain.com",
InsecureSkipTLSVerify: "false",
},
Credential: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "aws-creds",
Name: "cloud-credentials",
},
},
},
Expand Down Expand Up @@ -645,10 +474,10 @@ func TestVeleroReconciler_buildResticDaemonset(t *testing.T) {
},
},
{
Name: "aws-creds",
Name: "cloud-credentials",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: "aws-creds",
SecretName: "cloud-credentials",
},
},
},
Expand Down Expand Up @@ -685,7 +514,7 @@ func TestVeleroReconciler_buildResticDaemonset(t *testing.T) {
MountPath: "/etc/ssl/certs",
},
{
Name: "aws-creds",
Name: "cloud-credentials",
MountPath: "/credentials",
},
},
Expand Down Expand Up @@ -735,7 +564,7 @@ func TestVeleroReconciler_buildResticDaemonset(t *testing.T) {
},
},
{
name: "Valid velero with DNS Policy/Config with annotation and daemonset for aws as bsl with non-default secret name",
name: "Valid velero with DNS Policy/Config with annotation and daemonset for aws as bsl with default secret name",
args: args{
&oadpv1alpha1.Velero{
Spec: oadpv1alpha1.VeleroSpec{
Expand All @@ -757,7 +586,7 @@ func TestVeleroReconciler_buildResticDaemonset(t *testing.T) {
},
Credential: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "aws-creds",
Name: "cloud-credentials",
},
},
},
Expand Down Expand Up @@ -854,10 +683,10 @@ func TestVeleroReconciler_buildResticDaemonset(t *testing.T) {
},
},
{
Name: "aws-creds",
Name: "cloud-credentials",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: "aws-creds",
SecretName: "cloud-credentials",
},
},
},
Expand Down Expand Up @@ -894,7 +723,7 @@ func TestVeleroReconciler_buildResticDaemonset(t *testing.T) {
MountPath: "/etc/ssl/certs",
},
{
Name: "aws-creds",
Name: "cloud-credentials",
MountPath: "/credentials",
},
},
Expand Down
24 changes: 23 additions & 1 deletion controllers/velero.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ func (r *VeleroReconciler) ReconcileVeleroDeployment(log logr.Logger) (bool, err
if err != nil {
return err
}

// update the Deployment template
return r.buildVeleroDeployment(veleroDeployment, &velero)
})
Expand Down Expand Up @@ -531,3 +530,26 @@ func (r *VeleroReconciler) getVeleroResourceReqs(velero *oadpv1alpha1.Velero) co

return ResourcesReqs
}

// For later: Move this code into validator.go when more need for validation arises
// TODO: if multiple default plugins exist, ensure we validate all of them.
// Right now its sequential validation
func (r *VeleroReconciler) ValidateVeleroPlugins(log logr.Logger) (bool, error) {
velero := oadpv1alpha1.Velero{}
if err := r.Get(r.Context, r.NamespacedName, &velero); err != nil {
return false, err
}

var defaultPlugin oadpv1alpha1.DefaultPlugin
for _, plugin := range velero.Spec.DefaultVeleroPlugins {
if pluginSpecificMap, ok := credentials.PluginSpecificFields[plugin]; ok && pluginSpecificMap.IsCloudProvider {
secretName := pluginSpecificMap.SecretName
_, err := r.getProviderSecret(secretName)
if err != nil {
r.Log.Info(fmt.Sprintf("error validating %s provider secret: %s/%s", defaultPlugin, r.NamespacedName.Namespace, secretName))
return false, err
}
}
}
return true, nil
}
6 changes: 5 additions & 1 deletion controllers/velero_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package controllers

import (
"context"

routev1 "github.com/openshift/api/route/v1"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"

Expand Down Expand Up @@ -73,13 +74,15 @@ func (r *VeleroReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
// Set reconciler context + name
r.Context = ctx
r.NamespacedName = req.NamespacedName

velero := oadpv1alpha1.Velero{}

if err := r.Get(ctx, req.NamespacedName, &velero); err != nil {
log.Error(err, "unable to fetch velero CR")
return result, client.IgnoreNotFound(err)
}

_, err := ReconcileBatch(r.Log,
r.ValidateVeleroPlugins,
r.ReconcileVeleroSecurityContextConstraint,
r.ReconcileResticRestoreHelperConfig,
r.ValidateBackupStorageLocations,
Expand All @@ -103,6 +106,7 @@ func (r *VeleroReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
Message: err.Error(),
},
)

} else {
apimeta.SetStatusCondition(&velero.Status.Conditions,
metav1.Condition{
Expand Down
Loading