From 6fb5bc7ff05318c3e96a0f72579979d265bb6466 Mon Sep 17 00:00:00 2001 From: "Md. Emruz Hossain" Date: Thu, 4 Jul 2019 11:41:17 +0600 Subject: [PATCH] Create default Functions and Tasks from operator (#824) * create update-status function from operator * Create pvc-backup and pvc-restore function & task by default * Fix update-status function * Add comment on exported functions * Use CreateOrPatch to ensure Function and Task --- pkg/controller/config.go | 15 +++ pkg/util/crds.go | 274 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100644 pkg/util/crds.go diff --git a/pkg/controller/config.go b/pkg/controller/config.go index 2a548f54d..42f61d19e 100644 --- a/pkg/controller/config.go +++ b/pkg/controller/config.go @@ -19,6 +19,7 @@ import ( stashinformers "stash.appscode.dev/stash/client/informers/externalversions" "stash.appscode.dev/stash/pkg/eventer" stash_rbac "stash.appscode.dev/stash/pkg/rbac" + "stash.appscode.dev/stash/pkg/util" ) const ( @@ -79,9 +80,23 @@ func (c *Config) New() (*StashController, error) { recorder: eventer.NewEventRecorder(c.KubeClient, "stash-operator"), } + // register CRDs if err := ctrl.ensureCustomResourceDefinitions(); err != nil { return nil, err } + + // ensure default functions + err := util.EnsureDefaultFunctions(ctrl.stashClient, ctrl.DockerRegistry, ctrl.StashImageTag) + if err != nil { + return nil, err + } + + // ensure default tasks + err = util.EnsureDefaultTasks(ctrl.stashClient) + if err != nil { + return nil, err + } + if c.EnableMutatingWebhook { if err := reg_util.UpdateMutatingWebhookCABundle(c.ClientConfig, mutatingWebhook); err != nil { return nil, err diff --git a/pkg/util/crds.go b/pkg/util/crds.go new file mode 100644 index 000000000..84215a841 --- /dev/null +++ b/pkg/util/crds.go @@ -0,0 +1,274 @@ +package util + +import ( + core "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api_v1beta1 "stash.appscode.dev/stash/apis/stash/v1beta1" + cs "stash.appscode.dev/stash/client/clientset/versioned" + util_v1beta1 "stash.appscode.dev/stash/client/clientset/versioned/typed/stash/v1beta1/util" + "stash.appscode.dev/stash/pkg/docker" +) + +// EnsureDefaultFunctions creates "update-status", "pvc-backup" and "pvc-restore" Functions if they are not already present +func EnsureDefaultFunctions(stashClient cs.Interface, registry, imageTag string) error { + image := docker.Docker{ + Registry: registry, + Image: docker.ImageStash, + Tag: imageTag, + } + + defaultFunctions := []*api_v1beta1.Function{ + updateStatusFunction(image), + pvcBackupFunction(image), + pvcRestoreFunction(image), + } + + for _, fn := range defaultFunctions { + _, _, err := util_v1beta1.CreateOrPatchFunction(stashClient.StashV1beta1(), fn.ObjectMeta, func(in *api_v1beta1.Function) *api_v1beta1.Function { + in.Spec = fn.Spec + return in + }) + if err != nil { + return err + } + } + return nil +} + +// EnsureDefaultTasks creates "pvc-backup" and "pvc-restore" Tasks if they are not already present +func EnsureDefaultTasks(stashClient cs.Interface) error { + defaultTasks := []*api_v1beta1.Task{ + pvcBackupTask(), + pvcRestoreTask(), + } + + for _, task := range defaultTasks { + _, _, err := util_v1beta1.CreateOrPatchTask(stashClient.StashV1beta1(), task.ObjectMeta, func(in *api_v1beta1.Task) *api_v1beta1.Task { + in.Spec = task.Spec + return in + }) + if err != nil { + return err + } + } + + return nil +} + +func updateStatusFunction(image docker.Docker) *api_v1beta1.Function { + return &api_v1beta1.Function{ + ObjectMeta: metav1.ObjectMeta{ + Name: "update-status", + }, + Spec: api_v1beta1.FunctionSpec{ + Image: image.ToContainerImage(), + Args: []string{ + "update-status", + "--namespace=${NAMESPACE:=default}", + "--backup-session=${BACKUP_SESSION:=}", + "--repository=${REPOSITORY_NAME:=}", + "--restore-session=${RESTORE_SESSION:=}", + "--output-dir=${outputDir:=}", + "--enable-status-subresource=${ENABLE_STATUS_SUBRESOURCE:=false}", + }, + }, + } +} + +func pvcBackupFunction(image docker.Docker) *api_v1beta1.Function { + return &api_v1beta1.Function{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-backup", + }, + Spec: api_v1beta1.FunctionSpec{ + Image: image.ToContainerImage(), + Args: []string{ + "backup-pvc", + "--provider=${REPOSITORY_PROVIDER:=}", + "--bucket=${REPOSITORY_BUCKET:=}", + "--endpoint=${REPOSITORY_ENDPOINT:=}", + "--rest-server-url=${REPOSITORY_URL:=}", + "--path=${REPOSITORY_PREFIX:=}", + "--secret-dir=/etc/repository/secret", + "--scratch-dir=/tmp", + "--enable-cache=${ENABLE_CACHE:=true}", + "--max-connections=${MAX_CONNECTIONS:=0}", + "--hostname=${HOSTNAME:=}", + "--backup-dirs=${TARGET_DIRECTORIES}", + "--retention-keep-last=${RETENTION_KEEP_LAST:=0}", + "--retention-keep-hourly=${RETENTION_KEEP_HOURLY:=0}", + "--retention-keep-daily=${RETENTION_KEEP_DAILY:=0}", + "--retention-keep-weekly=${RETENTION_KEEP_WEEKLY:=0}", + "--retention-keep-monthly=${RETENTION_KEEP_MONTHLY:=0}", + "--retention-keep-yearly=${RETENTION_KEEP_YEARLY:=0}", + "--retention-keep-tags=${RETENTION_KEEP_TAGS:=}", + "--retention-prune=${RETENTION_PRUNE:=false}", + "--retention-dry-run=${RETENTION_DRY_RUN:=false}", + "--output-dir=${outputDir:=}", + "--metrics-enabled=true", + "--metrics-pushgateway-url=${PROMETHEUS_PUSHGATEWAY_URL:=}", + }, + VolumeMounts: []core.VolumeMount{ + { + Name: "${targetVolume}", + MountPath: "${TARGET_MOUNT_PATH}", + }, + { + Name: "${secretVolume}", + MountPath: "/etc/repository/secret", + }, + }, + }, + } +} + +func pvcRestoreFunction(image docker.Docker) *api_v1beta1.Function { + return &api_v1beta1.Function{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-restore", + }, + Spec: api_v1beta1.FunctionSpec{ + Image: image.ToContainerImage(), + Args: []string{ + "restore-pvc", + "--provider=${REPOSITORY_PROVIDER:=}", + "--bucket=${REPOSITORY_BUCKET:=}", + "--endpoint=${REPOSITORY_ENDPOINT:=}", + "--rest-server-url=${REPOSITORY_URL:=}", + "--path=${REPOSITORY_PREFIX:=}", + "--secret-dir=/etc/repository/secret", + "--scratch-dir=/tmp", + "--enable-cache=${ENABLE_CACHE:=true}", + "--max-connections=${MAX_CONNECTIONS:=0}", + "--hostname=${HOSTNAME:=}", + "--restore-dirs=${RESTORE_DIRECTORIES}", + "--snapshots=${RESTORE_SNAPSHOTS:=}", + "--output-dir=${outputDir:=}", + "--metrics-enabled=true", + "--metrics-pushgateway-url=${PROMETHEUS_PUSHGATEWAY_URL:=}", + }, + VolumeMounts: []core.VolumeMount{ + { + Name: "${targetVolume}", + MountPath: "${TARGET_MOUNT_PATH}", + }, + { + Name: "${secretVolume}", + MountPath: "/etc/repository/secret", + }, + }, + }, + } +} + +func pvcBackupTask() *api_v1beta1.Task { + return &api_v1beta1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-backup", + }, + Spec: api_v1beta1.TaskSpec{ + Steps: []api_v1beta1.FunctionRef{ + { + Name: "pvc-backup", + Params: []api_v1beta1.Param{ + { + Name: "outputDir", + Value: "/tmp/output", + }, + { + Name: "targetVolume", + Value: "target-volume", + }, + { + Name: "secretVolume", + Value: "secret-volume", + }, + }, + }, + { + Name: "update-status", + Params: []api_v1beta1.Param{ + { + Name: "outputDir", + Value: "/tmp/output", + }, + }, + }, + }, + Volumes: []core.Volume{ + { + Name: "target-volume", + VolumeSource: core.VolumeSource{ + PersistentVolumeClaim: &core.PersistentVolumeClaimVolumeSource{ + ClaimName: "${TARGET_NAME}", + }, + }, + }, + { + Name: "secret-volume", + VolumeSource: core.VolumeSource{ + Secret: &core.SecretVolumeSource{ + SecretName: "${REPOSITORY_SECRET_NAME}", + }, + }, + }, + }, + }, + } +} + +func pvcRestoreTask() *api_v1beta1.Task { + return &api_v1beta1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-restore", + }, + Spec: api_v1beta1.TaskSpec{ + Steps: []api_v1beta1.FunctionRef{ + { + Name: "pvc-restore", + Params: []api_v1beta1.Param{ + { + Name: "outputDir", + Value: "/tmp/output", + }, + { + Name: "targetVolume", + Value: "target-volume", + }, + { + Name: "secretVolume", + Value: "secret-volume", + }, + }, + }, + { + Name: "update-status", + Params: []api_v1beta1.Param{ + { + Name: "outputDir", + Value: "/tmp/output", + }, + }, + }, + }, + Volumes: []core.Volume{ + { + Name: "target-volume", + VolumeSource: core.VolumeSource{ + PersistentVolumeClaim: &core.PersistentVolumeClaimVolumeSource{ + ClaimName: "${TARGET_NAME}", + }, + }, + }, + { + Name: "secret-volume", + VolumeSource: core.VolumeSource{ + Secret: &core.SecretVolumeSource{ + SecretName: "${REPOSITORY_SECRET_NAME}", + }, + }, + }, + }, + }, + } +}