diff --git a/internal/controller/cloud-control/rediscluster_controller.go b/internal/controller/cloud-control/rediscluster_controller.go index 44bef904..d1954c24 100644 --- a/internal/controller/cloud-control/rediscluster_controller.go +++ b/internal/controller/cloud-control/rediscluster_controller.go @@ -23,6 +23,9 @@ import ( "github.com/kyma-project/cloud-manager/pkg/common/abstractions" "github.com/kyma-project/cloud-manager/pkg/common/actions/focal" "github.com/kyma-project/cloud-manager/pkg/composed" + awsrediscluster "github.com/kyma-project/cloud-manager/pkg/kcp/provider/aws/rediscluster" + azurerediscluster "github.com/kyma-project/cloud-manager/pkg/kcp/provider/azure/rediscluster" + gcprediscluster "github.com/kyma-project/cloud-manager/pkg/kcp/provider/gcp/rediscluster" "github.com/kyma-project/cloud-manager/pkg/kcp/rediscluster" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" @@ -34,10 +37,16 @@ func SetupRedisClusterReconciler( kcpManager manager.Manager, env abstractions.Environment, ) error { + if env == nil { + env = abstractions.NewOSEnvironment() + } return NewRedisClusterReconciler( rediscluster.NewRedisClusterReconciler( composed.NewStateFactory(composed.NewStateClusterFromCluster(kcpManager)), focal.NewStateFactory(), + gcprediscluster.NewStateFactory(env), + awsrediscluster.NewStateFactory(), + azurerediscluster.NewStateFactory(), ), ).SetupWithManager(kcpManager) } diff --git a/pkg/kcp/provider/aws/rediscluster/new.go b/pkg/kcp/provider/aws/rediscluster/new.go new file mode 100644 index 00000000..4d76f091 --- /dev/null +++ b/pkg/kcp/provider/aws/rediscluster/new.go @@ -0,0 +1,51 @@ +package rediscluster + +import ( + "context" + "fmt" + + "github.com/kyma-project/cloud-manager/pkg/common/actions" + "github.com/kyma-project/cloud-manager/pkg/kcp/rediscluster/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1" + cloudcontrolv1beta1 "github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1" + "github.com/kyma-project/cloud-manager/pkg/composed" +) + +func New(stateFactory StateFactory) composed.Action { + return func(ctx context.Context, st composed.State) (error, context.Context) { + + state, err := stateFactory.NewState(ctx, st.(types.State)) + if err != nil { + composed.LoggerFromCtx(ctx).Error(err, "Failed to bootstrap AWS RedisCluster state") + redisCluster := st.Obj().(*v1beta1.RedisCluster) + redisCluster.Status.State = cloudcontrolv1beta1.StateError + return composed.UpdateStatus(redisCluster). + SetExclusiveConditions(metav1.Condition{ + Type: v1beta1.ConditionTypeError, + Status: metav1.ConditionTrue, + Reason: v1beta1.ReasonCloudProviderError, + Message: "Failed to create RedisCluster state", + }). + SuccessError(composed.StopAndForget). + SuccessLogMsg(fmt.Sprintf("Error creating new AWS RedisCluster state: %s", err)). + Run(ctx, st) + } + + return composed.ComposeActions( + "redisCluster", + actions.AddCommonFinalizer(), + composed.IfElse(composed.Not(composed.MarkedForDeletionPredicate), + composed.ComposeActions( + "redisCluster-create", + ), + composed.ComposeActions( + "redisCluster-delete", + actions.RemoveCommonFinalizer(), + ), + ), + composed.StopAndForgetAction, + )(ctx, state) + } +} diff --git a/pkg/kcp/provider/aws/rediscluster/state.go b/pkg/kcp/provider/aws/rediscluster/state.go new file mode 100644 index 00000000..68edb6ba --- /dev/null +++ b/pkg/kcp/provider/aws/rediscluster/state.go @@ -0,0 +1,32 @@ +package rediscluster + +import ( + "context" + + "github.com/kyma-project/cloud-manager/pkg/kcp/rediscluster/types" +) + +type State struct { + types.State +} + +type StateFactory interface { + NewState(ctx context.Context, redisClusterState types.State) (*State, error) +} + +type stateFactory struct{} + +func NewStateFactory() StateFactory { + return &stateFactory{} +} + +func (statefactory *stateFactory) NewState(ctx context.Context, redisClusterState types.State) (*State, error) { + + return newState(redisClusterState), nil +} + +func newState(redisClusterState types.State) *State { + return &State{ + State: redisClusterState, + } +} diff --git a/pkg/kcp/provider/azure/rediscluster/new.go b/pkg/kcp/provider/azure/rediscluster/new.go new file mode 100644 index 00000000..e4b777da --- /dev/null +++ b/pkg/kcp/provider/azure/rediscluster/new.go @@ -0,0 +1,51 @@ +package rediscluster + +import ( + "context" + "fmt" + + "github.com/kyma-project/cloud-manager/pkg/common/actions" + "github.com/kyma-project/cloud-manager/pkg/kcp/rediscluster/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1" + cloudcontrolv1beta1 "github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1" + "github.com/kyma-project/cloud-manager/pkg/composed" +) + +func New(stateFactory StateFactory) composed.Action { + return func(ctx context.Context, st composed.State) (error, context.Context) { + + state, err := stateFactory.NewState(ctx, st.(types.State)) + if err != nil { + composed.LoggerFromCtx(ctx).Error(err, "Failed to bootstrap Azure RedisCluster state") + redisCluster := st.Obj().(*v1beta1.RedisCluster) + redisCluster.Status.State = cloudcontrolv1beta1.StateError + return composed.UpdateStatus(redisCluster). + SetExclusiveConditions(metav1.Condition{ + Type: v1beta1.ConditionTypeError, + Status: metav1.ConditionTrue, + Reason: v1beta1.ReasonCloudProviderError, + Message: "Failed to create RedisCluster state", + }). + SuccessError(composed.StopAndForget). + SuccessLogMsg(fmt.Sprintf("Error creating new Azure RedisCluster state: %s", err)). + Run(ctx, st) + } + + return composed.ComposeActions( + "redisCluster", + actions.AddCommonFinalizer(), + composed.IfElse(composed.Not(composed.MarkedForDeletionPredicate), + composed.ComposeActions( + "redisCluster-create", + ), + composed.ComposeActions( + "redisCluster-delete", + actions.RemoveCommonFinalizer(), + ), + ), + composed.StopAndForgetAction, + )(ctx, state) + } +} diff --git a/pkg/kcp/provider/azure/rediscluster/state.go b/pkg/kcp/provider/azure/rediscluster/state.go new file mode 100644 index 00000000..68edb6ba --- /dev/null +++ b/pkg/kcp/provider/azure/rediscluster/state.go @@ -0,0 +1,32 @@ +package rediscluster + +import ( + "context" + + "github.com/kyma-project/cloud-manager/pkg/kcp/rediscluster/types" +) + +type State struct { + types.State +} + +type StateFactory interface { + NewState(ctx context.Context, redisClusterState types.State) (*State, error) +} + +type stateFactory struct{} + +func NewStateFactory() StateFactory { + return &stateFactory{} +} + +func (statefactory *stateFactory) NewState(ctx context.Context, redisClusterState types.State) (*State, error) { + + return newState(redisClusterState), nil +} + +func newState(redisClusterState types.State) *State { + return &State{ + State: redisClusterState, + } +} diff --git a/pkg/kcp/provider/gcp/rediscluster/new.go b/pkg/kcp/provider/gcp/rediscluster/new.go new file mode 100644 index 00000000..752cc9a3 --- /dev/null +++ b/pkg/kcp/provider/gcp/rediscluster/new.go @@ -0,0 +1,51 @@ +package rediscluster + +import ( + "context" + "fmt" + + "github.com/kyma-project/cloud-manager/pkg/common/actions" + "github.com/kyma-project/cloud-manager/pkg/kcp/rediscluster/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1" + cloudcontrolv1beta1 "github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1" + "github.com/kyma-project/cloud-manager/pkg/composed" +) + +func New(stateFactory StateFactory) composed.Action { + return func(ctx context.Context, st composed.State) (error, context.Context) { + + state, err := stateFactory.NewState(ctx, st.(types.State)) + if err != nil { + composed.LoggerFromCtx(ctx).Error(err, "Failed to bootstrap GCP RedisCluster state") + redisCluster := st.Obj().(*v1beta1.RedisCluster) + redisCluster.Status.State = cloudcontrolv1beta1.StateError + return composed.UpdateStatus(redisCluster). + SetExclusiveConditions(metav1.Condition{ + Type: v1beta1.ConditionTypeError, + Status: metav1.ConditionTrue, + Reason: v1beta1.ReasonCloudProviderError, + Message: "Failed to create RedisCluster state", + }). + SuccessError(composed.StopAndForget). + SuccessLogMsg(fmt.Sprintf("Error creating new GCP RedisCluster state: %s", err)). + Run(ctx, st) + } + + return composed.ComposeActions( + "redisCluster", + actions.AddCommonFinalizer(), + composed.IfElse(composed.Not(composed.MarkedForDeletionPredicate), + composed.ComposeActions( + "redisCluster-create", + ), + composed.ComposeActions( + "redisCluster-delete", + actions.RemoveCommonFinalizer(), + ), + ), + composed.StopAndForgetAction, + )(ctx, state) + } +} diff --git a/pkg/kcp/provider/gcp/rediscluster/state.go b/pkg/kcp/provider/gcp/rediscluster/state.go new file mode 100644 index 00000000..7041340c --- /dev/null +++ b/pkg/kcp/provider/gcp/rediscluster/state.go @@ -0,0 +1,38 @@ +package rediscluster + +import ( + "context" + + "github.com/kyma-project/cloud-manager/pkg/common/abstractions" + + "github.com/kyma-project/cloud-manager/pkg/kcp/rediscluster/types" +) + +type State struct { + types.State +} + +type StateFactory interface { + NewState(ctx context.Context, redisClusterState types.State) (*State, error) +} + +type stateFactory struct { + env abstractions.Environment +} + +func NewStateFactory(env abstractions.Environment) StateFactory { + return &stateFactory{ + env: env, + } +} + +func (statefactory *stateFactory) NewState(ctx context.Context, redisClusterState types.State) (*State, error) { + + return newState(redisClusterState), nil +} + +func newState(redisClusterState types.State) *State { + return &State{ + State: redisClusterState, + } +} diff --git a/pkg/kcp/rediscluster/reconciler.go b/pkg/kcp/rediscluster/reconciler.go index 98666172..abc38896 100644 --- a/pkg/kcp/rediscluster/reconciler.go +++ b/pkg/kcp/rediscluster/reconciler.go @@ -8,6 +8,10 @@ import ( cloudcontrolv1beta1 "github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1" "github.com/kyma-project/cloud-manager/pkg/common/actions/focal" "github.com/kyma-project/cloud-manager/pkg/composed" + awsrediscluster "github.com/kyma-project/cloud-manager/pkg/kcp/provider/aws/rediscluster" + azurerediscluster "github.com/kyma-project/cloud-manager/pkg/kcp/provider/azure/rediscluster" + gcprediscluster "github.com/kyma-project/cloud-manager/pkg/kcp/provider/gcp/rediscluster" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" ) @@ -19,16 +23,25 @@ type RedisClusterReconciler interface { type redisClusterReconciler struct { composedStateFactory composed.StateFactory focalStateFactory focal.StateFactory + + gcpStateFactory gcprediscluster.StateFactory + awsStateFactory awsrediscluster.StateFactory + azureStateFactory azurerediscluster.StateFactory } func NewRedisClusterReconciler( composedStateFactory composed.StateFactory, focalStateFactory focal.StateFactory, - + gcpStateFactory gcprediscluster.StateFactory, + awsStateFactory awsrediscluster.StateFactory, + azureStateFactory azurerediscluster.StateFactory, ) RedisClusterReconciler { return &redisClusterReconciler{ composedStateFactory: composedStateFactory, focalStateFactory: focalStateFactory, + gcpStateFactory: gcpStateFactory, + awsStateFactory: awsStateFactory, + azureStateFactory: azureStateFactory, } } @@ -51,6 +64,13 @@ func (r *redisClusterReconciler) newAction() composed.Action { return composed.ComposeActions( "redisClusterCommon", loadIpRange, + composed.BuildSwitchAction( + "providerSwitch", + nil, + composed.NewCase(focal.GcpProviderPredicate, gcprediscluster.New(r.gcpStateFactory)), + composed.NewCase(focal.AwsProviderPredicate, awsrediscluster.New(r.awsStateFactory)), + composed.NewCase(focal.AzureProviderPredicate, azurerediscluster.New(r.azureStateFactory)), + ), )(ctx, newState(st.(focal.State))) }, )