Skip to content

Commit

Permalink
issue-711, avoiding cluster creation if cluster with provided name ex…
Browse files Browse the repository at this point in the history
…ists was implemented
  • Loading branch information
worryg0d committed Mar 4, 2024
1 parent a169e1d commit ce82931
Show file tree
Hide file tree
Showing 13 changed files with 131 additions and 23 deletions.
10 changes: 5 additions & 5 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -535,14 +535,14 @@
"filename": "controllers/clusters/helpers.go",
"hashed_secret": "5ffe533b830f08a0326348a9160afafc8ada44db",
"is_verified": false,
"line_number": 119
"line_number": 120
},
{
"type": "Secret Keyword",
"filename": "controllers/clusters/helpers.go",
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
"is_verified": false,
"line_number": 124
"line_number": 125
}
],
"controllers/clusters/kafkaconnect_controller_test.go": [
Expand All @@ -560,7 +560,7 @@
"filename": "controllers/clusters/postgresql_controller.go",
"hashed_secret": "5ffe533b830f08a0326348a9160afafc8ada44db",
"is_verified": false,
"line_number": 1183
"line_number": 1195
}
],
"controllers/clusters/zookeeper_controller_test.go": [
Expand Down Expand Up @@ -725,7 +725,7 @@
"filename": "pkg/instaclustr/client.go",
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
"is_verified": false,
"line_number": 2084
"line_number": 2085
}
],
"pkg/instaclustr/mock/client.go": [
Expand Down Expand Up @@ -1132,5 +1132,5 @@
}
]
},
"generated_at": "2024-02-29T10:48:32Z"
"generated_at": "2024-03-04T15:12:08Z"
}
18 changes: 16 additions & 2 deletions controllers/clusters/cassandra_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,23 @@ func (r *CassandraReconciler) createCluster(ctx context.Context, c *v1beta1.Cass
var instModel *models.CassandraCluster
var err error

if c.Spec.HasRestore() {
id, err := getClusterIDByName(r.API, models.CassandraAppType, c.Spec.Name)
if err != nil {
return err
}

if id != "" {
l.Info("Cluster with provided name already exists", "name", c.Spec.Name, "clusterID", id)
r.EventRecorder.Eventf(c, models.Warning, models.CreationFailed,
"Failed to create cluster. Cluster %s already exists", c.Spec.Name,
)
return fmt.Errorf("cluster %s already exists", c.Spec.Name)
}

switch {
case c.Spec.HasRestore():
instModel, err = r.createCassandraFromRestore(c, l)
} else {
default:
instModel, err = r.createCassandra(c, l)
}
if err != nil {
Expand Down
18 changes: 18 additions & 0 deletions controllers/clusters/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

"github.com/instaclustr/operator/pkg/instaclustr"
"github.com/instaclustr/operator/pkg/models"
"github.com/instaclustr/operator/pkg/utils/dcomparison"
)
Expand Down Expand Up @@ -238,3 +239,20 @@ func reconcileExternalChanges(c client.Client, r record.EventRecorder, obj Objec

return nil
}

func getClusterIDByName(api instaclustr.API, appType string, name string) (string, error) {
clusters, err := api.ListClustersByName(name)
if err != nil {
return "", fmt.Errorf("failed to list clusters by name, err: %w", err)
}

if len(clusters) == 0 {
return "", nil
}

if clusters[0].Application != appType {
return "", fmt.Errorf("the cluster %s already exists, but it has other application type %s", name, clusters[0].Application)
}

return clusters[0].ID, nil
}
13 changes: 13 additions & 0 deletions controllers/clusters/kafka_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,19 @@ func (r *KafkaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl
}

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)
r.EventRecorder.Eventf(k, models.Warning, models.CreationFailed,
"Failed to create cluster. Cluster %s already exists", k.Spec.Name,
)
return fmt.Errorf("cluster %s already exists", k.Spec.Name)
}

l.Info("Creating cluster",
"cluster name", k.Spec.Name,
"data centres", k.Spec.DataCentres)
Expand Down
15 changes: 14 additions & 1 deletion controllers/clusters/kafkaconnect_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,20 @@ func (r *KafkaConnectReconciler) mergeManagedClusterFromRef(ctx context.Context,
}

func (r *KafkaConnectReconciler) createCluster(ctx context.Context, kc *v1beta1.KafkaConnect, l logr.Logger) error {
err := r.mergeManagedClusterFromRef(ctx, kc)
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)
r.EventRecorder.Eventf(kc, models.Warning, models.CreationFailed,
"Failed to create cluster. Cluster %s already exists", kc.Spec.Name,
)
return fmt.Errorf("cluster %s already exists", kc.Spec.Name)
}

err = r.mergeManagedClusterFromRef(ctx, kc)
if err != nil {
return err
}
Expand Down
14 changes: 13 additions & 1 deletion controllers/clusters/opensearch_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,20 @@ 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 id != "" {
logger.Info("Cluster with provided name already exists", "name", o.Spec.Name, "clusterID", id)
r.EventRecorder.Eventf(o, models.Warning, models.CreationFailed,
"Failed to create cluster. Cluster %s already exists", o.Spec.Name,
)
return fmt.Errorf("cluster %s already exists", o.Spec.Name)
}

var instaModel *models.OpenSearchCluster
var err error

