github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/cis/account_cleanup.go (about) 1 package cis 2 3 import ( 4 "fmt" 5 6 "github.com/kyma-project/kyma-environment-broker/internal" 7 "github.com/kyma-project/kyma-environment-broker/internal/storage" 8 9 "github.com/sirupsen/logrus" 10 ) 11 12 //go:generate mockery --name=CisClient --output=automock 13 type CisClient interface { 14 FetchSubaccountsToDelete() ([]string, error) 15 } 16 17 //go:generate mockery --name=BrokerClient --output=automock 18 type BrokerClient interface { 19 Deprovision(instance internal.Instance) (string, error) 20 } 21 22 type SubAccountCleanupService struct { 23 client CisClient 24 brokerClient BrokerClient 25 storage storage.Instances 26 log logrus.FieldLogger 27 chunksAmount int 28 } 29 30 func NewSubAccountCleanupService(client CisClient, brokerClient BrokerClient, storage storage.Instances, log logrus.FieldLogger) *SubAccountCleanupService { 31 return &SubAccountCleanupService{ 32 client: client, 33 brokerClient: brokerClient, 34 storage: storage, 35 log: log, 36 chunksAmount: 50, 37 } 38 } 39 40 func (ac *SubAccountCleanupService) Run() error { 41 subaccounts, err := ac.client.FetchSubaccountsToDelete() 42 if err != nil { 43 return fmt.Errorf("while fetching subaccounts by client: %w", err) 44 } 45 46 subaccountsBatch := chunk(ac.chunksAmount, subaccounts) 47 chunks := len(subaccountsBatch) 48 errCh := make(chan error) 49 done := make(chan struct{}) 50 var isDone bool 51 52 for _, chunk := range subaccountsBatch { 53 go ac.executeDeprovisioning(chunk, done, errCh) 54 } 55 56 for !isDone { 57 select { 58 case err := <-errCh: 59 ac.log.Warnf("part of deprovisioning process failed with error: %s", err) 60 case <-done: 61 chunks-- 62 if chunks == 0 { 63 isDone = true 64 } 65 } 66 } 67 68 ac.log.Info("SubAccount cleanup process finished") 69 return nil 70 } 71 72 func (ac *SubAccountCleanupService) executeDeprovisioning(subaccounts []string, done chan<- struct{}, errCh chan<- error) { 73 instances, err := ac.storage.FindAllInstancesForSubAccounts(subaccounts) 74 if err != nil { 75 errCh <- fmt.Errorf("while finding all instances by subaccounts: %w", err) 76 return 77 } 78 79 for _, instance := range instances { 80 operation, err := ac.brokerClient.Deprovision(instance) 81 if err != nil { 82 errCh <- fmt.Errorf("error occurred during deprovisioning instance with ID %s: %w", instance.InstanceID, err) 83 continue 84 } 85 ac.log.Infof("deprovisioning for instance %s (SubAccountID: %s) was triggered, operation: %s", instance.InstanceID, instance.SubAccountID, operation) 86 } 87 88 done <- struct{}{} 89 } 90 91 func chunk(amount int, data []string) [][]string { 92 var divided [][]string 93 94 for i := 0; i < len(data); i += amount { 95 end := i + amount 96 if end > len(data) { 97 end = len(data) 98 } 99 divided = append(divided, data[i:end]) 100 } 101 102 return divided 103 }