diff --git a/operator/common/images.go b/operator/common/images.go new file mode 100644 index 000000000..4c72ffd01 --- /dev/null +++ b/operator/common/images.go @@ -0,0 +1,46 @@ +package common + +type image string + +func (i image) String() string { return string(i) } + +type dockerhubImage image + +type zitadelImage image + +const ( + CockroachImage dockerhubImage = "cockroachdb/cockroach:v20.2.3" + PostgresImage dockerhubImage = "postgres:9.6.17" + FlywayImage dockerhubImage = "flyway/flyway:7.5.1" + AlpineImage dockerhubImage = "alpine:3.11" + ZITADELImage zitadelImage = "caos/zitadel" + BackupImage zitadelImage = "caos/zitadel-crbackup" + ZITADELOperatorImage zitadelImage = "caos/zitadel-operator" +) + +func (z zitadelImage) Reference(customImageRegistry, version string) string { + + reg := "ghcr.io" + if customImageRegistry != "" { + reg = customImageRegistry + } + + return concat(image(z), reg, version) +} + +func (d dockerhubImage) Reference(customImageRegistry string) string { + return concat(image(d), customImageRegistry, "") +} + +func concat(img image, customImageRegistry, version string) string { + str := img.String() + + if customImageRegistry != "" { + str = customImageRegistry + "/" + str + } + + if version != "" { + str = str + ":" + version + } + return str +} diff --git a/operator/common/images_test.go b/operator/common/images_test.go new file mode 100644 index 000000000..799c79da3 --- /dev/null +++ b/operator/common/images_test.go @@ -0,0 +1,106 @@ +package common + +import ( + "errors" + "fmt" + "strings" + "testing" +) + +func TestDockerHubReference(t *testing.T) { + + imgs := []dockerhubImage{CockroachImage, PostgresImage, FlywayImage, AlpineImage} + + type args struct { + customImageRegistry string + } + tests := []struct { + name string + args args + test func(result string) error + }{{ + name: "Image should be pulled from docker hub by default", + args: args{ + customImageRegistry: "", + }, + test: func(result string) error { + return expectRegistry(result, "") + }, + }, { + name: "Given a custom image registry, the registry should be prepended", + args: args{ + customImageRegistry: "myreg.io", + }, + test: func(result string) error { + return expectRegistry(result, "myreg.io") + }, + }} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for i := range imgs { + got := imgs[i].Reference(tt.args.customImageRegistry) + if err := tt.test(got); err != nil { + t.Error(fmt.Errorf("DockerHubReference(%s): %w", imgs[i], err)) + } + } + }) + } +} + +func TestZITADELReference(t *testing.T) { + + imgs := []zitadelImage{ZITADELImage, BackupImage} + dummyVersion := "v99.99.99" + + type args struct { + customImageRegistry string + } + tests := []struct { + name string + args args + test func(result string) error + }{{ + name: "Image should be pulled from GHCR by default", + args: args{ + customImageRegistry: "", + }, + test: func(result string) error { + return expectRegistry(result, "ghcr.io/") + }, + }, { + name: "Given a random docker hub image and a custom image registry, the registry should be prepended", + args: args{ + customImageRegistry: "myreg.io", + }, + test: func(result string) error { + return expectRegistry(result, "myreg.io") + }, + }} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for i := range imgs { + got := imgs[i].Reference(tt.args.customImageRegistry, dummyVersion) + if err := tt.test(got); err != nil { + t.Error(fmt.Errorf("ZITADELReference(%s): %w", imgs[i], err)) + } + } + }) + } +} + +func expectRegistry(result, expect string) error { + if !strings.HasPrefix(result, expect) { + return fmt.Errorf("image is not prefixed by the registry %s", expect) + } + points := strings.Count(result[:strings.Index(result, ":")], ".") + if expect == "" && points > 1 { + return errors.New("doesn't look like a docker image") + } + + if points > 1 { + return errors.New("too many points") + } + return nil +} diff --git a/operator/database/kinds/backups/backups.go b/operator/database/kinds/backups/backups.go index 745206280..cc74380c1 100644 --- a/operator/database/kinds/backups/backups.go +++ b/operator/database/kinds/backups/backups.go @@ -24,6 +24,7 @@ func Adapt( tolerations []corev1.Toleration, version string, features []string, + customImageRegistry string, ) ( operator.QueryFunc, operator.DestroyFunc, @@ -51,6 +52,7 @@ func Adapt( tolerations, version, features, + customImageRegistry, )(monitor, desiredTree, currentTree) default: return nil, nil, nil, nil, nil, false, errors.Errorf("unknown database kind %s", desiredTree.Common.Kind) diff --git a/operator/database/kinds/backups/bucket/adapt.go b/operator/database/kinds/backups/bucket/adapt.go index 0f77d9487..fd8b458ac 100644 --- a/operator/database/kinds/backups/bucket/adapt.go +++ b/operator/database/kinds/backups/bucket/adapt.go @@ -9,6 +9,7 @@ import ( "github.com/caos/orbos/pkg/secret/read" "github.com/caos/orbos/pkg/tree" "github.com/caos/zitadel/operator" + "github.com/caos/zitadel/operator/common" "github.com/caos/zitadel/operator/database/kinds/backups/bucket/backup" "github.com/caos/zitadel/operator/database/kinds/backups/bucket/clean" "github.com/caos/zitadel/operator/database/kinds/backups/bucket/restore" @@ -32,6 +33,7 @@ func AdaptFunc( tolerations []corev1.Toleration, version string, features []string, + customImageRegistry string, ) operator.AdaptFunc { return func( monitor mntr.Monitor, @@ -66,6 +68,8 @@ func AdaptFunc( return nil, nil, nil, nil, nil, false, err } + image := common.BackupImage.Reference(customImageRegistry, version) + _, destroyB, err := backup.AdaptFunc( internalMonitor, name, @@ -81,7 +85,7 @@ func AdaptFunc( nodeselector, tolerations, features, - version, + image, ) if err != nil { return nil, nil, nil, nil, nil, false, err @@ -100,7 +104,7 @@ func AdaptFunc( checkDBReady, secretName, secretKey, - version, + image, ) if err != nil { return nil, nil, nil, nil, nil, false, err @@ -117,7 +121,7 @@ func AdaptFunc( checkDBReady, secretName, secretKey, - version, + image, ) if err != nil { return nil, nil, nil, nil, nil, false, err @@ -183,7 +187,7 @@ func AdaptFunc( nodeselector, tolerations, features, - version, + image, ) if err != nil { return nil, err @@ -202,7 +206,7 @@ func AdaptFunc( checkDBReady, secretName, secretKey, - version, + image, ) if err != nil { return nil, err @@ -219,7 +223,7 @@ func AdaptFunc( checkDBReady, secretName, secretKey, - version, + image, ) if err != nil { return nil, err diff --git a/operator/database/kinds/backups/bucket/adapt_test.go b/operator/database/kinds/backups/bucket/adapt_test.go index 6d85a7e28..8e4c874d5 100644 --- a/operator/database/kinds/backups/bucket/adapt_test.go +++ b/operator/database/kinds/backups/bucket/adapt_test.go @@ -71,6 +71,7 @@ func TestBucket_Secrets(t *testing.T) { tolerations, version, features, + "", )( monitor, desired, @@ -143,6 +144,7 @@ func TestBucket_AdaptBackup(t *testing.T) { tolerations, version, features, + "", )( monitor, desired, @@ -217,6 +219,7 @@ func TestBucket_AdaptInstantBackup(t *testing.T) { tolerations, version, features, + "", )( monitor, desired, @@ -292,6 +295,7 @@ func TestBucket_AdaptRestore(t *testing.T) { tolerations, version, features, + "", )( monitor, desired, @@ -367,6 +371,7 @@ func TestBucket_AdaptClean(t *testing.T) { tolerations, version, features, + "", )( monitor, desired, diff --git a/operator/database/kinds/backups/bucket/backup/adapt.go b/operator/database/kinds/backups/bucket/backup/adapt.go index c4d6d96b8..2e1aae1d8 100644 --- a/operator/database/kinds/backups/bucket/backup/adapt.go +++ b/operator/database/kinds/backups/bucket/backup/adapt.go @@ -21,7 +21,6 @@ const ( backupNameEnv = "BACKUP_NAME" cronJobNamePrefix = "backup-" internalSecretName = "client-certs" - image = "ghcr.io/caos/zitadel-crbackup" rootSecretName = "cockroachdb.client.root" timeout = 15 * time.Minute Normal = "backup" @@ -43,7 +42,7 @@ func AdaptFunc( nodeselector map[string]string, tolerations []corev1.Toleration, features []string, - version string, + image string, ) ( queryFunc operator.QueryFunc, destroyFunc operator.DestroyFunc, @@ -63,8 +62,8 @@ func AdaptFunc( secretName, secretKey, backupName, - version, command, + image, ) destroyers := []operator.DestroyFunc{} diff --git a/operator/database/kinds/backups/bucket/backup/adapt_test.go b/operator/database/kinds/backups/bucket/backup/adapt_test.go index 76b6f55bb..a8834b88b 100644 --- a/operator/database/kinds/backups/bucket/backup/adapt_test.go +++ b/operator/database/kinds/backups/bucket/backup/adapt_test.go @@ -29,7 +29,7 @@ func TestBackup_AdaptInstantBackup1(t *testing.T) { tolerations := []corev1.Toleration{ {Key: "testKey", Operator: "testOp"}} backupName := "testName" - version := "testVersion" + image := "testImage" secretKey := "testKey" secretName := "testSecretName" jobName := GetJobName(backupName) @@ -49,13 +49,13 @@ func TestBackup_AdaptInstantBackup1(t *testing.T) { secretName, secretKey, backupName, - version, getBackupCommand( timestamp, databases, bucketName, backupName, ), + image, ), ) @@ -77,7 +77,7 @@ func TestBackup_AdaptInstantBackup1(t *testing.T) { nodeselector, tolerations, features, - version, + image, ) assert.NoError(t, err) @@ -101,7 +101,7 @@ func TestBackup_AdaptInstantBackup2(t *testing.T) { tolerations := []corev1.Toleration{ {Key: "testKey2", Operator: "testOp2"}} backupName := "testName2" - version := "testVersion2" + image := "testImage2" secretKey := "testKey2" secretName := "testSecretName2" jobName := GetJobName(backupName) @@ -121,13 +121,13 @@ func TestBackup_AdaptInstantBackup2(t *testing.T) { secretName, secretKey, backupName, - version, getBackupCommand( timestamp, databases, bucketName, backupName, ), + image, ), ) @@ -149,7 +149,7 @@ func TestBackup_AdaptInstantBackup2(t *testing.T) { nodeselector, tolerations, features, - version, + image, ) assert.NoError(t, err) @@ -173,7 +173,7 @@ func TestBackup_AdaptBackup1(t *testing.T) { tolerations := []corev1.Toleration{ {Key: "testKey", Operator: "testOp"}} backupName := "testName" - version := "testVersion" + image := "testImage" secretKey := "testKey" secretName := "testSecretName" jobName := GetJobName(backupName) @@ -194,13 +194,13 @@ func TestBackup_AdaptBackup1(t *testing.T) { secretName, secretKey, backupName, - version, getBackupCommand( timestamp, databases, bucketName, backupName, ), + image, ), ) @@ -221,7 +221,7 @@ func TestBackup_AdaptBackup1(t *testing.T) { nodeselector, tolerations, features, - version, + image, ) assert.NoError(t, err) @@ -245,7 +245,7 @@ func TestBackup_AdaptBackup2(t *testing.T) { tolerations := []corev1.Toleration{ {Key: "testKey2", Operator: "testOp2"}} backupName := "testName2" - version := "testVersion2" + image := "testImage2" secretKey := "testKey2" secretName := "testSecretName2" jobName := GetJobName(backupName) @@ -266,13 +266,13 @@ func TestBackup_AdaptBackup2(t *testing.T) { secretName, secretKey, backupName, - version, getBackupCommand( timestamp, databases, bucketName, backupName, ), + image, ), ) @@ -293,7 +293,7 @@ func TestBackup_AdaptBackup2(t *testing.T) { nodeselector, tolerations, features, - version, + image, ) assert.NoError(t, err) diff --git a/operator/database/kinds/backups/bucket/backup/job.go b/operator/database/kinds/backups/bucket/backup/job.go index e2615112d..b7a53a22f 100644 --- a/operator/database/kinds/backups/bucket/backup/job.go +++ b/operator/database/kinds/backups/bucket/backup/job.go @@ -52,8 +52,8 @@ func getJobSpecDef( secretName string, secretKey string, backupName string, - version string, command string, + image string, ) batchv1.JobSpec { return batchv1.JobSpec{ Template: corev1.PodTemplateSpec{ @@ -63,7 +63,7 @@ func getJobSpecDef( Tolerations: tolerations, Containers: []corev1.Container{{ Name: backupName, - Image: image + ":" + version, + Image: image, Command: []string{ "/bin/bash", "-c", diff --git a/operator/database/kinds/backups/bucket/backup/job_test.go b/operator/database/kinds/backups/bucket/backup/job_test.go index 9ac146bde..f41a6efcc 100644 --- a/operator/database/kinds/backups/bucket/backup/job_test.go +++ b/operator/database/kinds/backups/bucket/backup/job_test.go @@ -1,11 +1,12 @@ package backup import ( + "testing" + "github.com/caos/zitadel/operator/helpers" "github.com/stretchr/testify/assert" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" - "testing" ) func TestBackup_JobSpec1(t *testing.T) { @@ -13,10 +14,10 @@ func TestBackup_JobSpec1(t *testing.T) { tolerations := []corev1.Toleration{ {Key: "testKey", Operator: "testOp"}} backupName := "testName" - version := "testVersion" command := "test" secretKey := "testKey" secretName := "testSecretName" + image := "testImage" equals := batchv1.JobSpec{ Template: corev1.PodTemplateSpec{ @@ -26,7 +27,7 @@ func TestBackup_JobSpec1(t *testing.T) { Tolerations: tolerations, Containers: []corev1.Container{{ Name: backupName, - Image: image + ":" + version, + Image: image, Command: []string{ "/bin/bash", "-c", @@ -62,7 +63,7 @@ func TestBackup_JobSpec1(t *testing.T) { }, } - assert.Equal(t, equals, getJobSpecDef(nodeselector, tolerations, secretName, secretKey, backupName, version, command)) + assert.Equal(t, equals, getJobSpecDef(nodeselector, tolerations, secretName, secretKey, backupName, command, image)) } func TestBackup_JobSpec2(t *testing.T) { @@ -70,10 +71,10 @@ func TestBackup_JobSpec2(t *testing.T) { tolerations := []corev1.Toleration{ {Key: "testKey2", Operator: "testOp2"}} backupName := "testName2" - version := "testVersion2" command := "test2" secretKey := "testKey2" secretName := "testSecretName2" + image := "testImage2" equals := batchv1.JobSpec{ Template: corev1.PodTemplateSpec{ @@ -83,7 +84,7 @@ func TestBackup_JobSpec2(t *testing.T) { Tolerations: tolerations, Containers: []corev1.Container{{ Name: backupName, - Image: image + ":" + version, + Image: image, Command: []string{ "/bin/bash", "-c", @@ -119,5 +120,5 @@ func TestBackup_JobSpec2(t *testing.T) { }, } - assert.Equal(t, equals, getJobSpecDef(nodeselector, tolerations, secretName, secretKey, backupName, version, command)) + assert.Equal(t, equals, getJobSpecDef(nodeselector, tolerations, secretName, secretKey, backupName, command, image)) } diff --git a/operator/database/kinds/backups/bucket/clean/adapt.go b/operator/database/kinds/backups/bucket/clean/adapt.go index 7d8dd46e9..c46b8d0c9 100644 --- a/operator/database/kinds/backups/bucket/clean/adapt.go +++ b/operator/database/kinds/backups/bucket/clean/adapt.go @@ -18,7 +18,6 @@ const ( certPath = "/cockroach/cockroach-certs" secretPath = "/secrets/sa.json" internalSecretName = "client-certs" - image = "ghcr.io/caos/zitadel-crbackup" rootSecretName = "cockroachdb.client.root" jobPrefix = "backup-" jobSuffix = "-clean" @@ -36,7 +35,7 @@ func AdaptFunc( checkDBReady operator.EnsureFunc, secretName string, secretKey string, - version string, + image string, ) ( queryFunc operator.QueryFunc, destroyFunc operator.DestroyFunc, @@ -52,8 +51,9 @@ func AdaptFunc( tolerations, secretName, secretKey, - version, - command) + command, + image, + ) destroyJ, err := job.AdaptFuncToDestroy(jobDef.Namespace, jobDef.Name) if err != nil { diff --git a/operator/database/kinds/backups/bucket/clean/adapt_test.go b/operator/database/kinds/backups/bucket/clean/adapt_test.go index 45a1b0be1..5c6ad8db9 100644 --- a/operator/database/kinds/backups/bucket/clean/adapt_test.go +++ b/operator/database/kinds/backups/bucket/clean/adapt_test.go @@ -24,7 +24,7 @@ func TestBackup_Adapt1(t *testing.T) { tolerations := []corev1.Toleration{ {Key: "testKey", Operator: "testOp"}} backupName := "testName" - version := "testVersion" + image := "testImage" secretKey := "testKey" secretName := "testSecretName" jobName := GetJobName(backupName) @@ -42,10 +42,10 @@ func TestBackup_Adapt1(t *testing.T) { tolerations, secretName, secretKey, - version, getCommand( databases, ), + image, ) client.EXPECT().ApplyJob(jobDef).Times(1).Return(nil) @@ -62,7 +62,7 @@ func TestBackup_Adapt1(t *testing.T) { checkDBReady, secretName, secretKey, - version, + image, ) assert.NoError(t, err) @@ -82,7 +82,7 @@ func TestBackup_Adapt2(t *testing.T) { tolerations := []corev1.Toleration{ {Key: "testKey2", Operator: "testOp2"}} backupName := "testName2" - version := "testVersion2" + image := "testImage2" secretKey := "testKey2" secretName := "testSecretName2" jobName := GetJobName(backupName) @@ -100,10 +100,10 @@ func TestBackup_Adapt2(t *testing.T) { tolerations, secretName, secretKey, - version, getCommand( databases, ), + image, ) client.EXPECT().ApplyJob(jobDef).Times(1).Return(nil) @@ -120,7 +120,7 @@ func TestBackup_Adapt2(t *testing.T) { checkDBReady, secretName, secretKey, - version, + image, ) assert.NoError(t, err) diff --git a/operator/database/kinds/backups/bucket/clean/job.go b/operator/database/kinds/backups/bucket/clean/job.go index 4ae4d75cc..de753259b 100644 --- a/operator/database/kinds/backups/bucket/clean/job.go +++ b/operator/database/kinds/backups/bucket/clean/job.go @@ -15,8 +15,8 @@ func getJob( tolerations []corev1.Toleration, secretName string, secretKey string, - version string, command string, + image string, ) *batchv1.Job { return &batchv1.Job{ @@ -33,7 +33,7 @@ func getJob( RestartPolicy: corev1.RestartPolicyNever, Containers: []corev1.Container{{ Name: nameLabels.Name(), - Image: image + ":" + version, + Image: image, Command: []string{ "/bin/bash", "-c", diff --git a/operator/database/kinds/backups/bucket/clean/job_test.go b/operator/database/kinds/backups/bucket/clean/job_test.go index 419f6b064..8ad27a39a 100644 --- a/operator/database/kinds/backups/bucket/clean/job_test.go +++ b/operator/database/kinds/backups/bucket/clean/job_test.go @@ -1,25 +1,26 @@ package clean import ( + "testing" + "github.com/caos/orbos/pkg/labels" "github.com/caos/zitadel/operator/helpers" "github.com/stretchr/testify/assert" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "testing" ) func TestBackup_Job1(t *testing.T) { nodeselector := map[string]string{"test": "test"} tolerations := []corev1.Toleration{ {Key: "testKey", Operator: "testOp"}} - version := "testVersion" command := "test" secretKey := "testKey" secretName := "testSecretName" jobName := "testJob" namespace := "testNs" + image := "testImage" k8sLabels := map[string]string{ "app.kubernetes.io/component": "testComponent", @@ -47,7 +48,7 @@ func TestBackup_Job1(t *testing.T) { Tolerations: tolerations, Containers: []corev1.Container{{ Name: jobName, - Image: image + ":" + version, + Image: image, Command: []string{ "/bin/bash", "-c", @@ -84,19 +85,19 @@ func TestBackup_Job1(t *testing.T) { }, } - assert.Equal(t, equals, getJob(namespace, nameLabels, nodeselector, tolerations, secretName, secretKey, version, command)) + assert.Equal(t, equals, getJob(namespace, nameLabels, nodeselector, tolerations, secretName, secretKey, command, image)) } func TestBackup_Job2(t *testing.T) { nodeselector := map[string]string{"test2": "test2"} tolerations := []corev1.Toleration{ {Key: "testKey2", Operator: "testOp2"}} - version := "testVersion2" command := "test2" secretKey := "testKey2" secretName := "testSecretName2" jobName := "testJob2" namespace := "testNs2" + image := "testImage2" k8sLabels := map[string]string{ "app.kubernetes.io/component": "testComponent2", "app.kubernetes.io/managed-by": "testOp2", @@ -123,7 +124,7 @@ func TestBackup_Job2(t *testing.T) { Tolerations: tolerations, Containers: []corev1.Container{{ Name: jobName, - Image: image + ":" + version, + Image: image, Command: []string{ "/bin/bash", "-c", @@ -160,5 +161,5 @@ func TestBackup_Job2(t *testing.T) { }, } - assert.Equal(t, equals, getJob(namespace, nameLabels, nodeselector, tolerations, secretName, secretKey, version, command)) + assert.Equal(t, equals, getJob(namespace, nameLabels, nodeselector, tolerations, secretName, secretKey, command, image)) } diff --git a/operator/database/kinds/backups/bucket/restore/adapt.go b/operator/database/kinds/backups/bucket/restore/adapt.go index 5f232e2e0..e9a98c61d 100644 --- a/operator/database/kinds/backups/bucket/restore/adapt.go +++ b/operator/database/kinds/backups/bucket/restore/adapt.go @@ -19,7 +19,6 @@ const ( secretPath = "/secrets/sa.json" jobPrefix = "backup-" jobSuffix = "-restore" - image = "ghcr.io/caos/zitadel-crbackup" internalSecretName = "client-certs" rootSecretName = "cockroachdb.client.root" timeout = 15 * time.Minute @@ -38,7 +37,7 @@ func AdaptFunc( checkDBReady operator.EnsureFunc, secretName string, secretKey string, - version string, + image string, ) ( queryFunc operator.QueryFunc, destroyFunc operator.DestroyFunc, @@ -60,8 +59,8 @@ func AdaptFunc( tolerations, secretName, secretKey, - version, - command) + command, + image) destroyJ, err := job.AdaptFuncToDestroy(jobName, namespace) if err != nil { diff --git a/operator/database/kinds/backups/bucket/restore/adapt_test.go b/operator/database/kinds/backups/bucket/restore/adapt_test.go index b6031def5..5eaf96cf6 100644 --- a/operator/database/kinds/backups/bucket/restore/adapt_test.go +++ b/operator/database/kinds/backups/bucket/restore/adapt_test.go @@ -26,7 +26,7 @@ func TestBackup_Adapt1(t *testing.T) { timestamp := "testTs" backupName := "testName2" bucketName := "testBucket2" - version := "testVersion" + image := "testImage2" secretKey := "testKey" secretName := "testSecretName" jobName := GetJobName(backupName) @@ -44,13 +44,13 @@ func TestBackup_Adapt1(t *testing.T) { tolerations, secretName, secretKey, - version, getCommand( timestamp, databases, bucketName, backupName, ), + image, ) client.EXPECT().ApplyJob(jobDef).Times(1).Return(nil) @@ -69,7 +69,7 @@ func TestBackup_Adapt1(t *testing.T) { checkDBReady, secretName, secretKey, - version, + image, ) assert.NoError(t, err) @@ -91,7 +91,7 @@ func TestBackup_Adapt2(t *testing.T) { timestamp := "testTs" backupName := "testName2" bucketName := "testBucket2" - version := "testVersion2" + image := "testImage2" secretKey := "testKey2" secretName := "testSecretName2" jobName := GetJobName(backupName) @@ -109,13 +109,13 @@ func TestBackup_Adapt2(t *testing.T) { tolerations, secretName, secretKey, - version, getCommand( timestamp, databases, bucketName, backupName, ), + image, ) client.EXPECT().ApplyJob(jobDef).Times(1).Return(nil) @@ -134,7 +134,7 @@ func TestBackup_Adapt2(t *testing.T) { checkDBReady, secretName, secretKey, - version, + image, ) assert.NoError(t, err) diff --git a/operator/database/kinds/backups/bucket/restore/job.go b/operator/database/kinds/backups/bucket/restore/job.go index cdf28f39d..7193fc3db 100644 --- a/operator/database/kinds/backups/bucket/restore/job.go +++ b/operator/database/kinds/backups/bucket/restore/job.go @@ -15,9 +15,8 @@ func getJob( tolerations []corev1.Toleration, secretName string, secretKey string, - version string, command string, - + image string, ) *batchv1.Job { return &batchv1.Job{ ObjectMeta: v1.ObjectMeta{ @@ -33,7 +32,7 @@ func getJob( RestartPolicy: corev1.RestartPolicyNever, Containers: []corev1.Container{{ Name: nameLabels.Name(), - Image: image + ":" + version, + Image: image, Command: []string{ "/bin/bash", "-c", diff --git a/operator/database/kinds/backups/bucket/restore/job_test.go b/operator/database/kinds/backups/bucket/restore/job_test.go index 9efed1955..d9547968c 100644 --- a/operator/database/kinds/backups/bucket/restore/job_test.go +++ b/operator/database/kinds/backups/bucket/restore/job_test.go @@ -1,25 +1,26 @@ package restore import ( + "testing" + "github.com/caos/orbos/pkg/labels" "github.com/caos/zitadel/operator/helpers" "github.com/stretchr/testify/assert" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "testing" ) func TestBackup_Job1(t *testing.T) { nodeselector := map[string]string{"test": "test"} tolerations := []corev1.Toleration{ {Key: "testKey", Operator: "testOp"}} - version := "testVersion" command := "test" secretKey := "testKey" secretName := "testSecretName" jobName := "testJob" namespace := "testNs" + image := "testImage" k8sLabels := map[string]string{ "app.kubernetes.io/component": "testComponent", "app.kubernetes.io/managed-by": "testOp", @@ -46,7 +47,7 @@ func TestBackup_Job1(t *testing.T) { Tolerations: tolerations, Containers: []corev1.Container{{ Name: jobName, - Image: image + ":" + version, + Image: image, Command: []string{ "/bin/bash", "-c", @@ -83,19 +84,19 @@ func TestBackup_Job1(t *testing.T) { }, } - assert.Equal(t, equals, getJob(namespace, nameLabels, nodeselector, tolerations, secretName, secretKey, version, command)) + assert.Equal(t, equals, getJob(namespace, nameLabels, nodeselector, tolerations, secretName, secretKey, command, image)) } func TestBackup_Job2(t *testing.T) { nodeselector := map[string]string{"test2": "test2"} tolerations := []corev1.Toleration{ {Key: "testKey2", Operator: "testOp2"}} - version := "testVersion2" command := "test2" secretKey := "testKey2" secretName := "testSecretName2" jobName := "testJob2" namespace := "testNs2" + testImage := "testImage2" k8sLabels := map[string]string{ "app.kubernetes.io/component": "testComponent2", "app.kubernetes.io/managed-by": "testOp2", @@ -122,7 +123,7 @@ func TestBackup_Job2(t *testing.T) { Tolerations: tolerations, Containers: []corev1.Container{{ Name: jobName, - Image: image + ":" + version, + Image: testImage, Command: []string{ "/bin/bash", "-c", @@ -159,5 +160,5 @@ func TestBackup_Job2(t *testing.T) { }, } - assert.Equal(t, equals, getJob(namespace, nameLabels, nodeselector, tolerations, secretName, secretKey, version, command)) + assert.Equal(t, equals, getJob(namespace, nameLabels, nodeselector, tolerations, secretName, secretKey, command, testImage)) } diff --git a/operator/database/kinds/databases/databases.go b/operator/database/kinds/databases/databases.go index 23b6f6ef9..29a280ad5 100644 --- a/operator/database/kinds/databases/databases.go +++ b/operator/database/kinds/databases/databases.go @@ -31,6 +31,7 @@ func Adapt( tolerations []core.Toleration, version string, features []string, + customImageRegistry string, ) ( query operator.QueryFunc, destroy operator.DestroyFunc, @@ -45,7 +46,16 @@ func Adapt( switch desiredTree.Common.Kind { case "databases.caos.ch/CockroachDB": - return managed.Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(internalMonitor, desiredTree, currentTree) + return managed.Adapter( + componentLabels, + namespace, + timestamp, + nodeselector, + tolerations, + version, + features, + customImageRegistry, + )(internalMonitor, desiredTree, currentTree) case "databases.caos.ch/ProvidedDatabase": return provided.Adapter()(internalMonitor, desiredTree, currentTree) default: diff --git a/operator/database/kinds/databases/managed/adapt.go b/operator/database/kinds/databases/managed/adapt.go index c3d564c45..c3d140c2d 100644 --- a/operator/database/kinds/databases/managed/adapt.go +++ b/operator/database/kinds/databases/managed/adapt.go @@ -4,6 +4,8 @@ import ( "strconv" "strings" + "github.com/caos/zitadel/operator/common" + "github.com/caos/zitadel/operator" "github.com/caos/orbos/pkg/labels" @@ -44,6 +46,7 @@ func Adapter( tolerations []corev1.Toleration, version string, features []string, + customImageRegistry string, ) operator.AdaptFunc { return func( @@ -114,7 +117,7 @@ func Adapter( cockroachSelector, desiredKind.Spec.Force, namespace, - image, + common.CockroachImage.Reference(customImageRegistry), serviceAccountName, desiredKind.Spec.ReplicaCount, desiredKind.Spec.StorageCapacity, @@ -219,6 +222,7 @@ func Adapter( tolerations, version, features, + customImageRegistry, ) if err != nil { return nil, nil, nil, nil, nil, false, err diff --git a/operator/database/kinds/databases/managed/adapt_backup_test.go b/operator/database/kinds/databases/managed/adapt_backup_test.go index 6e915b281..276a5d3b2 100644 --- a/operator/database/kinds/databases/managed/adapt_backup_test.go +++ b/operator/database/kinds/databases/managed/adapt_backup_test.go @@ -84,7 +84,7 @@ func TestManaged_AdaptBucketBackup(t *testing.T) { bucket.SetBackup(k8sClient, namespace, labels, saJson) k8sClient.EXPECT().WaitUntilStatefulsetIsReady(namespace, SfsName, true, true, 60*time.Second) - query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{}) + query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features, "")(monitor, desired, &tree.Tree{}) assert.NoError(t, err) databases := []string{"test1", "test2"} @@ -124,7 +124,7 @@ func TestManaged_AdaptBucketInstantBackup(t *testing.T) { desired := getTreeWithDBAndBackup(t, masterkey, saJson, backupName) - query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{}) + query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features, "")(monitor, desired, &tree.Tree{}) assert.NoError(t, err) databases := []string{"test1", "test2"} @@ -165,7 +165,7 @@ func TestManaged_AdaptBucketCleanAndRestore(t *testing.T) { desired := getTreeWithDBAndBackup(t, masterkey, saJson, backupName) - query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{}) + query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features, "")(monitor, desired, &tree.Tree{}) assert.NoError(t, err) databases := []string{"test1", "test2"} diff --git a/operator/database/kinds/databases/managed/adapt_test.go b/operator/database/kinds/databases/managed/adapt_test.go index d88ef44d0..a0b48eb5d 100644 --- a/operator/database/kinds/databases/managed/adapt_test.go +++ b/operator/database/kinds/databases/managed/adapt_test.go @@ -133,7 +133,16 @@ func TestManaged_Adapt1(t *testing.T) { dbCurrent.EXPECT().SetCertificateKey(gomock.Any()).MinTimes(1).MaxTimes(1) k8sClient.EXPECT().ApplySecret(gomock.Any()).MinTimes(1).MaxTimes(1) - query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{}) + query, _, _, _, _, _, err := Adapter( + componentLabels, + namespace, + timestamp, + nodeselector, + tolerations, + version, + features, + "", + )(monitor, desired, &tree.Tree{}) assert.NoError(t, err) ensure, err := query(k8sClient, queried) @@ -245,7 +254,16 @@ func TestManaged_Adapt2(t *testing.T) { dbCurrent.EXPECT().SetCertificateKey(gomock.Any()).MinTimes(1).MaxTimes(1) k8sClient.EXPECT().ApplySecret(gomock.Any()).MinTimes(1).MaxTimes(1) - query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{}) + query, _, _, _, _, _, err := Adapter( + componentLabels, + namespace, + timestamp, + nodeselector, + tolerations, + version, + features, + "", + )(monitor, desired, &tree.Tree{}) assert.NoError(t, err) ensure, err := query(k8sClient, queried) diff --git a/operator/database/kinds/orb/adapt.go b/operator/database/kinds/orb/adapt.go index 79a89f59b..ebd33108a 100644 --- a/operator/database/kinds/orb/adapt.go +++ b/operator/database/kinds/orb/adapt.go @@ -85,6 +85,7 @@ func AdaptFunc( desiredKind.Spec.Tolerations, desiredKind.Spec.Version, features, + desiredKind.Spec.CustomImageRegistry, ) if err != nil { return nil, nil, nil, nil, nil, migrate, err diff --git a/operator/database/kinds/orb/desired.go b/operator/database/kinds/orb/desired.go index 15a982876..2f4f5eca3 100644 --- a/operator/database/kinds/orb/desired.go +++ b/operator/database/kinds/orb/desired.go @@ -19,8 +19,8 @@ type Spec struct { Tolerations []corev1.Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"` Version string `json:"version,omitempty" yaml:"version,omitempty"` SelfReconciling bool `json:"selfReconciling" yaml:"selfReconciling"` - //Use this registry to pull the Database operator image from - //@default: ghcr.io + //Use this registry to pull container images from + //@default: CustomImageRegistry string `json:"customImageRegistry,omitempty" yaml:"customImageRegistry,omitempty"` } diff --git a/operator/database/kinds/orb/reconcile.go b/operator/database/kinds/orb/reconcile.go index 851478a50..dd9a3f926 100644 --- a/operator/database/kinds/orb/reconcile.go +++ b/operator/database/kinds/orb/reconcile.go @@ -24,11 +24,6 @@ func Reconcile( return err } - imageRegistry := spec.CustomImageRegistry - if imageRegistry == "" { - imageRegistry = "ghcr.io" - } - if spec.SelfReconciling { desiredTree := &tree.Tree{ Common: &tree.Common{ @@ -37,7 +32,7 @@ func Reconcile( }, } - if err := zitadelKubernetes.EnsureDatabaseArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustDatabaseOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, imageRegistry, gitops); err != nil { + if err := zitadelKubernetes.EnsureDatabaseArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustDatabaseOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, spec.CustomImageRegistry, gitops); err != nil { recMonitor.Error(errors.Wrap(err, "Failed to deploy database-operator into k8s-cluster")) return err } diff --git a/operator/zitadel/kinds/iam/iam.go b/operator/zitadel/kinds/iam/iam.go index 22a24aa66..b8161a8ca 100644 --- a/operator/zitadel/kinds/iam/iam.go +++ b/operator/zitadel/kinds/iam/iam.go @@ -27,6 +27,7 @@ func Adapt( action string, version *string, features []string, + customImageRegistry string, ) ( query operator.QueryFunc, destroy operator.DestroyFunc, @@ -46,7 +47,17 @@ func Adapt( switch desiredTree.Common.Kind { case "zitadel.caos.ch/ZITADEL": apiLabels := labels.MustForAPI(operatorLabels, "ZITADEL", desiredTree.Common.Version) - return zitadel.AdaptFunc(apiLabels, nodeselector, tolerations, dbClient, namespace, action, version, features)(monitor, desiredTree, currentTree) + return zitadel.AdaptFunc( + apiLabels, + nodeselector, + tolerations, + dbClient, + namespace, + action, + version, + features, + customImageRegistry, + )(monitor, desiredTree, currentTree) default: return nil, nil, nil, nil, nil, false, errors.Errorf("unknown iam kind %s", desiredTree.Common.Kind) } diff --git a/operator/zitadel/kinds/iam/zitadel/adapt.go b/operator/zitadel/kinds/iam/zitadel/adapt.go index bad67e2df..956da953c 100644 --- a/operator/zitadel/kinds/iam/zitadel/adapt.go +++ b/operator/zitadel/kinds/iam/zitadel/adapt.go @@ -35,6 +35,7 @@ func AdaptFunc( action string, version *string, features []string, + customImageRegistry string, ) operator.AdaptFunc { return func( monitor mntr.Monitor, @@ -141,6 +142,7 @@ func AdaptFunc( usersWithoutPWs, nodeselector, tolerations, + customImageRegistry, ) if err != nil { return nil, nil, nil, nil, nil, false, err @@ -162,6 +164,7 @@ func AdaptFunc( consoleCMName, secretVarsName, secretPasswordName, + customImageRegistry, ) if err != nil { return nil, nil, nil, nil, nil, false, err @@ -189,6 +192,7 @@ func AdaptFunc( migration.GetDoneFunc(monitor, namespace, action), configuration.GetReadyFunc(monitor, namespace, secretName, secretVarsName, secretPasswordName, cmName, consoleCMName), setup.GetDoneFunc(monitor, namespace, action), + customImageRegistry, ) if err != nil { return nil, nil, nil, nil, nil, false, err diff --git a/operator/zitadel/kinds/iam/zitadel/deployment/adapt.go b/operator/zitadel/kinds/iam/zitadel/deployment/adapt.go index b0b88333b..ceca1c9ac 100644 --- a/operator/zitadel/kinds/iam/zitadel/deployment/adapt.go +++ b/operator/zitadel/kinds/iam/zitadel/deployment/adapt.go @@ -21,8 +21,7 @@ const ( containerName = "zitadel" RunAsUser = int64(1000) //zitadelImage can be found in github.com/caos/zitadel repo - zitadelImage = "ghcr.io/caos/zitadel" - timeout = 60 * time.Second + timeout = 60 * time.Second ) func AdaptFunc( @@ -47,6 +46,7 @@ func AdaptFunc( migrationDone operator.EnsureFunc, configurationDone operator.EnsureFunc, setupDone operator.EnsureFunc, + customImageRegistry string, ) ( func( necessaryUsers map[string]string, @@ -93,6 +93,7 @@ func AdaptFunc( consoleCMName, secretVarsName, secretPasswordsName, + customImageRegistry, ) hashes, err := getConfigurationHashes(k8sClient, queried, necessaryUsers) @@ -126,7 +127,26 @@ func AdaptFunc( } -func deploymentDef(nameLabels *labels.Name, namespace string, replicaCount int, podSelector *labels.Selector, nodeSelector map[string]string, tolerations []corev1.Toleration, affinity *k8s.Affinity, users []string, version *string, resources *k8s.Resources, cmName string, certPath string, secretName string, secretPath string, consoleCMName string, secretVarsName string, secretPasswordsName string) *appsv1.Deployment { +func deploymentDef( + nameLabels *labels.Name, + namespace string, + replicaCount int, + podSelector *labels.Selector, + nodeSelector map[string]string, + tolerations []corev1.Toleration, + affinity *k8s.Affinity, + users []string, + version *string, + resources *k8s.Resources, + cmName string, + certPath string, + secretName string, + secretPath string, + consoleCMName string, + secretVarsName string, + secretPasswordsName string, + customImageRegistry string, +) *appsv1.Deployment { deploymentDef := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: nameLabels.Name(), @@ -161,6 +181,7 @@ func deploymentDef(nameLabels *labels.Name, namespace string, replicaCount int, dbSecrets, users, RunAsUser, + customImageRegistry, ), }, Containers: []corev1.Container{ @@ -180,6 +201,7 @@ func deploymentDef(nameLabels *labels.Name, namespace string, replicaCount int, users, dbSecrets, "start", + customImageRegistry, ), }, Volumes: GetVolumes( diff --git a/operator/zitadel/kinds/iam/zitadel/deployment/adapt_test.go b/operator/zitadel/kinds/iam/zitadel/deployment/adapt_test.go index 24e3b164e..1970fbb0a 100644 --- a/operator/zitadel/kinds/iam/zitadel/deployment/adapt_test.go +++ b/operator/zitadel/kinds/iam/zitadel/deployment/adapt_test.go @@ -32,6 +32,8 @@ func TestDeployment_Adapt(t *testing.T) { secretName := "testSecret" consoleCMName := "testConsoleCM" cmName := "testCM" + customImageRegistry := "" + usersMap := map[string]string{"test": "test"} users := []string{} for _, user := range usersMap { @@ -86,6 +88,7 @@ func TestDeployment_Adapt(t *testing.T) { dbSecrets, users, RunAsUser, + customImageRegistry, ), }, Containers: []corev1.Container{ @@ -105,6 +108,7 @@ func TestDeployment_Adapt(t *testing.T) { users, dbSecrets, "start", + customImageRegistry, ), }, Volumes: GetVolumes( @@ -154,6 +158,7 @@ func TestDeployment_Adapt(t *testing.T) { migrationDone, configurationDone, setupDone, + customImageRegistry, ) assert.NoError(t, err) queried := map[string]interface{}{} diff --git a/operator/zitadel/kinds/iam/zitadel/deployment/container.go b/operator/zitadel/kinds/iam/zitadel/deployment/container.go index d3a5e52c7..f207bf778 100644 --- a/operator/zitadel/kinds/iam/zitadel/deployment/container.go +++ b/operator/zitadel/kinds/iam/zitadel/deployment/container.go @@ -4,6 +4,8 @@ import ( "sort" "strings" + "github.com/caos/zitadel/operator/common" + "github.com/caos/orbos/pkg/kubernetes/k8s" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -25,6 +27,7 @@ func GetContainer( users []string, dbSecrets string, command string, + customImageRegistry string, ) corev1.Container { envVars := []corev1.EnvVar{ @@ -107,7 +110,7 @@ func GetContainer( RunAsNonRoot: &runAsNonRoot, }, Name: containerName, - Image: zitadelImage + ":" + version, + Image: common.ZITADELImage.Reference(customImageRegistry, version), ImagePullPolicy: corev1.PullIfNotPresent, Ports: []corev1.ContainerPort{ {Name: "grpc", ContainerPort: 50001}, diff --git a/operator/zitadel/kinds/iam/zitadel/deployment/container_test.go b/operator/zitadel/kinds/iam/zitadel/deployment/container_test.go index 65cc1134d..56210ef02 100644 --- a/operator/zitadel/kinds/iam/zitadel/deployment/container_test.go +++ b/operator/zitadel/kinds/iam/zitadel/deployment/container_test.go @@ -1,13 +1,17 @@ package deployment import ( + "fmt" + "testing" + + "github.com/caos/zitadel/operator/common" + "github.com/caos/orbos/pkg/kubernetes/k8s" "github.com/caos/zitadel/operator/helpers" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/intstr" - "testing" ) func TestDeployment_GetContainer(t *testing.T) { @@ -108,7 +112,7 @@ func TestDeployment_GetContainer(t *testing.T) { RunAsNonRoot: helpers.PointerBool(true), }, Name: containerName, - Image: zitadelImage + ":" + version, + Image: fmt.Sprintf("ghcr.io/%s:%s", common.ZITADELImage, version), ImagePullPolicy: corev1.PullIfNotPresent, Ports: []corev1.ContainerPort{ {Name: "grpc", ContainerPort: 50001}, @@ -164,6 +168,7 @@ func TestDeployment_GetContainer(t *testing.T) { users, dbSecrets, "start", + "", ) assert.Equal(t, equals, container) diff --git a/operator/zitadel/kinds/iam/zitadel/deployment/initcontainer.go b/operator/zitadel/kinds/iam/zitadel/deployment/initcontainer.go index d6de06f70..811f0f88d 100644 --- a/operator/zitadel/kinds/iam/zitadel/deployment/initcontainer.go +++ b/operator/zitadel/kinds/iam/zitadel/deployment/initcontainer.go @@ -1,10 +1,13 @@ package deployment import ( - corev1 "k8s.io/api/core/v1" "sort" "strconv" "strings" + + "github.com/caos/zitadel/operator/common" + + corev1 "k8s.io/api/core/v1" ) const ( @@ -17,6 +20,7 @@ func GetInitContainer( dbSecrets string, users []string, runAsUser int64, + customImageRegistry string, ) corev1.Container { initVolumeMounts := []corev1.VolumeMount{ @@ -47,7 +51,7 @@ func GetInitContainer( return corev1.Container{ Name: "fix-permissions", - Image: "alpine:3.11", + Image: common.AlpineImage.Reference(customImageRegistry), Command: []string{"/bin/sh", "-c"}, Args: []string{strings.Join(initCommands, " && ")}, VolumeMounts: initVolumeMounts, diff --git a/operator/zitadel/kinds/iam/zitadel/deployment/initcontainer_test.go b/operator/zitadel/kinds/iam/zitadel/deployment/initcontainer_test.go index b913cd837..24144fcbb 100644 --- a/operator/zitadel/kinds/iam/zitadel/deployment/initcontainer_test.go +++ b/operator/zitadel/kinds/iam/zitadel/deployment/initcontainer_test.go @@ -1,10 +1,11 @@ package deployment import ( - "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" "strings" "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" ) func TestDeployment_GetInitContainer(t *testing.T) { @@ -35,7 +36,7 @@ func TestDeployment_GetInitContainer(t *testing.T) { TerminationMessagePath: "/dev/termination-log", } - init := GetInitContainer(rootSecret, dbSecrets, users, RunAsUser) + init := GetInitContainer(rootSecret, dbSecrets, users, RunAsUser, "") assert.Equal(t, equals, init) } @@ -68,7 +69,7 @@ func TestDeployment_GetInitContainer1(t *testing.T) { ImagePullPolicy: corev1.PullIfNotPresent, } - init := GetInitContainer(rootSecret, dbSecrets, users, RunAsUser) + init := GetInitContainer(rootSecret, dbSecrets, users, RunAsUser, "") assert.Equal(t, equals, init) } @@ -104,7 +105,7 @@ func TestDeployment_GetInitContainer2(t *testing.T) { TerminationMessagePath: "/dev/termination-log", } - init := GetInitContainer(rootSecret, dbSecrets, users, RunAsUser) + init := GetInitContainer(rootSecret, dbSecrets, users, RunAsUser, "") assert.Equal(t, equals, init) } diff --git a/operator/zitadel/kinds/iam/zitadel/migration/adapt.go b/operator/zitadel/kinds/iam/zitadel/migration/adapt.go index d8ce50b23..2da9e6db4 100644 --- a/operator/zitadel/kinds/iam/zitadel/migration/adapt.go +++ b/operator/zitadel/kinds/iam/zitadel/migration/adapt.go @@ -4,13 +4,14 @@ import ( "crypto/sha512" "encoding/base64" "encoding/json" - "github.com/pkg/errors" - "github.com/rakyll/statik/fs" "os" "path/filepath" "regexp" "sort" + "github.com/pkg/errors" + "github.com/rakyll/statik/fs" + "github.com/caos/orbos/mntr" "github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes/resources/configmap" @@ -49,6 +50,7 @@ func AdaptFunc( users []string, nodeselector map[string]string, tolerations []corev1.Toleration, + customImageRegistry string, ) ( operator.QueryFunc, operator.DestroyFunc, @@ -103,9 +105,9 @@ func AdaptFunc( Spec: corev1.PodSpec{ NodeSelector: nodeselector, Tolerations: tolerations, - InitContainers: getPreContainer(dbHost, dbPort, migrationUser, secretPasswordName), + InitContainers: getPreContainer(dbHost, dbPort, migrationUser, secretPasswordName, customImageRegistry), Containers: []corev1.Container{ - getMigrationContainer(dbHost, dbPort, migrationUser, secretPasswordName, users), + getMigrationContainer(dbHost, dbPort, migrationUser, secretPasswordName, users, customImageRegistry), }, RestartPolicy: "Never", DNSPolicy: "ClusterFirst", diff --git a/operator/zitadel/kinds/iam/zitadel/migration/adapt_test.go b/operator/zitadel/kinds/iam/zitadel/migration/adapt_test.go index fbdadaa1a..488cdd8d6 100644 --- a/operator/zitadel/kinds/iam/zitadel/migration/adapt_test.go +++ b/operator/zitadel/kinds/iam/zitadel/migration/adapt_test.go @@ -99,9 +99,9 @@ func TestMigration_AdaptFunc(t *testing.T) { Spec: corev1.PodSpec{ NodeSelector: nodeselector, Tolerations: tolerations, - InitContainers: getPreContainer(dbHost, dbPort, migrationUser, secretPasswordName), + InitContainers: getPreContainer(dbHost, dbPort, migrationUser, secretPasswordName, ""), Containers: []corev1.Container{ - getMigrationContainer(dbHost, dbPort, migrationUser, secretPasswordName, users), + getMigrationContainer(dbHost, dbPort, migrationUser, secretPasswordName, users, ""), }, RestartPolicy: "Never", DNSPolicy: "ClusterFirst", @@ -163,6 +163,7 @@ func TestMigration_AdaptFunc(t *testing.T) { users, nodeselector, tolerations, + "", ) queried := map[string]interface{}{} diff --git a/operator/zitadel/kinds/iam/zitadel/migration/migrationcontainer.go b/operator/zitadel/kinds/iam/zitadel/migration/migrationcontainer.go index 10c94f4f1..d6a0bf6bf 100644 --- a/operator/zitadel/kinds/iam/zitadel/migration/migrationcontainer.go +++ b/operator/zitadel/kinds/iam/zitadel/migration/migrationcontainer.go @@ -3,6 +3,8 @@ package migration import ( "strings" + "github.com/caos/zitadel/operator/common" + corev1 "k8s.io/api/core/v1" ) @@ -12,10 +14,12 @@ func getMigrationContainer( migrationUser string, secretPasswordName string, users []string, + customImageRegistry string, ) corev1.Container { + return corev1.Container{ Name: "db-migration", - Image: "flyway/flyway:7.5.1", + Image: common.FlywayImage.Reference(customImageRegistry), Args: []string{ "-url=jdbc:postgresql://" + dbHost + ":" + dbPort + "/defaultdb?&sslmode=verify-full&ssl=true&sslrootcert=" + rootUserPath + "/ca.crt&sslfactory=org.postgresql.ssl.NonValidatingFactory", "-locations=filesystem:" + migrationsPath, diff --git a/operator/zitadel/kinds/iam/zitadel/migration/postcontainer.go b/operator/zitadel/kinds/iam/zitadel/migration/postcontainer.go index d8fbb9d7b..06d245f3a 100644 --- a/operator/zitadel/kinds/iam/zitadel/migration/postcontainer.go +++ b/operator/zitadel/kinds/iam/zitadel/migration/postcontainer.go @@ -1,8 +1,11 @@ package migration import ( - corev1 "k8s.io/api/core/v1" "strings" + + "github.com/caos/zitadel/operator/common" + + corev1 "k8s.io/api/core/v1" ) func getPostContainers( @@ -10,11 +13,13 @@ func getPostContainers( dbPort string, migrationUser string, secretPasswordName string, + customImageRegistry string, ) []corev1.Container { + return []corev1.Container{ { Name: "delete-flyway-user", - Image: "cockroachdb/cockroach:v20.2.3", + Image: common.CockroachImage.Reference(customImageRegistry), Command: []string{"/bin/bash", "-c", "--"}, Args: []string{ strings.Join([]string{ diff --git a/operator/zitadel/kinds/iam/zitadel/migration/precontainer.go b/operator/zitadel/kinds/iam/zitadel/migration/precontainer.go index ddd527f96..584279be9 100644 --- a/operator/zitadel/kinds/iam/zitadel/migration/precontainer.go +++ b/operator/zitadel/kinds/iam/zitadel/migration/precontainer.go @@ -1,8 +1,11 @@ package migration import ( - corev1 "k8s.io/api/core/v1" "strings" + + "github.com/caos/zitadel/operator/common" + + corev1 "k8s.io/api/core/v1" ) func getPreContainer( @@ -10,11 +13,13 @@ func getPreContainer( dbPort string, migrationUser string, secretPasswordName string, + customImageRegistry string, ) []corev1.Container { + return []corev1.Container{ { Name: "check-db-ready", - Image: "postgres:9.6.17", + Image: common.PostgresImage.Reference(customImageRegistry), Command: []string{ "sh", "-c", @@ -26,7 +31,7 @@ func getPreContainer( }, { Name: "create-flyway-user", - Image: "cockroachdb/cockroach:v20.2.3", + Image: common.CockroachImage.Reference(customImageRegistry), Env: baseEnvVars(envMigrationUser, envMigrationPW, migrationUser, secretPasswordName), VolumeMounts: []corev1.VolumeMount{{ Name: rootUserInternal, diff --git a/operator/zitadel/kinds/iam/zitadel/migration/precontainer_test.go b/operator/zitadel/kinds/iam/zitadel/migration/precontainer_test.go index 0d7848103..8b2d51e86 100644 --- a/operator/zitadel/kinds/iam/zitadel/migration/precontainer_test.go +++ b/operator/zitadel/kinds/iam/zitadel/migration/precontainer_test.go @@ -1,9 +1,10 @@ package migration import ( - "github.com/stretchr/testify/assert" "strings" "testing" + + "github.com/stretchr/testify/assert" ) func TestMigration_CreateUserCommand(t *testing.T) { diff --git a/operator/zitadel/kinds/iam/zitadel/setup/adapt.go b/operator/zitadel/kinds/iam/zitadel/setup/adapt.go index ae0f581d1..25446a627 100644 --- a/operator/zitadel/kinds/iam/zitadel/setup/adapt.go +++ b/operator/zitadel/kinds/iam/zitadel/setup/adapt.go @@ -37,6 +37,7 @@ func AdaptFunc( consoleCMName string, secretVarsName string, secretPasswordsName string, + customImageRegistry string, ) ( func( necessaryUsers map[string]string, @@ -82,9 +83,9 @@ func AdaptFunc( secretVarsName, secretPasswordsName, namespace, - componentLabels, nodeselector, tolerations, + customImageRegistry, ) hashes, err := getConfigurationHashes(k8sClient, queried, necessaryUsers) @@ -115,13 +116,30 @@ func AdaptFunc( } -func jobDef(name *labels.Name, users []string, version *string, resources *k8s.Resources, cmName string, certPath string, secretName string, secretPath string, consoleCMName string, secretVarsName string, secretPasswordsName string, namespace string, componentLabels *labels.Component, nodeselector map[string]string, tolerations []corev1.Toleration) *batchv1.Job { +func jobDef( + name *labels.Name, + users []string, + version *string, + resources *k8s.Resources, + cmName string, + certPath string, + secretName string, + secretPath string, + consoleCMName string, + secretVarsName string, + secretPasswordsName string, + namespace string, + nodeselector map[string]string, + tolerations []corev1.Toleration, + customImageRegistry string, +) *batchv1.Job { initContainers := []corev1.Container{ deployment.GetInitContainer( rootSecret, dbSecrets, users, deployment.RunAsUser, + customImageRegistry, )} containers := []corev1.Container{ @@ -141,6 +159,7 @@ func jobDef(name *labels.Name, users []string, version *string, resources *k8s.R users, dbSecrets, "setup", + customImageRegistry, )} volumes := deployment.GetVolumes(secretName, secretPasswordsName, consoleCMName, users) diff --git a/operator/zitadel/kinds/iam/zitadel/setup/adapt_test.go b/operator/zitadel/kinds/iam/zitadel/setup/adapt_test.go index 6e13654c8..3439274f0 100644 --- a/operator/zitadel/kinds/iam/zitadel/setup/adapt_test.go +++ b/operator/zitadel/kinds/iam/zitadel/setup/adapt_test.go @@ -60,7 +60,7 @@ func TestSetup_AdaptFunc(t *testing.T) { }, } - initContainers := []corev1.Container{deployment.GetInitContainer(rootSecret, dbSecrets, users, deployment.RunAsUser)} + initContainers := []corev1.Container{deployment.GetInitContainer(rootSecret, dbSecrets, users, deployment.RunAsUser, "")} containers := []corev1.Container{deployment.GetContainer( containerName, version, @@ -77,6 +77,7 @@ func TestSetup_AdaptFunc(t *testing.T) { users, dbSecrets, "setup", + "", )} volumes := deployment.GetVolumes(secretName, secretPasswordsName, consoleCMName, users) @@ -133,6 +134,7 @@ func TestSetup_AdaptFunc(t *testing.T) { consoleCMName, secretVarsName, secretPasswordsName, + "", ) queried := map[string]interface{}{} diff --git a/operator/zitadel/kinds/orb/adapt.go b/operator/zitadel/kinds/orb/adapt.go index c48cdcfe1..f385182df 100644 --- a/operator/zitadel/kinds/orb/adapt.go +++ b/operator/zitadel/kinds/orb/adapt.go @@ -93,6 +93,7 @@ func AdaptFunc( action, &desiredKind.Spec.Version, features, + desiredKind.Spec.CustomImageRegistry, ) if err != nil { return nil, nil, nil, nil, nil, false, err diff --git a/operator/zitadel/kinds/orb/desired.go b/operator/zitadel/kinds/orb/desired.go index 3903ed1c3..4e00beeaf 100644 --- a/operator/zitadel/kinds/orb/desired.go +++ b/operator/zitadel/kinds/orb/desired.go @@ -19,8 +19,8 @@ type Spec struct { Tolerations []corev1.Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"` Version string `json:"version,omitempty" yaml:"version,omitempty"` SelfReconciling bool `json:"selfReconciling" yaml:"selfReconciling"` - //Use this registry to pull the zitadel operator image from - //@default: ghcr.io + //Use this registry to pull container images from + //@default: CustomImageRegistry string `json:"customImageRegistry,omitempty" yaml:"customImageRegistry,omitempty"` } diff --git a/operator/zitadel/kinds/orb/reconcile.go b/operator/zitadel/kinds/orb/reconcile.go index 4063823b4..6c2e79c9c 100644 --- a/operator/zitadel/kinds/orb/reconcile.go +++ b/operator/zitadel/kinds/orb/reconcile.go @@ -24,11 +24,6 @@ func Reconcile( return err } - imageRegistry := spec.CustomImageRegistry - if imageRegistry == "" { - imageRegistry = "ghcr.io" - } - if spec.SelfReconciling { desiredTree := &tree.Tree{ Common: &tree.Common{ @@ -37,7 +32,7 @@ func Reconcile( }, } - if err := kubernetes.EnsureZitadelOperatorArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustZITADELOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, imageRegistry, gitops); err != nil { + if err := kubernetes.EnsureZitadelOperatorArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustZITADELOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, spec.CustomImageRegistry, gitops); err != nil { recMonitor.Error(errors.Wrap(err, "Failed to deploy zitadel-operator into k8s-cluster")) return err } diff --git a/pkg/kubernetes/artifacts.go b/pkg/kubernetes/artifacts.go index 7aadd48cd..f7ea5917f 100644 --- a/pkg/kubernetes/artifacts.go +++ b/pkg/kubernetes/artifacts.go @@ -1,7 +1,7 @@ package kubernetes import ( - "fmt" + "github.com/caos/zitadel/operator/common" "gopkg.in/yaml.v3" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -23,7 +23,7 @@ func EnsureZitadelOperatorArtifacts( version string, nodeselector map[string]string, tolerations []core.Toleration, - imageRegistry string, + customImageRegistry string, gitops bool, ) error { @@ -268,7 +268,7 @@ status: Containers: []core.Container{{ Name: "zitadel", ImagePullPolicy: core.PullIfNotPresent, - Image: fmt.Sprintf("%s/caos/zitadel-operator:%s", imageRegistry, version), + Image: common.ZITADELOperatorImage.Reference(customImageRegistry, version), Command: cmd, Args: []string{}, Ports: []core.ContainerPort{{ @@ -329,7 +329,7 @@ func EnsureDatabaseArtifacts( version string, nodeselector map[string]string, tolerations []core.Toleration, - imageRegistry string, + customImageRegistry string, gitops bool) error { monitor.WithFields(map[string]interface{}{ @@ -566,7 +566,7 @@ status: Containers: []core.Container{{ Name: "database", ImagePullPolicy: core.PullIfNotPresent, - Image: fmt.Sprintf("%s/caos/zitadel-operator:%s", imageRegistry, version), + Image: common.ZITADELOperatorImage.Reference(customImageRegistry, version), Command: cmd, Args: []string{}, Ports: []core.ContainerPort{{