Skip to content

Commit

Permalink
Added integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ravi-shankar-sap committed Dec 16, 2024
1 parent abb799f commit 36af95d
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 99 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ jobs:
nukeBackupsGcp:
- "false"
- "true"
nukeBackupsAws:
- "false"
- "true"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
Expand All @@ -28,6 +31,7 @@ jobs:
env:
FF_GCP_NFS_VOLUME_AUTOMATIC_LOCATION_ALLOCATION: ${{ matrix.gcpNfsVolumeAutomaticLocationAllocation }}
FF_NUKE_BAKCUPS_GCP: ${{ matrix.nukeBackupsGcp }}
FF_NUKE_BACKUPS_AWS: ${{ matrix.nukeBackupsAws }}
run: |
./config/sync.sh
go mod tidy
Expand Down
151 changes: 151 additions & 0 deletions internal/controller/cloud-control/nuke_aws_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package cloudcontrol

import (
"context"
"fmt"
cloudcontrolv1beta1 "github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1"
"github.com/kyma-project/cloud-manager/pkg/feature"
awsnukeclient "github.com/kyma-project/cloud-manager/pkg/kcp/provider/aws/nuke/client"
scopePkg "github.com/kyma-project/cloud-manager/pkg/kcp/scope"
awsnfsbackupclient "github.com/kyma-project/cloud-manager/pkg/skr/awsnfsvolumebackup/client"
. "github.com/kyma-project/cloud-manager/pkg/testinfra/dsl"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"k8s.io/utils/ptr"
)

