generated from kyma-project/template-repository
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(RedisInstance): add AWS KCP reconciler (#354)
- Loading branch information
1 parent
f550578
commit b660db2
Showing
26 changed files
with
1,042 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
internal/controller/cloud-control/redisinstance_aws_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package cloudcontrol | ||
|
||
import ( | ||
"time" | ||
|
||
elasticacheTypes "github.com/aws/aws-sdk-go-v2/service/elasticache/types" | ||
cloudcontrolv1beta1 "github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1" | ||
iprangePkg "github.com/kyma-project/cloud-manager/pkg/kcp/iprange" | ||
awsmeta "github.com/kyma-project/cloud-manager/pkg/kcp/provider/aws/meta" | ||
scopePkg "github.com/kyma-project/cloud-manager/pkg/kcp/scope" | ||
. "github.com/kyma-project/cloud-manager/pkg/testinfra/dsl" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("Feature: KCP RedisInstance", func() { | ||
|
||
It("Scenario: KCP AWS RedisInstance is created and deleted", func() { | ||
|
||
name := "6e6ff0b2-3edb-4d6e-8ae5-fbd3d3644ce2" | ||
scope := &cloudcontrolv1beta1.Scope{} | ||
|
||
By("Given Scope exists", func() { | ||
// Tell Scope reconciler to ignore this kymaName | ||
scopePkg.Ignore.AddName(name) | ||
|
||
Eventually(CreateScopeAws). | ||
WithArguments(infra.Ctx(), infra, scope, WithName(name)). | ||
Should(Succeed()) | ||
}) | ||
|
||
kcpIpRangeName := "7017ef87-3814-4dc5-bcd1-966d2f44e285" | ||
kcpIpRange := &cloudcontrolv1beta1.IpRange{} | ||
|
||
// Tell IpRange reconciler to ignore this kymaName | ||
iprangePkg.Ignore.AddName(kcpIpRangeName) | ||
By("And Given KCP IPRange exists", func() { | ||
Eventually(CreateKcpIpRange). | ||
WithArguments( | ||
infra.Ctx(), infra.KCP().Client(), kcpIpRange, | ||
WithName(kcpIpRangeName), | ||
WithKcpIpRangeSpecScope(scope.Name), | ||
). | ||
Should(Succeed()) | ||
}) | ||
|
||
By("And Given KCP IpRange has Ready condition", func() { | ||
Eventually(UpdateStatus). | ||
WithArguments( | ||
infra.Ctx(), infra.KCP().Client(), kcpIpRange, | ||
WithKcpIpRangeStatusCidr(kcpIpRange.Spec.Cidr), | ||
WithConditions(KcpReadyCondition()), | ||
).WithTimeout(20*time.Second).WithPolling(200*time.Millisecond). | ||
Should(Succeed(), "Expected KCP IpRange to become ready") | ||
}) | ||
|
||
redisInstance := &cloudcontrolv1beta1.RedisInstance{} | ||
|
||
By("When RedisInstance is created", func() { | ||
Eventually(CreateRedisInstance). | ||
WithArguments(infra.Ctx(), infra.KCP().Client(), redisInstance, | ||
WithName(name), | ||
WithRemoteRef("skr-redis-example-aws"), | ||
WithIpRange(kcpIpRangeName), | ||
WithInstanceScope(name), | ||
WithRedisInstanceAws(), | ||
// todo add specs | ||
). | ||
Should(Succeed(), "failed creating RedisInstance") | ||
}) | ||
|
||
var awsElastiCacheClusterInstance *elasticacheTypes.CacheCluster | ||
By("Then AWS Redis is created", func() { | ||
Eventually(LoadAndCheck). | ||
WithArguments(infra.Ctx(), infra.KCP().Client(), redisInstance, | ||
NewObjActions(), | ||
HavingRedisInstanceStatusId()). | ||
Should(Succeed(), "expected RedisInstance to get status.id") | ||
awsElastiCacheClusterInstance = infra.AwsMock().GetAwsElastiCacheByName(redisInstance.Status.Id) | ||
}) | ||
|
||
By("When AWS Redis is Available", func() { | ||
infra.AwsMock().SetAwsElastiCacheLifeCycleState(*awsElastiCacheClusterInstance.CacheClusterId, awsmeta.ElastiCache_AVAILABLE) | ||
}) | ||
|
||
By("Then RedisInstance has Ready condition", func() { | ||
Eventually(LoadAndCheck). | ||
WithArguments(infra.Ctx(), infra.KCP().Client(), redisInstance, | ||
NewObjActions(), | ||
HavingConditionTrue(cloudcontrolv1beta1.ConditionTypeReady), | ||
). | ||
Should(Succeed(), "expected RedisInstance to has Ready state, but it didn't") | ||
}) | ||
|
||
By("And Then RedisInstance has .status.primaryEndpoint set", func() { | ||
Expect(len(redisInstance.Status.PrimaryEndpoint) > 0).To(Equal(true)) | ||
}) | ||
// TODO | ||
// By("And Then RedisInstance has .status.readEndpoint set", func() { | ||
// Expect(len(redisInstance.Status.ReadEndpoint) > 0).To(Equal(true)) | ||
// }) | ||
// By("And Then RedisInstance has .status.authString set", func() { | ||
// Expect(len(redisInstance.Status.AuthString) > 0).To(Equal(true)) | ||
// }) | ||
|
||
// DELETE | ||
|
||
By("When RedisInstance is deleted", func() { | ||
Eventually(Delete). | ||
WithArguments(infra.Ctx(), infra.KCP().Client(), redisInstance). | ||
Should(Succeed(), "failed deleting RedisInstance") | ||
}) | ||
|
||
By("And When AWS Redis state is deleted", func() { | ||
infra.AwsMock().DeleteAwsElastiCacheByName(*awsElastiCacheClusterInstance.CacheClusterId) | ||
}) | ||
|
||
By("Then RedisInstance does not exist", func() { | ||
Eventually(IsDeleted, 5*time.Second). | ||
WithArguments(infra.Ctx(), infra.KCP().Client(), redisInstance). | ||
Should(Succeed(), "expected RedisInstance not to exist (be deleted), but it still exists") | ||
}) | ||
}) | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,13 +3,15 @@ package meta | |
import ( | ||
"context" | ||
"errors" | ||
"net/http" | ||
|
||
"github.com/aws/aws-sdk-go-v2/aws/retry" | ||
efsTypes "github.com/aws/aws-sdk-go-v2/service/efs/types" | ||
elasticacheTypes "github.com/aws/aws-sdk-go-v2/service/elasticache/types" | ||
"github.com/aws/smithy-go" | ||
smithyhttp "github.com/aws/smithy-go/transport/http" | ||
"github.com/kyma-project/cloud-manager/pkg/composed" | ||
"github.com/kyma-project/cloud-manager/pkg/util" | ||
"net/http" | ||
) | ||
|
||
type awsAccountKeyType struct{} | ||
|
@@ -47,25 +49,29 @@ func AsApiError(err error) smithy.APIError { | |
} | ||
|
||
var notFoundErrorCodes = map[string]struct{}{ | ||
(&efsTypes.FileSystemNotFound{}).ErrorCode(): {}, | ||
(&efsTypes.AccessPointNotFound{}).ErrorCode(): {}, | ||
(&efsTypes.MountTargetNotFound{}).ErrorCode(): {}, | ||
(&efsTypes.PolicyNotFound{}).ErrorCode(): {}, | ||
(&efsTypes.FileSystemNotFound{}).ErrorCode(): {}, | ||
(&efsTypes.AccessPointNotFound{}).ErrorCode(): {}, | ||
(&efsTypes.MountTargetNotFound{}).ErrorCode(): {}, | ||
(&efsTypes.PolicyNotFound{}).ErrorCode(): {}, | ||
(&elasticacheTypes.CacheSubnetGroupNotFoundFault{}).ErrorCode(): {}, | ||
(&elasticacheTypes.CacheClusterNotFoundFault{}).ErrorCode(): {}, | ||
} | ||
|
||
func IsNotFound(err error) bool { | ||
if err != nil { | ||
var apiErr smithy.APIError | ||
if errors.As(err, &apiErr) { | ||
var smithyhttpErr *smithyhttp.ResponseError | ||
if errors.As(err, &smithyhttpErr) { | ||
return smithyhttpErr.HTTPStatusCode() == http.StatusNotFound | ||
} | ||
|
||
_, listed := notFoundErrorCodes[apiErr.ErrorCode()] | ||
if listed { | ||
return true | ||
} | ||
|
||
if errors.As(err, &smithyhttpErr) { | ||
return smithyhttpErr.HTTPStatusCode() == http.StatusNotFound | ||
} | ||
|
||
} | ||
} | ||
return false | ||
|
@@ -92,3 +98,22 @@ func LogErrorAndReturn(err error, msg string, ctx context.Context) (error, conte | |
result := ErrorToRequeueResponse(err) | ||
return composed.LogErrorAndReturn(err, msg, result, ctx) | ||
} | ||
|
||
type ElastiCacheState = string | ||
|
||
// github.com/aws/aws-sdk-go-v2/service/[email protected]/types/types.go | ||
// CacheClusterStatus *string | ||
// The current state of this cluster, one of the following values: available , | ||
// creating , deleted , deleting , incompatible-network , modifying , rebooting | ||
// cluster nodes , restore-failed , or snapshotting . | ||
const ( | ||
ElastiCache_AVAILABLE ElastiCacheState = "available" | ||
ElastiCache_CREATING ElastiCacheState = "creating" | ||
ElastiCache_DELETED ElastiCacheState = "deleted" | ||
ElastiCache_DELETING ElastiCacheState = "deleting" | ||
ElastiCache_INCOMPATIBLE_NETWORK ElastiCacheState = "incompatible-network" | ||
ElastiCache_MODIFYING ElastiCacheState = "modifying" | ||
ElastiCache_REBOOTING_CLUSTER_NODES ElastiCacheState = "rebooting cluster nodes" | ||
ElastiCache_RESTORE_FAILED ElastiCacheState = "restore-failed" | ||
ElastiCache_SNAPSHOTTING ElastiCacheState = "snapshotting" | ||
) |
Oops, something went wrong.