if o.Spec.HasRestore() {
instaModel, err = r.createOpenSearchFromRestore(o, logger)
Expand Down
14 changes: 13 additions & 1 deletion controllers/clusters/postgresql_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,20 @@ 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 id != "" {
l.Info("Cluster with provided name already exists", "name", pg.Spec.Name, "clusterID", id)
r.EventRecorder.Eventf(pg, models.Warning, models.CreationFailed,
"Failed to create cluster. Cluster %s already exists", pg.Spec.Name,
)
return fmt.Errorf("cluster %s already exists", pg.Spec.Name)
}

var instaModel *models.PGCluster
var err error

if pg.Spec.HasRestore() {
instaModel, err = r.createFromRestore(pg, l)
Expand Down
14 changes: 13 additions & 1 deletion controllers/clusters/redis_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,20 @@ 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 id != "" {
l.Info("Cluster with provided name already exists", "name", redis.Spec.Name, "clusterID", id)
r.EventRecorder.Eventf(redis, models.Warning, models.CreationFailed,
"Failed to create cluster. Cluster %s already exists", redis.Spec.Name,
)
return fmt.Errorf("cluster %s already exists", redis.Spec.Name)
}

var instaModel *models.RedisCluster
var err error

if redis.Spec.HasRestore() {
instaModel, err = r.createFromRestore(redis, l)
Expand Down
13 changes: 13 additions & 0 deletions controllers/clusters/zookeeper_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ 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)
r.EventRecorder.Eventf(zook, models.Warning, models.CreationFailed,
"Failed to create cluster. Cluster %s already exists", zook.Spec.Name,
)
return fmt.Errorf("cluster %s already exists", zook.Spec.Name)
}

l.Info("Creating zookeeper cluster",
"cluster name", zook.Spec.Name,
"data centres", zook.Spec.DataCentres)
Expand Down
9 changes: 6 additions & 3 deletions pkg/instaclustr/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"io"
"net/http"
"strings"
"time"

clusterresourcesv1beta1 "github.com/instaclustr/operator/apis/clusterresources/v1beta1"
Expand Down Expand Up @@ -2112,8 +2113,10 @@ func (c *Client) UpdatePostgreSQLDefaultUserPassword(id, password string) error
return nil
}

func (c *Client) ListClusters() ([]*models.ActiveClusters, error) {
url := c.serverHostname + ClustersEndpoint
func (c *Client) ListClustersByName(name string) ([]*models.ActiveCluster, error) {
url := c.serverHostname + ClustersEndpoint + fmt.Sprintf("?search=name:%s", name)
url = strings.ReplaceAll(url, " ", "%20")

resp, err := c.DoRequest(url, http.MethodGet, nil)
if err != nil {
return nil, err
Expand All @@ -2135,7 +2138,7 @@ func (c *Client) ListClusters() ([]*models.ActiveClusters, error) {
return nil, err
}

return response, nil
return response[0].Clusters, nil
}

func (c *Client) CreateEncryptionKey(
Expand Down
2 changes: 1 addition & 1 deletion pkg/instaclustr/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ type API interface {
ResetPostgreSQLConfiguration(id, name string) error
GetCadence(id string) (*models.CadenceCluster, error)
UpdatePostgreSQLDefaultUserPassword(id, password string) error
ListClusters() ([]*models.ActiveClusters, error)
ListClustersByName(name string) ([]*models.ActiveCluster, error)
CreateEncryptionKey(encryptionKeySpec any) (*clusterresourcesv1beta1.AWSEncryptionKeyStatus, error)
GetEncryptionKeyStatus(encryptionKeyID string, encryptionKeyEndpoint string) (*clusterresourcesv1beta1.AWSEncryptionKeyStatus, error)
DeleteEncryptionKey(encryptionKeyID string) error
Expand Down
4 changes: 2 additions & 2 deletions pkg/instaclustr/mock/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ func (c *mockClient) UpdateKafkaConnect(id string, kc models.KafkaConnectAPIUpda
panic("UpdateKafkaConnect: is not implemented")
}

func (c *mockClient) ListClusters() ([]*models.ActiveClusters, error) {
panic("ListClusters: is not implemented")
func (c *mockClient) ListClustersByName(name string) ([]*models.ActiveCluster, error) {
panic("ListClustersByName: is not implemented")
}

func (c *mockClient) CreateRedisUser(user *models.RedisUser) (string, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ package openapi

import (
"context"
"errors"
"net/http"
)

// AccountClusterListV2APIService is a service that implements the logic for the AccountClusterListV2APIServicer
Expand All @@ -31,8 +29,8 @@ func (s *AccountClusterListV2APIService) ClusterManagementV2DataSourcesClustersV
// TODO - update ClusterManagementV2DataSourcesClustersV2Get with the required logic for this service method.
// Add api_account_cluster_list_v2_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.

// TODO: Uncomment the next line to return response Response(200, []AccountClustersV2{}) or use other options such as http.Ok ...
// return Response(200, []AccountClustersV2{}), nil

return Response(http.StatusNotImplemented, nil), errors.New("ClusterManagementV2DataSourcesClustersV2Get method not implemented")
return Response(200, []AccountClustersV2{{
AccountId: "test-account-id",
Clusters: []ClusterSummaryV2{},
}}), nil
}

0 comments on commit ce82931

Please sign in to comment.