var _ = Describe("Feature: KCP Nuke AwsNfsVolumeBackup", func() {

//Define variables
scopeName := "test-nuke-aws-nfs-backups-scope-01"
scope := &cloudcontrolv1beta1.Scope{}

vaultName := fmt.Sprintf("cm-%s", scopeName)
clientProvider := awsnukeclient.Mock()

recoveryPointArns := []string{"", ""}

BeforeEach(func() {
By("Given KCP Scope exists", func() {
scopePkg.Ignore.AddName(scopeName)
// Given Scope exists
Eventually(GivenScopeAwsExists).
WithArguments(
infra.Ctx(), infra, scope,
WithName(scopeName),
).
Should(Succeed())
})
By("And Given Scope is in Ready state", func() {
Eventually(LoadAndCheck).
WithArguments(
infra.Ctx(), infra.KCP().Client(), scope,
NewObjActions(),
).
Should(Succeed())

//Update KCP Scope status to Ready
Eventually(UpdateStatus).
WithArguments(
infra.Ctx(), infra.KCP().Client(), scope,
WithConditions(KcpReadyCondition()),
).
Should(Succeed())
})

nukeClient, _ := clientProvider(infra.Ctx(),
scope.Spec.Scope.Aws.AccountId, "", "", "", "")

By(" And Given Aws Vault exits for the same scope", func() {
_, err := nukeClient.CreateBackupVault(
infra.Ctx(),
vaultName,
make(map[string]string),
)
Expect(err).
ShouldNot(HaveOccurred(), "failed creating Aws Vault directly")
})

By(" And Given Aws Backups exits for the same scope", func() {
for i := range recoveryPointArns {
out, err := nukeClient.StartBackupJob(
infra.Ctx(),
&awsnfsbackupclient.StartBackupJobInput{
BackupVaultName: vaultName,
})
Expect(err).ShouldNot(HaveOccurred(), "failed creating Aws Recovery Point directly")
recoveryPointArns[i] = ptr.Deref(out.RecoveryPointArn, "")
}
})
})

//Define variables.
nukeName := "nuke-" + scopeName
nuke := &cloudcontrolv1beta1.Nuke{}
It("When Nuke for the Scope is created", func() {
//Disable the test case if the feature is not enabled.
if !feature.FFNukeBackupsAws.Value(context.Background()) {
Skip("Nuke Backups for AWS is disabled")
}

nukeClient, _ := clientProvider(infra.Ctx(),
scope.Spec.Scope.Aws.AccountId, "", "", "", "")

Eventually(CreateObj(infra.Ctx(), infra.KCP().Client(), nuke,
WithName(nukeName),
WithScope(scopeName),
)).Should(Succeed())

By("Then Nuke status state is Deleting", func() {
Eventually(LoadAndCheck).
WithArguments(infra.Ctx(), infra.KCP().Client(), nuke, NewObjActions(),
HavingState("Completed"),
).
Should(Succeed())
})

kind := "AwsNfsVolumeBackup"

By(fmt.Sprintf("And Then provider resource %s does not exist", kind), func() {
Eventually(func() error {
backupsOnAws, err := nukeClient.ListRecoveryPointsForVault(infra.Ctx(), "", vaultName)
if err != nil {
return err
}
Expect(backupsOnAws).To(HaveLen(0))
return nil
}).Should(Succeed())
})

By(fmt.Sprintf("And Then Nuke status resource %s has state Deleted", kind), func() {
Eventually(func() error {
if err := LoadAndCheck(infra.Ctx(), infra.KCP().Client(), nuke, NewObjActions()); err != nil {
return err
}
sk := nuke.Status.GetKindNoCreate(kind)
if sk == nil {
return fmt.Errorf("kind %s not found in Nuke status", kind)
}
for _, arn := range recoveryPointArns {
actual := sk.Objects[arn]
if actual == cloudcontrolv1beta1.NukeResourceStatusDeleted {
continue
}
return fmt.Errorf("expected resource %s/%s to have status Deleted, but found %s", kind, arn, actual)
}
return nil
}).Should(Succeed())
})

By("And Then Scope is deleted", func() {
Eventually(IsDeleted).
WithArguments(infra.Ctx(), infra.KCP().Client(), scope).
Should(Succeed())
})

By("// cleanup: Delete Nuke", func() {
Expect(Delete(infra.Ctx(), infra.KCP().Client(), nuke)).
To(Succeed())
})
})
})
2 changes: 1 addition & 1 deletion internal/controller/cloud-control/nuke_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func SetupNukeReconciler(
kcpManager manager.Manager,
activeSkrCollection skrruntime.ActiveSkrCollection,
gcpFileBackupClientProvider gcpclient.ClientProvider[gcpfilebackupclient.FileBackupClient],
awsNukeNfsClientProvider awsclient.SkrClientProvider[awsnukenfsclient.Client],
awsNukeNfsClientProvider awsclient.SkrClientProvider[awsnukenfsclient.NukeNfsBackupClient],
env abstractions.Environment,
) error {
baseStateFactory := composed.NewStateFactory(composed.NewStateClusterFromCluster(kcpManager))
Expand Down
2 changes: 1 addition & 1 deletion internal/controller/cloud-control/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ var _ = BeforeSuite(func() {
infra.KcpManager(),
infra.ActiveSkrCollection(),
infra.GcpMock().FileBackupClientProvider(),
awsnukeclient.NewMock("aws-test-scope"),
awsnukeclient.Mock(),
env,
)).To(Succeed())

Expand Down
48 changes: 6 additions & 42 deletions pkg/kcp/provider/aws/nuke/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,20 @@ package client
import (
"context"
"github.com/aws/aws-sdk-go-v2/service/backup"
"github.com/aws/aws-sdk-go-v2/service/backup/types"
awsclient "github.com/kyma-project/cloud-manager/pkg/kcp/provider/aws/client"
"k8s.io/utils/ptr"
awsnfsbackupclient "github.com/kyma-project/cloud-manager/pkg/skr/awsnfsvolumebackup/client"
)

type Client interface {
ListRecoveryPointsForVault(ctx context.Context, accountId, backupVaultName string) ([]types.RecoveryPointByBackupVault, error)
DeleteRecoveryPoint(ctx context.Context, backupVaultName, recoveryPointArn string) (*backup.DeleteRecoveryPointOutput, error)
type NukeNfsBackupClient interface {
awsnfsbackupclient.Client
}

func NewClientProvider() awsclient.SkrClientProvider[Client] {
return func(ctx context.Context, account, region, key, secret, role string) (Client, error) {
func NewClientProvider() awsclient.SkrClientProvider[NukeNfsBackupClient] {
return func(ctx context.Context, account, region, key, secret, role string) (NukeNfsBackupClient, error) {
cfg, err := awsclient.NewSkrConfig(ctx, region, key, secret, role)
if err != nil {
return nil, err
}
return newClient(backup.NewFromConfig(cfg)), nil
return awsnfsbackupclient.NewClient(backup.NewFromConfig(cfg)), nil
}
}

func newClient(svc *backup.Client) Client {
return &client{
svc: svc,
}
}

type client struct {
svc *backup.Client
}

func (c *client) ListRecoveryPointsForVault(ctx context.Context, accountId, backupVaultName string) ([]types.RecoveryPointByBackupVault, error) {
in := &backup.ListRecoveryPointsByBackupVaultInput{
BackupVaultName: ptr.To(backupVaultName),
BackupVaultAccountId: ptr.To(accountId),
}
out, err := c.svc.ListRecoveryPointsByBackupVault(ctx, in)
if err != nil {
return nil, err
}
return out.RecoveryPoints, nil
}

func (c *client) DeleteRecoveryPoint(ctx context.Context, backupVaultName, recoveryPointArn string) (*backup.DeleteRecoveryPointOutput, error) {
in := &backup.DeleteRecoveryPointInput{
BackupVaultName: ptr.To(backupVaultName),
RecoveryPointArn: ptr.To(recoveryPointArn),
}
out, err := c.svc.DeleteRecoveryPoint(ctx, in)
if err != nil {
return nil, err
}
return out, nil
}
52 changes: 4 additions & 48 deletions pkg/kcp/provider/aws/nuke/client/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,12 @@ package client

import (
"context"
"fmt"
"github.com/aws/aws-sdk-go-v2/service/backup"
"github.com/aws/aws-sdk-go-v2/service/backup/types"
"github.com/kyma-project/cloud-manager/pkg/composed"
awsclient "github.com/kyma-project/cloud-manager/pkg/kcp/provider/aws/client"
"k8s.io/utils/ptr"
awsnfsbackupclient "github.com/kyma-project/cloud-manager/pkg/skr/awsnfsvolumebackup/client"
)

type mockClient struct {
vaultName string
recoveryPoints []types.RecoveryPointByBackupVault
}

func NewMock(scopeId string) awsclient.SkrClientProvider[Client] {
mock := mockClient{}
mock.init(scopeId)
return func(ctx context.Context, account, region, key, secret, role string) (Client, error) {
return &mock, nil
}
}

func (c *mockClient) init(scopeId string) {
vaultName := fmt.Sprintf("cm-%s", scopeId)
c.vaultName = vaultName
c.recoveryPoints = []types.RecoveryPointByBackupVault{
{
BackupVaultName: ptr.To(vaultName),
RecoveryPointArn: ptr.To("arn:"),
},
{
BackupVaultName: ptr.To(vaultName),
RecoveryPointArn: ptr.To("arn:"),
},
}
}

func (c *mockClient) ListRecoveryPointsForVault(ctx context.Context, accountId, backupVaultName string) ([]types.RecoveryPointByBackupVault, error) {
if c.vaultName != backupVaultName {
return []types.RecoveryPointByBackupVault{}, nil
}
return c.recoveryPoints, nil
}

func (c *mockClient) DeleteRecoveryPoint(ctx context.Context, backupVaultName, recoveryPointArn string) (*backup.DeleteRecoveryPointOutput, error) {
logger := composed.LoggerFromCtx(ctx)
for i, rPoint := range c.recoveryPoints {
if ptr.Deref(rPoint.RecoveryPointArn, "") == recoveryPointArn {
c.recoveryPoints = append(c.recoveryPoints[:i], c.recoveryPoints[i+1:]...)
logger.WithName("DeleteRecoveryPoint - mock").Info(fmt.Sprintf("Length :: %d", len(c.recoveryPoints)))
}
func Mock() awsclient.SkrClientProvider[NukeNfsBackupClient] {
return func(ctx context.Context, account, region, key, secret, role string) (NukeNfsBackupClient, error) {
return awsnfsbackupclient.NewMockClient()(ctx, account, region, key, secret, role)
}
return &backup.DeleteRecoveryPointOutput{}, nil
}
2 changes: 1 addition & 1 deletion pkg/kcp/provider/aws/nuke/loadNfsBackups.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func loadNfsBackups(ctx context.Context, st composed.State) (error, context.Cont
if err != nil {
logger.Error(err, "Error listing Aws Recovery Points")

state.ObjAsNuke().Status.State = string(cloudcontrolv1beta1.ErrorState)
state.ObjAsNuke().Status.State = string(cloudcontrolv1beta1.StateError)

return composed.PatchStatus(state.ObjAsNuke()).
SetExclusiveConditions(metav1.Condition{
Expand Down
8 changes: 4 additions & 4 deletions pkg/kcp/provider/aws/nuke/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type StateFactory interface {
}

func NewStateFactory(
awsClientProvider awsClient.SkrClientProvider[awsnukeclient.Client],
awsClientProvider awsClient.SkrClientProvider[awsnukeclient.NukeNfsBackupClient],
env abstractions.Environment) StateFactory {
return stateFactory{
awsClientProvider: awsClientProvider,
Expand All @@ -27,7 +27,7 @@ func NewStateFactory(
}

type stateFactory struct {
awsClientProvider awsClient.SkrClientProvider[awsnukeclient.Client]
awsClientProvider awsClient.SkrClientProvider[awsnukeclient.NukeNfsBackupClient]
env abstractions.Environment
}

Expand All @@ -43,9 +43,9 @@ type State struct {
nuketypes.State
ProviderResources []*nuketypes.ProviderResourceKindState

awsClientProvider awsClient.SkrClientProvider[awsnukeclient.Client]
awsClientProvider awsClient.SkrClientProvider[awsnukeclient.NukeNfsBackupClient]
env abstractions.Environment
awsClient awsnukeclient.Client
awsClient awsnukeclient.NukeNfsBackupClient
}

type AwsBackup struct {
Expand Down
17 changes: 15 additions & 2 deletions pkg/skr/awsnfsvolumebackup/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Client interface {
StartBackupJob(ctx context.Context, params *StartBackupJobInput) (*backup.StartBackupJobOutput, error)
DescribeBackupJob(ctx context.Context, backupJobId string) (*backup.DescribeBackupJobOutput, error)

ListRecoveryPointsForVault(ctx context.Context, accountId, backupVaultName string) ([]backuptypes.RecoveryPointByBackupVault, error)
DescribeRecoveryPoint(ctx context.Context, accountId, backupVaultName, recoveryPointArn string) (*backup.DescribeRecoveryPointOutput, error)
DeleteRecoveryPoint(ctx context.Context, backupVaultName, recoveryPointArn string) (*backup.DeleteRecoveryPointOutput, error)
}
Expand All @@ -49,7 +50,7 @@ func NewClientProvider() awsclient.SkrClientProvider[Client] {
if err != nil {
return nil, err
}
return newClient(backup.NewFromConfig(cfg)), nil
return NewClient(backup.NewFromConfig(cfg)), nil
}
}

Expand All @@ -59,7 +60,7 @@ func newLocalClient() *localClient {
}
}

func newClient(svc *backup.Client) Client {
func NewClient(svc *backup.Client) Client {
return &client{
localClient: *newLocalClient(),
svc: svc,
Expand Down Expand Up @@ -192,6 +193,18 @@ func (c *client) DescribeBackupJob(ctx context.Context, backupJobId string) (*ba
return out, nil
}

func (c *client) ListRecoveryPointsForVault(ctx context.Context, accountId, backupVaultName string) ([]backuptypes.RecoveryPointByBackupVault, error) {
in := &backup.ListRecoveryPointsByBackupVaultInput{
BackupVaultName: ptr.To(backupVaultName),
BackupVaultAccountId: ptr.To(accountId),
}
out, err := c.svc.ListRecoveryPointsByBackupVault(ctx, in)
if err != nil {
return nil, err
}
return out.RecoveryPoints, nil
}

func (c *client) DescribeRecoveryPoint(ctx context.Context, accountId, backupVaultName, recoveryPointArn string) (*backup.DescribeRecoveryPointOutput, error) {
in := &backup.DescribeRecoveryPointInput{
BackupVaultName: ptr.To(backupVaultName),
Expand Down
Loading

0 comments on commit 36af95d

Please sign in to comment.