mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-05-08 17:25:14 -04:00
Manually manage resource group on Azure
This commit is contained in:
parent
e6ae54a25a
commit
f15605cb45
25 changed files with 403 additions and 1162 deletions
133
cli/internal/azure/client/terminate.go
Normal file
133
cli/internal/azure/client/terminate.go
Normal file
|
@ -0,0 +1,133 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
|
||||
)
|
||||
|
||||
// TerminateResourceGroupResources deletes all resources from the resource group.
|
||||
func (c *Client) TerminateResourceGroupResources(ctx context.Context) error {
|
||||
const timeOut = 10 * time.Minute
|
||||
ctx, cancel := context.WithTimeout(ctx, timeOut)
|
||||
defer cancel()
|
||||
|
||||
pollers := make(chan *runtime.Poller[armresources.ClientDeleteByIDResponse], 20)
|
||||
delete := make(chan struct{}, 1)
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
go func() { // This routine lists resources and starts their deletion, where possible.
|
||||
defer wg.Done()
|
||||
defer func() {
|
||||
close(pollers)
|
||||
for range delete { // drain channel
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
ids, err := c.getResourceIDList(ctx)
|
||||
if err != nil {
|
||||
time.Sleep(3 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(ids) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, id := range ids {
|
||||
poller, err := c.deleteResourceByID(ctx, id)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
pollers <- poller
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case _, ok := <-delete:
|
||||
if !ok { // channel was closed
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() { // This routine polls for for the deletions to complete.
|
||||
defer wg.Done()
|
||||
defer close(delete)
|
||||
|
||||
for poller := range pollers {
|
||||
_, err := poller.PollUntilDone(ctx, nil)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
select {
|
||||
case delete <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) getResourceIDList(ctx context.Context) ([]string, error) {
|
||||
var ids []string
|
||||
pager := c.resourceAPI.NewListByResourceGroupPager(c.resourceGroup, nil)
|
||||
for pager.More() {
|
||||
page, err := pager.NextPage(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting next page of ListByResourceGroup: %w", err)
|
||||
}
|
||||
for _, resource := range page.Value {
|
||||
if resource.ID == nil {
|
||||
return nil, fmt.Errorf("resource %v has no ID", resource)
|
||||
}
|
||||
ids = append(ids, *resource.ID)
|
||||
}
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (c *Client) deleteResourceByID(ctx context.Context, id string,
|
||||
) (*runtime.Poller[armresources.ClientDeleteByIDResponse], error) {
|
||||
apiVersion := "2020-02-02"
|
||||
|
||||
// First try, API version unknown, will fail.
|
||||
poller, err := c.resourceAPI.BeginDeleteByID(ctx, id, apiVersion, nil)
|
||||
if isVersionWrongErr(err) {
|
||||
// bad hack, but easiest way to get the right API version
|
||||
apiVersion = parseAPIVersionFromErr(err)
|
||||
poller, err = c.resourceAPI.BeginDeleteByID(ctx, id, apiVersion, nil)
|
||||
}
|
||||
return poller, err
|
||||
}
|
||||
|
||||
func isVersionWrongErr(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
return strings.Contains(err.Error(), "NoRegisteredProviderFound") &&
|
||||
strings.Contains(err.Error(), "The supported api-versions are")
|
||||
}
|
||||
|
||||
var apiVersionRegex = regexp.MustCompile(` (\d\d\d\d-\d\d-\d\d)'`)
|
||||
|
||||
func parseAPIVersionFromErr(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
matches := apiVersionRegex.FindStringSubmatch(err.Error())
|
||||
return matches[1]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue