From 98c80a4740ac0d787ce49329a2a4bdc9349ca316 Mon Sep 17 00:00:00 2001 From: Bohdan Siryk Date: Wed, 6 Mar 2024 16:06:26 +0200 Subject: [PATCH] implemented everything expect cadence --- .secrets.baseline | 8 ++- apis/clusters/v1beta1/generic_spec.go | 6 +++ .../clusters.instaclustr.com_cadences.yaml | 2 + .../clusters.instaclustr.com_cassandras.yaml | 2 + ...lusters.instaclustr.com_kafkaconnects.yaml | 2 + .../clusters.instaclustr.com_kafkas.yaml | 2 + ...clusters.instaclustr.com_opensearches.yaml | 2 + .../clusters.instaclustr.com_postgresqls.yaml | 2 + .../bases/clusters.instaclustr.com_redis.yaml | 2 + .../clusters.instaclustr.com_zookeepers.yaml | 2 + .../samples/clusters_v1beta1_cassandra.yaml | 3 +- config/samples/clusters_v1beta1_kafka.yaml | 13 ++--- .../samples/clusters_v1beta1_opensearch.yaml | 5 +- config/samples/clusters_v1beta1_redis.yaml | 4 +- .../samples/clusters_v1beta1_zookeeper.yaml | 3 +- controllers/clusters/cassandra_controller.go | 23 ++++---- controllers/clusters/kafka_controller.go | 54 +++++++++++++------ .../clusters/kafkaconnect_controller.go | 52 ++++++++++++------ controllers/clusters/opensearch_controller.go | 25 +++++---- controllers/clusters/postgresql_controller.go | 25 +++++---- controllers/clusters/redis_controller.go | 25 +++++---- controllers/clusters/zookeeper_controller.go | 50 +++++++++++------ 22 files changed, 215 insertions(+), 97 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index ca6d12f63..545dcbd70 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -75,6 +75,10 @@ { "path": "detect_secrets.filters.allowlist.is_line_allowlisted" }, + { + "path": "detect_secrets.filters.common.is_baseline_file", + "filename": ".secrets.baseline" + }, { "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", "min_level": 2 @@ -558,7 +562,7 @@ "filename": "controllers/clusters/postgresql_controller.go", "hashed_secret": "5ffe533b830f08a0326348a9160afafc8ada44db", "is_verified": false, - "line_number": 1192 + "line_number": 1199 } ], "controllers/clusters/zookeeper_controller_test.go": [ @@ -1130,5 +1134,5 @@ } ] }, - "generated_at": "2024-03-05T16:46:11Z" + "generated_at": "2024-03-06T14:06:22Z" } diff --git a/apis/clusters/v1beta1/generic_spec.go b/apis/clusters/v1beta1/generic_spec.go index d35cbc431..776b756e5 100644 --- a/apis/clusters/v1beta1/generic_spec.go +++ b/apis/clusters/v1beta1/generic_spec.go @@ -20,6 +20,8 @@ type GenericClusterSpec struct { Description string `json:"description,omitempty"` + InheritsFrom string `json:"inheritsFrom,omitempty"` + TwoFactorDelete []*TwoFactorDelete `json:"twoFactorDelete,omitempty"` } @@ -227,3 +229,7 @@ func (s *GenericDataCentreSpec) cloudProviderSettingsFromInstAPI(instaModel *mod }} } } + +func (s *GenericClusterSpec) Inherits() bool { + return s.InheritsFrom != "" +} diff --git a/config/crd/bases/clusters.instaclustr.com_cadences.yaml b/config/crd/bases/clusters.instaclustr.com_cadences.yaml index a1e1521fe..1f648be50 100644 --- a/config/crd/bases/clusters.instaclustr.com_cadences.yaml +++ b/config/crd/bases/clusters.instaclustr.com_cadences.yaml @@ -217,6 +217,8 @@ spec: type: array description: type: string + inheritsFrom: + type: string name: description: Name [ 3 .. 32 ] characters. type: string diff --git a/config/crd/bases/clusters.instaclustr.com_cassandras.yaml b/config/crd/bases/clusters.instaclustr.com_cassandras.yaml index 54bb7d321..a883b15c4 100644 --- a/config/crd/bases/clusters.instaclustr.com_cassandras.yaml +++ b/config/crd/bases/clusters.instaclustr.com_cassandras.yaml @@ -240,6 +240,8 @@ spec: type: array description: type: string + inheritsFrom: + type: string luceneEnabled: type: boolean name: diff --git a/config/crd/bases/clusters.instaclustr.com_kafkaconnects.yaml b/config/crd/bases/clusters.instaclustr.com_kafkaconnects.yaml index 734dc8342..9b4ee994b 100644 --- a/config/crd/bases/clusters.instaclustr.com_kafkaconnects.yaml +++ b/config/crd/bases/clusters.instaclustr.com_kafkaconnects.yaml @@ -269,6 +269,8 @@ spec: type: array description: type: string + inheritsFrom: + type: string name: description: Name [ 3 .. 32 ] characters. type: string diff --git a/config/crd/bases/clusters.instaclustr.com_kafkas.yaml b/config/crd/bases/clusters.instaclustr.com_kafkas.yaml index 24bb40720..77d7085df 100644 --- a/config/crd/bases/clusters.instaclustr.com_kafkas.yaml +++ b/config/crd/bases/clusters.instaclustr.com_kafkas.yaml @@ -225,6 +225,8 @@ spec: type: array description: type: string + inheritsFrom: + type: string karapaceRestProxy: items: properties: diff --git a/config/crd/bases/clusters.instaclustr.com_opensearches.yaml b/config/crd/bases/clusters.instaclustr.com_opensearches.yaml index 605e47edc..fdc26729e 100644 --- a/config/crd/bases/clusters.instaclustr.com_opensearches.yaml +++ b/config/crd/bases/clusters.instaclustr.com_opensearches.yaml @@ -229,6 +229,8 @@ spec: - nodeSize type: object type: array + inheritsFrom: + type: string knnPlugin: type: boolean loadBalancer: diff --git a/config/crd/bases/clusters.instaclustr.com_postgresqls.yaml b/config/crd/bases/clusters.instaclustr.com_postgresqls.yaml index 9758c2207..a1d3e219e 100644 --- a/config/crd/bases/clusters.instaclustr.com_postgresqls.yaml +++ b/config/crd/bases/clusters.instaclustr.com_postgresqls.yaml @@ -236,6 +236,8 @@ spec: - name type: object type: array + inheritsFrom: + type: string name: description: Name [ 3 .. 32 ] characters. type: string diff --git a/config/crd/bases/clusters.instaclustr.com_redis.yaml b/config/crd/bases/clusters.instaclustr.com_redis.yaml index b9dd7cc62..94928dae1 100644 --- a/config/crd/bases/clusters.instaclustr.com_redis.yaml +++ b/config/crd/bases/clusters.instaclustr.com_redis.yaml @@ -208,6 +208,8 @@ spec: type: array description: type: string + inheritsFrom: + type: string name: description: Name [ 3 .. 32 ] characters. type: string diff --git a/config/crd/bases/clusters.instaclustr.com_zookeepers.yaml b/config/crd/bases/clusters.instaclustr.com_zookeepers.yaml index 4ee17c34b..e52c9a89f 100644 --- a/config/crd/bases/clusters.instaclustr.com_zookeepers.yaml +++ b/config/crd/bases/clusters.instaclustr.com_zookeepers.yaml @@ -192,6 +192,8 @@ spec: type: array description: type: string + inheritsFrom: + type: string name: description: Name [ 3 .. 32 ] characters. type: string diff --git a/config/samples/clusters_v1beta1_cassandra.yaml b/config/samples/clusters_v1beta1_cassandra.yaml index 338ca2b85..e63c8ee63 100644 --- a/config/samples/clusters_v1beta1_cassandra.yaml +++ b/config/samples/clusters_v1beta1_cassandra.yaml @@ -3,8 +3,9 @@ kind: Cassandra metadata: name: cassandra-cluster spec: - name: "username-cassandra" #(immutable) + name: "bohdan-cassandra" #(immutable) version: "4.1.3" #(immutable) +# inheritsFrom: "42a0fa34-a647-4a30-96e0-fde64aba0eae" privateNetwork: false #(immutable) dataCentres: - name: "AWS_cassandra" #(mutable) diff --git a/config/samples/clusters_v1beta1_kafka.yaml b/config/samples/clusters_v1beta1_kafka.yaml index 3cef49ed2..9306eaaba 100644 --- a/config/samples/clusters_v1beta1_kafka.yaml +++ b/config/samples/clusters_v1beta1_kafka.yaml @@ -3,7 +3,8 @@ kind: Kafka metadata: name: kafka spec: - name: "example-kafka" + name: "bohdan-kafka" +# inheritsFrom: 42a0fa34-a647-4a30-96e0-fde64aba0eae version: "3.5.1" pciCompliance: false replicationFactor: 3 @@ -21,13 +22,13 @@ spec: # twoFactorDelete: # - email: "asdfadfsdsf" # phone: "ddsafasdf" - karapaceSchemaRegistry: - - version: "3.6.2" +# karapaceSchemaRegistry: +# - version: "3.6.2" # schemaRegistry: # - version: "3.0.0" - karapaceRestProxy: - - integrateRestProxyWithSchemaRegistry: true - version: "3.6.2" +# karapaceRestProxy: +# - integrateRestProxyWithSchemaRegistry: true +# version: "3.6.2" # kraft: # - controllerNodeCount: 3 # restProxy: diff --git a/config/samples/clusters_v1beta1_opensearch.yaml b/config/samples/clusters_v1beta1_opensearch.yaml index ff7d11d71..3c87c9dbe 100644 --- a/config/samples/clusters_v1beta1_opensearch.yaml +++ b/config/samples/clusters_v1beta1_opensearch.yaml @@ -7,11 +7,12 @@ metadata: app.kubernetes.io/part-of: operator app.kuberentes.io/managed-by: kustomize app.kubernetes.io/created-by: operator - name: opensearch-sample + name: opensearch-sample2 annotations: test.annotation/first: testAnnotation spec: - name: opensearch-test + name: bohdan-test2 + inheritsFrom: ed8a0dc3-0a41-4e94-a508-3d5cf4b1a28b alertingPlugin: false anomalyDetectionPlugin: false asynchronousSearchPlugin: false diff --git a/config/samples/clusters_v1beta1_redis.yaml b/config/samples/clusters_v1beta1_redis.yaml index 157fda6f1..67a993704 100644 --- a/config/samples/clusters_v1beta1_redis.yaml +++ b/config/samples/clusters_v1beta1_redis.yaml @@ -8,13 +8,15 @@ metadata: app.kuberentes.io/managed-by: kustomize app.kubernetes.io/created-by: operator name: redis-sample + namespace: nm1 spec: - name: "example-redis" + name: "bohdan-redis1" version: "7.0.14" slaTier: "NON_PRODUCTION" clientEncryption: false passwordAndUserAuth: true privateNetwork: false +# inheritsFrom: "83bb77aa-16fb-4f3e-b103-93b1c0352c1b" # userRefs: # - name: redisuser-sample-1 # namespace: default diff --git a/config/samples/clusters_v1beta1_zookeeper.yaml b/config/samples/clusters_v1beta1_zookeeper.yaml index 43cf66ab1..e0ce6726d 100644 --- a/config/samples/clusters_v1beta1_zookeeper.yaml +++ b/config/samples/clusters_v1beta1_zookeeper.yaml @@ -3,7 +3,8 @@ kind: Zookeeper metadata: name: zookeeper-sample spec: - name: "example-zookeeper" + name: "bohdan-zookeeper2" +# inheritsFrom: "3afa5885-116e-4414-b3ac-678d7d195baa" # description: "some description" dataCentres: - clientToServerEncryption: false diff --git a/controllers/clusters/cassandra_controller.go b/controllers/clusters/cassandra_controller.go index 1fb187fa7..9761ff286 100644 --- a/controllers/clusters/cassandra_controller.go +++ b/controllers/clusters/cassandra_controller.go @@ -214,20 +214,25 @@ func (r *CassandraReconciler) createCassandra(c *v1beta1.Cassandra, l logr.Logge } func (r *CassandraReconciler) createCluster(ctx context.Context, c *v1beta1.Cassandra, l logr.Logger) error { - var instModel *models.CassandraCluster - var err error + if !c.Spec.Inherits() { + id, err := getClusterIDByName(r.API, models.CassandraAppType, c.Spec.Name) + if err != nil { + return err + } - id, err := getClusterIDByName(r.API, models.CassandraAppType, c.Spec.Name) - if err != nil { - return err + if id != "" && c.Spec.Inherits() { + l.Info("Cluster with provided name already exists", "name", c.Spec.Name, "clusterID", id) + return fmt.Errorf("cluster %s already exists, please change name property", c.Spec.Name) + } } - if id != "" { - l.Info("Cluster with provided name already exists", "name", c.Spec.Name, "clusterID", id) - return fmt.Errorf("cluster %s already exists, please change name property", c.Spec.Name) - } + var instModel *models.CassandraCluster + var err error switch { + case c.Spec.Inherits(): + l.Info("Inheriting from the cluster", "clusterID", c.Spec.InheritsFrom) + instModel, err = r.API.GetCassandra(c.Spec.InheritsFrom) case c.Spec.HasRestore(): instModel, err = r.createCassandraFromRestore(c, l) default: diff --git a/controllers/clusters/kafka_controller.go b/controllers/clusters/kafka_controller.go index a41dd64c1..74cde4843 100644 --- a/controllers/clusters/kafka_controller.go +++ b/controllers/clusters/kafka_controller.go @@ -106,30 +106,20 @@ func (r *KafkaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl return models.ExitReconcile, nil } -func (r *KafkaReconciler) createCluster(ctx context.Context, k *v1beta1.Kafka, l logr.Logger) error { - id, err := getClusterIDByName(r.API, models.KafkaAppType, k.Spec.Name) - if err != nil { - return err - } - - if id != "" { - l.Info("Cluster with provided name already exists", "name", k.Spec.Name, "clusterID", id) - return fmt.Errorf("cluster %s already exists, please change name property", k.Spec.Name) - } - +func (r *KafkaReconciler) createKafka(k *v1beta1.Kafka, l logr.Logger) (*models.KafkaCluster, error) { l.Info("Creating cluster", "cluster name", k.Spec.Name, "data centres", k.Spec.DataCentres) b, err := r.API.CreateClusterRaw(instaclustr.KafkaEndpoint, k.Spec.ToInstAPI()) if err != nil { - return fmt.Errorf("failed to create kafka cluster, err: %w", err) + return nil, fmt.Errorf("failed to create kafka cluster, err: %w", err) } - instaModel := models.KafkaCluster{} - err = json.Unmarshal(b, &instaModel) + instaModel := &models.KafkaCluster{} + err = json.Unmarshal(b, instaModel) if err != nil { - return fmt.Errorf("failed to unmarshal json to kafka model, err: %w", err) + return nil, fmt.Errorf("failed to unmarshal json to kafka model, err: %w", err) } r.EventRecorder.Eventf( @@ -138,14 +128,44 @@ func (r *KafkaReconciler) createCluster(ctx context.Context, k *v1beta1.Kafka, l instaModel.ID, ) - k.Spec.FromInstAPI(&instaModel) + return instaModel, nil +} + +func (r *KafkaReconciler) createCluster(ctx context.Context, k *v1beta1.Kafka, l logr.Logger) error { + if !k.Spec.Inherits() { + id, err := getClusterIDByName(r.API, models.KafkaAppType, k.Spec.Name) + if err != nil { + return err + } + + if id != "" { + l.Info("Cluster with provided name already exists", "name", k.Spec.Name, "clusterID", id) + return fmt.Errorf("cluster %s already exists, please change name property", k.Spec.Name) + } + } + + var instaModel *models.KafkaCluster + var err error + + switch { + case k.Spec.Inherits(): + l.Info("Inheriting from the cluster", "clusterID", k.Spec.InheritsFrom) + instaModel, err = r.API.GetKafka(k.Spec.InheritsFrom) + default: + instaModel, err = r.createKafka(k, l) + } + if err != nil { + return err + } + + k.Spec.FromInstAPI(instaModel) k.Annotations[models.ResourceStateAnnotation] = models.SyncingEvent err = r.Update(ctx, k) if err != nil { return fmt.Errorf("failed to update kafka spec, err: %w", err) } - k.Status.FromInstAPI(&instaModel) + k.Status.FromInstAPI(instaModel) err = r.Status().Update(ctx, k) if err != nil { return fmt.Errorf("failed to update kafka status, err: %w", err) diff --git a/controllers/clusters/kafkaconnect_controller.go b/controllers/clusters/kafkaconnect_controller.go index 05b39c292..c67c5f643 100644 --- a/controllers/clusters/kafkaconnect_controller.go +++ b/controllers/clusters/kafkaconnect_controller.go @@ -122,41 +122,61 @@ func (r *KafkaConnectReconciler) mergeManagedClusterFromRef(ctx context.Context, return nil } -func (r *KafkaConnectReconciler) createCluster(ctx context.Context, kc *v1beta1.KafkaConnect, l logr.Logger) error { - id, err := getClusterIDByName(r.API, models.KafkaConnectAppType, kc.Spec.Name) +func (r *KafkaConnectReconciler) createKafkaConnect(ctx context.Context, kc *v1beta1.KafkaConnect) (*models.KafkaConnectCluster, error) { + err := r.mergeManagedClusterFromRef(ctx, kc) if err != nil { - return err + return nil, err } - if id != "" { - l.Info("Cluster with provided name already exists", "name", kc.Spec.Name, "clusterID", id) - return fmt.Errorf("cluster %s already exists, please change name property", kc.Spec.Name) + b, err := r.API.CreateClusterRaw(instaclustr.KafkaConnectEndpoint, kc.Spec.ToInstAPI()) + if err != nil { + return nil, fmt.Errorf("failed to create KafkaConnect cluster, err: %w", err) } - err = r.mergeManagedClusterFromRef(ctx, kc) + var instaModel models.KafkaConnectCluster + err = json.Unmarshal(b, &instaModel) if err != nil { - return err + return nil, fmt.Errorf("failed to unmarshal body to KafkaConnect model, err: %w", err) } - b, err := r.API.CreateClusterRaw(instaclustr.KafkaConnectEndpoint, kc.Spec.ToInstAPI()) - if err != nil { - return fmt.Errorf("failed to create KafkaConnect cluster, err: %w", err) + return &instaModel, nil +} + +func (r *KafkaConnectReconciler) createCluster(ctx context.Context, kc *v1beta1.KafkaConnect, l logr.Logger) error { + if !kc.Spec.Inherits() { + id, err := getClusterIDByName(r.API, models.KafkaConnectAppType, kc.Spec.Name) + if err != nil { + return err + } + + if id != "" { + l.Info("Cluster with provided name already exists", "name", kc.Spec.Name, "clusterID", id) + return fmt.Errorf("cluster %s already exists, please change name property", kc.Spec.Name) + } } - var instaModel models.KafkaConnectCluster - err = json.Unmarshal(b, &instaModel) + var instaModel *models.KafkaConnectCluster + var err error + + switch { + case kc.Spec.Inherits(): + l.Info("Inheriting from the cluster", "clusterID", kc.Spec.InheritsFrom) + instaModel, err = r.API.GetKafkaConnect(kc.Spec.InheritsFrom) + default: + instaModel, err = r.createKafkaConnect(ctx, kc) + } if err != nil { - return fmt.Errorf("failed to unmarshal body to KafkaConnect model, err: %w", err) + return err } - kc.Spec.FromInstAPI(&instaModel) + kc.Spec.FromInstAPI(instaModel) kc.Annotations[models.ResourceStateAnnotation] = models.SyncingEvent err = r.Update(ctx, kc) if err != nil { return fmt.Errorf("failed to update resource spec, err: %w", err) } - kc.Status.FromInstAPI(&instaModel) + kc.Status.FromInstAPI(instaModel) err = r.Status().Update(ctx, kc) if err != nil { return fmt.Errorf("failed to update resource status, err: %w", err) diff --git a/controllers/clusters/opensearch_controller.go b/controllers/clusters/opensearch_controller.go index 98e8df7a5..995211899 100644 --- a/controllers/clusters/opensearch_controller.go +++ b/controllers/clusters/opensearch_controller.go @@ -182,21 +182,28 @@ func (r *OpenSearchReconciler) createOpenSearch(o *v1beta1.OpenSearch, logger lo } func (r *OpenSearchReconciler) createCluster(ctx context.Context, o *v1beta1.OpenSearch, logger logr.Logger) error { - id, err := getClusterIDByName(r.API, models.OpenSearchAppType, o.Spec.Name) - if err != nil { - return err - } + if !o.Spec.Inherits() { + id, err := getClusterIDByName(r.API, models.OpenSearchAppType, o.Spec.Name) + if err != nil { + return err + } - if id != "" { - logger.Info("Cluster with provided name already exists", "name", o.Spec.Name, "clusterID", id) - return fmt.Errorf("cluster %s already exists, please change name property", o.Spec.Name) + if id != "" { + logger.Info("Cluster with provided name already exists", "name", o.Spec.Name, "clusterID", id) + return fmt.Errorf("cluster %s already exists, please change name property", o.Spec.Name) + } } var instaModel *models.OpenSearchCluster + var err error - if o.Spec.HasRestore() { + switch { + case o.Spec.Inherits(): + instaModel, err = r.API.GetOpenSearch(o.Spec.InheritsFrom) + case o.Spec.HasRestore(): + logger.Info("Inheriting from the cluster", "clusterID", o.Spec.InheritsFrom) instaModel, err = r.createOpenSearchFromRestore(o, logger) - } else { + default: instaModel, err = r.createOpenSearch(o, logger) } if err != nil { diff --git a/controllers/clusters/postgresql_controller.go b/controllers/clusters/postgresql_controller.go index b422c4111..0f9934091 100644 --- a/controllers/clusters/postgresql_controller.go +++ b/controllers/clusters/postgresql_controller.go @@ -181,21 +181,28 @@ func (r *PostgreSQLReconciler) createPostgreSQL(pg *v1beta1.PostgreSQL, l logr.L } func (r *PostgreSQLReconciler) createCluster(ctx context.Context, pg *v1beta1.PostgreSQL, l logr.Logger) error { - id, err := getClusterIDByName(r.API, models.PgAppType, pg.Spec.Name) - if err != nil { - return err - } + if !pg.Spec.Inherits() { + id, err := getClusterIDByName(r.API, models.PgAppType, pg.Spec.Name) + if err != nil { + return err + } - if id != "" { - l.Info("Cluster with provided name already exists", "name", pg.Spec.Name, "clusterID", id) - return fmt.Errorf("cluster %s already exists, please change name property", pg.Spec.Name) + if id != "" { + l.Info("Cluster with provided name already exists", "name", pg.Spec.Name, "clusterID", id) + return fmt.Errorf("cluster %s already exists, please change name property", pg.Spec.Name) + } } var instaModel *models.PGCluster + var err error - if pg.Spec.HasRestore() { + switch { + case pg.Spec.Inherits(): + l.Info("Inheriting from the cluster", "clusterID", pg.Spec.InheritsFrom) + instaModel, err = r.API.GetPostgreSQL(pg.Spec.InheritsFrom) + case pg.Spec.HasRestore(): instaModel, err = r.createFromRestore(pg, l) - } else { + default: instaModel, err = r.createPostgreSQL(pg, l) } if err != nil { diff --git a/controllers/clusters/redis_controller.go b/controllers/clusters/redis_controller.go index af75480ad..d2cfd01f5 100644 --- a/controllers/clusters/redis_controller.go +++ b/controllers/clusters/redis_controller.go @@ -181,21 +181,28 @@ func (r *RedisReconciler) createRedis(redis *v1beta1.Redis, l logr.Logger) (*mod } func (r *RedisReconciler) createCluster(ctx context.Context, redis *v1beta1.Redis, l logr.Logger) error { - id, err := getClusterIDByName(r.API, models.RedisAppType, redis.Spec.Name) - if err != nil { - return err - } + if !redis.Spec.Inherits() { + id, err := getClusterIDByName(r.API, models.RedisAppType, redis.Spec.Name) + if err != nil { + return err + } - if id != "" { - l.Info("Cluster with provided name already exists", "name", redis.Spec.Name, "clusterID", id) - return fmt.Errorf("cluster %s already exists, please change name property", redis.Spec.Name) + if id != "" { + l.Info("Cluster with provided name already exists", "name", redis.Spec.Name, "clusterID", id) + return fmt.Errorf("cluster %s already exists, please change name property", redis.Spec.Name) + } } var instaModel *models.RedisCluster + var err error - if redis.Spec.HasRestore() { + switch { + case redis.Spec.Inherits(): + l.Info("Inheriting from the cluster", "clusterID", redis.Spec.InheritsFrom) + instaModel, err = r.API.GetRedis(redis.Spec.InheritsFrom) + case redis.Spec.HasRestore(): instaModel, err = r.createFromRestore(redis, l) - } else { + default: instaModel, err = r.createRedis(redis, l) } if err != nil { diff --git a/controllers/clusters/zookeeper_controller.go b/controllers/clusters/zookeeper_controller.go index f20c31816..a7420b37c 100644 --- a/controllers/clusters/zookeeper_controller.go +++ b/controllers/clusters/zookeeper_controller.go @@ -103,42 +103,62 @@ func (r *ZookeeperReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( } } -func (r *ZookeeperReconciler) createCluster(ctx context.Context, zook *v1beta1.Zookeeper, l logr.Logger) error { - id, err := getClusterIDByName(r.API, models.ZookeeperAppType, zook.Spec.Name) - if err != nil { - return err - } - - if id != "" { - l.Info("Cluster with provided name already exists", "name", zook.Spec.Name, "clusterID", id) - return fmt.Errorf("cluster %s already exists, please change name property", zook.Spec.Name) - } - +func (r *ZookeeperReconciler) createZookeeper(zook *v1beta1.Zookeeper, l logr.Logger) (*models.ZookeeperCluster, error) { l.Info("Creating zookeeper cluster", "cluster name", zook.Spec.Name, "data centres", zook.Spec.DataCentres) b, err := r.API.CreateClusterRaw(instaclustr.ZookeeperEndpoint, zook.Spec.ToInstAPI()) if err != nil { - return fmt.Errorf("failed to create zookeeper cluster, err: %w", err) + return nil, fmt.Errorf("failed to create zookeeper cluster, err: %w", err) } var instaModel models.ZookeeperCluster err = json.Unmarshal(b, &instaModel) if err != nil { - return fmt.Errorf("failed to unmarshal body to models.ZookeeperCluster, err: %w", err) + return nil, fmt.Errorf("failed to unmarshal body to models.ZookeeperCluster, err: %w", err) + } + + return &instaModel, err +} + +func (r *ZookeeperReconciler) createCluster(ctx context.Context, zook *v1beta1.Zookeeper, l logr.Logger) error { + if !zook.Spec.Inherits() { + id, err := getClusterIDByName(r.API, models.ZookeeperAppType, zook.Spec.Name) + if err != nil { + return err + } + + if id != "" { + l.Info("Cluster with provided name already exists", "name", zook.Spec.Name, "clusterID", id) + return fmt.Errorf("cluster %s already exists, please change name property", zook.Spec.Name) + } + } + + var instaModel *models.ZookeeperCluster + var err error + + switch { + case zook.Spec.Inherits(): + l.Info("Inheriting from the cluster", "clusterID", zook.Spec.InheritsFrom) + instaModel, err = r.API.GetZookeeper(zook.Spec.InheritsFrom) + default: + instaModel, err = r.createZookeeper(zook, l) + } + if err != nil { + return err } patch := zook.NewPatch() - zook.Spec.FromInstAPI(&instaModel) + zook.Spec.FromInstAPI(instaModel) zook.Annotations[models.ResourceStateAnnotation] = models.SyncingEvent err = r.Patch(ctx, zook, patch) if err != nil { return fmt.Errorf("failed to patch cluster spec, err: %w", err) } - zook.Status.FromInstAPI(&instaModel) + zook.Status.FromInstAPI(instaModel) err = r.Status().Patch(ctx, zook, patch) if err != nil { return fmt.Errorf("failed to patch cluster status, err: %w", err)