From 503b1126384647232e47993d30119e222bfd60a3 Mon Sep 17 00:00:00 2001 From: Nolan Brubaker Date: Wed, 13 Mar 2019 13:23:00 -0400 Subject: [PATCH] Add location resources and tests (#1277) Add locations and tests to install package Signed-off-by: Nolan Brubaker --- pkg/install/crd.go | 6 +++- pkg/install/daemonset.go | 6 +++- pkg/install/daemonset_test.go | 38 ++++++++++++++++++++++ pkg/install/deployment.go | 20 +++++++++++- pkg/install/deployment_test.go | 46 +++++++++++++++++++++++++++ pkg/install/doc.go | 19 +++++++++++ pkg/install/resources.go | 58 ++++++++++++++++++++++++++++++---- pkg/install/resources_test.go | 50 +++++++++++++++++++++++++++++ 8 files changed, 234 insertions(+), 9 deletions(-) create mode 100644 pkg/install/daemonset_test.go create mode 100644 pkg/install/deployment_test.go create mode 100644 pkg/install/doc.go create mode 100644 pkg/install/resources_test.go diff --git a/pkg/install/crd.go b/pkg/install/crd.go index 3c77601f0..b409f7c72 100644 --- a/pkg/install/crd.go +++ b/pkg/install/crd.go @@ -1,5 +1,5 @@ /* -Copyright 2018 the Heptio Ark contributors. +Copyright 2018, 2019 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. @@ -41,6 +41,10 @@ func crd(kind, plural string) *apiextv1beta1.CustomResourceDefinition { ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("%s.%s", plural, velerov1api.GroupName), }, + TypeMeta: metav1.TypeMeta{ + Kind: "CustomResourceDefinition", + APIVersion: apiextv1beta1.SchemeGroupVersion.String(), + }, Spec: apiextv1beta1.CustomResourceDefinitionSpec{ Group: velerov1api.GroupName, Version: velerov1api.SchemeGroupVersion.Version, diff --git a/pkg/install/daemonset.go b/pkg/install/daemonset.go index 539e62e77..289cd7324 100644 --- a/pkg/install/daemonset.go +++ b/pkg/install/daemonset.go @@ -1,5 +1,5 @@ /* -Copyright 2018 the Heptio Ark contributors. +Copyright 2018, 2019 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. @@ -42,6 +42,10 @@ func DaemonSet(namespace string, opts ...podTemplateOption) *appsv1.DaemonSet { daemonSet := &appsv1.DaemonSet{ ObjectMeta: objectMeta(namespace, "restic"), + TypeMeta: metav1.TypeMeta{ + Kind: "DaemonSet", + APIVersion: appsv1.SchemeGroupVersion.String(), + }, Spec: appsv1.DaemonSetSpec{ Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ diff --git a/pkg/install/daemonset_test.go b/pkg/install/daemonset_test.go new file mode 100644 index 000000000..11c447813 --- /dev/null +++ b/pkg/install/daemonset_test.go @@ -0,0 +1,38 @@ +/* +Copyright 2019 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 install + +import ( + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" +) + +func TestDaemonSet(t *testing.T) { + ds := DaemonSet("velero") + + assert.Equal(t, "restic", ds.Spec.Template.Spec.Containers[0].Name) + assert.Equal(t, "velero", ds.ObjectMeta.Namespace) + + ds = DaemonSet("velero", WithoutCredentialsVolume()) + assert.Equal(t, 1, len(ds.Spec.Template.Spec.Volumes)) + + ds = DaemonSet("velero", WithImage("gcr.io/heptio-images/velero:v0.11")) + assert.Equal(t, "gcr.io/heptio-images/velero:v0.11", ds.Spec.Template.Spec.Containers[0].Image) + assert.Equal(t, corev1.PullIfNotPresent, ds.Spec.Template.Spec.Containers[0].ImagePullPolicy) +} diff --git a/pkg/install/deployment.go b/pkg/install/deployment.go index 54eb27539..f4442055d 100644 --- a/pkg/install/deployment.go +++ b/pkg/install/deployment.go @@ -1,5 +1,5 @@ /* -Copyright 2018 the Heptio Ark contributors. +Copyright 2018, 2019 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. @@ -30,6 +30,7 @@ type podTemplateConfig struct { image string withoutCredentialsVolume bool envVars []corev1.EnvVar + restoreOnly bool } func WithImage(image string) podTemplateOption { @@ -60,7 +61,14 @@ func WithEnvFromSecretKey(varName, secret, key string) podTemplateOption { } } +func WithRestoreOnly() podTemplateOption { + return func(c *podTemplateConfig) { + c.restoreOnly = true + } +} + func Deployment(namespace string, opts ...podTemplateOption) *appsv1beta1.Deployment { + // TODO: Add support for server args c := &podTemplateConfig{ image: "gcr.io/heptio-images/velero:latest", } @@ -78,6 +86,10 @@ func Deployment(namespace string, opts ...podTemplateOption) *appsv1beta1.Deploy deployment := &appsv1beta1.Deployment{ ObjectMeta: objectMeta(namespace, "velero"), + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: appsv1beta1.SchemeGroupVersion.String(), + }, Spec: appsv1beta1.DeploymentSpec{ Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -152,5 +164,11 @@ func Deployment(namespace string, opts ...podTemplateOption) *appsv1beta1.Deploy ) } + deployment.Spec.Template.Spec.Containers[0].Env = append(deployment.Spec.Template.Spec.Containers[0].Env, c.envVars...) + + if c.restoreOnly { + deployment.Spec.Template.Spec.Containers[0].Args = append(deployment.Spec.Template.Spec.Containers[0].Args, "--restore-only") + } + return deployment } diff --git a/pkg/install/deployment_test.go b/pkg/install/deployment_test.go new file mode 100644 index 000000000..67b2aaceb --- /dev/null +++ b/pkg/install/deployment_test.go @@ -0,0 +1,46 @@ +/* +Copyright 2019 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 install + +import ( + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" +) + +func TestDeployment(t *testing.T) { + deploy := Deployment("velero") + + assert.Equal(t, "velero", deploy.ObjectMeta.Namespace) + + deploy = Deployment("velero", WithRestoreOnly()) + assert.Equal(t, "--restore-only", deploy.Spec.Template.Spec.Containers[0].Args[1]) + + deploy = Deployment("velero", WithEnvFromSecretKey("my-var", "my-secret", "my-key")) + envSecret := deploy.Spec.Template.Spec.Containers[0].Env[2] + assert.Equal(t, "my-var", envSecret.Name) + assert.Equal(t, "my-secret", envSecret.ValueFrom.SecretKeyRef.LocalObjectReference.Name) + assert.Equal(t, "my-key", envSecret.ValueFrom.SecretKeyRef.Key) + + deploy = Deployment("velero", WithoutCredentialsVolume()) + assert.Equal(t, 1, len(deploy.Spec.Template.Spec.Volumes)) + + deploy = Deployment("velero", WithImage("gcr.io/heptio-images/velero:v0.11")) + assert.Equal(t, "gcr.io/heptio-images/velero:v0.11", deploy.Spec.Template.Spec.Containers[0].Image) + assert.Equal(t, corev1.PullIfNotPresent, deploy.Spec.Template.Spec.Containers[0].ImagePullPolicy) +} diff --git a/pkg/install/doc.go b/pkg/install/doc.go new file mode 100644 index 000000000..ef5f28017 --- /dev/null +++ b/pkg/install/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 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 install provides public functions for easily creating and installing +// resources necessary for Velero to operate. Some default settings are assumed with these functions. +package install diff --git a/pkg/install/resources.go b/pkg/install/resources.go index d9e56a1c3..d05b967da 100644 --- a/pkg/install/resources.go +++ b/pkg/install/resources.go @@ -1,5 +1,5 @@ /* -Copyright 2018 the Heptio Ark contributors. +Copyright 2018, 2019 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. @@ -20,6 +20,8 @@ import ( corev1 "k8s.io/api/core/v1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/heptio/velero/pkg/apis/velero/v1" ) func labels() map[string]string { @@ -56,13 +58,19 @@ func objectMeta(namespace, name string) metav1.ObjectMeta { func ServiceAccount(namespace string) *corev1.ServiceAccount { return &corev1.ServiceAccount{ ObjectMeta: objectMeta(namespace, "velero"), + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceAccount", + APIVersion: corev1.SchemeGroupVersion.String(), + }, } } func ClusterRoleBinding(namespace string) *rbacv1beta1.ClusterRoleBinding { - return &rbacv1beta1.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "velero", + crb := &rbacv1beta1.ClusterRoleBinding{ + ObjectMeta: objectMeta("", "velero"), + TypeMeta: metav1.TypeMeta{ + Kind: "ClusterRoleBinding", + APIVersion: rbacv1beta1.SchemeGroupVersion.String(), }, Subjects: []rbacv1beta1.Subject{ { @@ -77,12 +85,50 @@ func ClusterRoleBinding(namespace string) *rbacv1beta1.ClusterRoleBinding { APIGroup: "rbac.authorization.k8s.io", }, } + + return crb } func Namespace(namespace string) *corev1.Namespace { return &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: namespace, + ObjectMeta: objectMeta("", namespace), + TypeMeta: metav1.TypeMeta{ + Kind: "Namespace", + APIVersion: corev1.SchemeGroupVersion.String(), + }, + } +} + +func BackupStorageLocation(namespace, provider, bucket, prefix string, config map[string]string) *v1.BackupStorageLocation { + return &v1.BackupStorageLocation{ + ObjectMeta: objectMeta(namespace, "default"), + TypeMeta: metav1.TypeMeta{ + Kind: "BackupStorageLocation", + APIVersion: v1.SchemeGroupVersion.String(), + }, + Spec: v1.BackupStorageLocationSpec{ + Provider: provider, + StorageType: v1.StorageType{ + ObjectStorage: &v1.ObjectStorageLocation{ + Bucket: bucket, + Prefix: prefix, + }, + }, + Config: config, + }, + } +} + +func VolumeSnapshotLocation(namespace, provider string, config map[string]string) *v1.VolumeSnapshotLocation { + return &v1.VolumeSnapshotLocation{ + ObjectMeta: objectMeta(namespace, "default"), + TypeMeta: metav1.TypeMeta{ + Kind: "VolumeSnapshotLocation", + APIVersion: v1.SchemeGroupVersion.String(), + }, + Spec: v1.VolumeSnapshotLocationSpec{ + Provider: provider, + Config: config, }, } } diff --git a/pkg/install/resources_test.go b/pkg/install/resources_test.go new file mode 100644 index 000000000..84818dfbb --- /dev/null +++ b/pkg/install/resources_test.go @@ -0,0 +1,50 @@ +/* +Copyright 2019 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 install + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResources(t *testing.T) { + bsl := BackupStorageLocation("velero", "test", "test", "", make(map[string]string)) + + assert.Equal(t, "velero", bsl.ObjectMeta.Namespace) + assert.Equal(t, "test", bsl.Spec.Provider) + assert.Equal(t, "test", bsl.Spec.StorageType.ObjectStorage.Bucket) + assert.Equal(t, make(map[string]string), bsl.Spec.Config) + + vsl := VolumeSnapshotLocation("velero", "test", make(map[string]string)) + + assert.Equal(t, "velero", vsl.ObjectMeta.Namespace) + assert.Equal(t, "test", vsl.Spec.Provider) + assert.Equal(t, make(map[string]string), vsl.Spec.Config) + + ns := Namespace("velero") + + assert.Equal(t, "velero", ns.Name) + + crb := ClusterRoleBinding("velero") + // The CRB is a cluster-scoped resource + assert.Equal(t, "", crb.ObjectMeta.Namespace) + assert.Equal(t, "velero", crb.Subjects[0].Namespace) + + sa := ServiceAccount("velero") + assert.Equal(t, "velero", sa.ObjectMeta.Namespace) +}