From 6552a000047411085928a19af3289307a730a693 Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Fri, 14 Aug 2020 16:24:43 +0200 Subject: [PATCH] Use SDK storage.AccountClient.ListKeys. Needed to refactor code to avoid cyclic dependencies --- aci/aci.go | 50 +++---------------- aci/backend.go | 6 +-- aci/convert/convert.go | 6 +-- aci/login/StorageAccountHelper.go | 46 ++++------------- aci/login/clientsetup.go | 82 +++++++++++++++++++++++++++++++ aci/resource_group.go | 32 +++--------- 6 files changed, 112 insertions(+), 110 deletions(-) create mode 100644 aci/login/clientsetup.go diff --git a/aci/aci.go b/aci/aci.go index f1d1e76dd..2b5dfbb91 100644 --- a/aci/aci.go +++ b/aci/aci.go @@ -24,8 +24,6 @@ import ( "strings" "time" - "github.com/docker/api/errdefs" - "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/to" @@ -39,13 +37,12 @@ import ( "github.com/docker/api/aci/login" "github.com/docker/api/containers" "github.com/docker/api/context/store" + "github.com/docker/api/errdefs" "github.com/docker/api/progress" ) -const aciDockerUserAgent = "docker-cli" - func createACIContainers(ctx context.Context, aciContext store.AciContext, groupDefinition containerinstance.ContainerGroup) error { - containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.GetContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return errors.Wrapf(err, "cannot get container group client") } @@ -69,7 +66,7 @@ func createACIContainers(ctx context.Context, aciContext store.AciContext, group func createOrUpdateACIContainers(ctx context.Context, aciContext store.AciContext, groupDefinition containerinstance.ContainerGroup) error { w := progress.ContextWriter(ctx) - containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.GetContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return errors.Wrapf(err, "cannot get container group client") } @@ -124,7 +121,7 @@ func createOrUpdateACIContainers(ctx context.Context, aciContext store.AciContex } func getACIContainerGroup(ctx context.Context, aciContext store.AciContext, containerGroupName string) (containerinstance.ContainerGroup, error) { - containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.GetContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return containerinstance.ContainerGroup{}, fmt.Errorf("cannot get container group client: %v", err) } @@ -133,7 +130,7 @@ func getACIContainerGroup(ctx context.Context, aciContext store.AciContext, cont } func deleteACIContainerGroup(ctx context.Context, aciContext store.AciContext, containerGroupName string) (containerinstance.ContainerGroup, error) { - containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.GetContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return containerinstance.ContainerGroup{}, fmt.Errorf("cannot get container group client: %v", err) } @@ -142,7 +139,7 @@ func deleteACIContainerGroup(ctx context.Context, aciContext store.AciContext, c } func stopACIContainerGroup(ctx context.Context, aciContext store.AciContext, containerGroupName string) error { - containerGroupsClient, err := getContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.GetContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return fmt.Errorf("cannot get container group client: %v", err) } @@ -155,7 +152,7 @@ func stopACIContainerGroup(ctx context.Context, aciContext store.AciContext, con } func execACIContainer(ctx context.Context, aciContext store.AciContext, command, containerGroup string, containerName string) (c containerinstance.ContainerExecResponse, err error) { - containerClient, err := getContainerClient(aciContext.SubscriptionID) + containerClient, err := login.GetContainerClient(aciContext.SubscriptionID) if err != nil { return c, errors.Wrapf(err, "cannot get container client") } @@ -248,7 +245,7 @@ func exec(ctx context.Context, address string, password string, request containe } func getACIContainerLogs(ctx context.Context, aciContext store.AciContext, containerGroupName, containerName string, tail *int32) (string, error) { - containerClient, err := getContainerClient(aciContext.SubscriptionID) + containerClient, err := login.GetContainerClient(aciContext.SubscriptionID) if err != nil { return "", errors.Wrapf(err, "cannot get container client") } @@ -311,34 +308,3 @@ func getBacktrackLines(lines []string, terminalWidth int) int { return numLines } - -func getContainerGroupsClient(subscriptionID string) (containerinstance.ContainerGroupsClient, error) { - containerGroupsClient := containerinstance.NewContainerGroupsClient(subscriptionID) - err := setupClient(&containerGroupsClient.Client) - if err != nil { - return containerinstance.ContainerGroupsClient{}, err - } - containerGroupsClient.PollingDelay = 5 * time.Second - containerGroupsClient.RetryAttempts = 30 - containerGroupsClient.RetryDuration = 1 * time.Second - return containerGroupsClient, nil -} - -func setupClient(aciClient *autorest.Client) error { - aciClient.UserAgent = aciDockerUserAgent - auth, err := login.NewAuthorizerFromLogin() - if err != nil { - return err - } - aciClient.Authorizer = auth - return nil -} - -func getContainerClient(subscriptionID string) (containerinstance.ContainerClient, error) { - containerClient := containerinstance.NewContainerClient(subscriptionID) - err := setupClient(&containerClient.Client) - if err != nil { - return containerinstance.ContainerClient{}, err - } - return containerClient, nil -} diff --git a/aci/backend.go b/aci/backend.go index feaebab66..f977c59d3 100644 --- a/aci/backend.go +++ b/aci/backend.go @@ -133,7 +133,7 @@ type aciContainerService struct { } func (cs *aciContainerService) List(ctx context.Context, all bool) ([]containers.Container, error) { - groupsClient, err := getContainerGroupsClient(cs.ctx.SubscriptionID) + groupsClient, err := login.GetContainerGroupsClient(cs.ctx.SubscriptionID) if err != nil { return nil, err } @@ -232,7 +232,7 @@ func (cs *aciContainerService) Start(ctx context.Context, containerID string) er return errors.New(fmt.Sprintf(msg, containerName, groupName, groupName)) } - containerGroupsClient, err := getContainerGroupsClient(cs.ctx.SubscriptionID) + containerGroupsClient, err := login.GetContainerGroupsClient(cs.ctx.SubscriptionID) if err != nil { return err } @@ -336,7 +336,7 @@ func (cs *aciContainerService) Delete(ctx context.Context, containerID string, r } if !request.Force { - containerGroupsClient, err := getContainerGroupsClient(cs.ctx.SubscriptionID) + containerGroupsClient, err := login.GetContainerGroupsClient(cs.ctx.SubscriptionID) if err != nil { return err } diff --git a/aci/convert/convert.go b/aci/convert/convert.go index b151433ae..f5153f1ae 100644 --- a/aci/convert/convert.go +++ b/aci/convert/convert.go @@ -25,14 +25,12 @@ import ( "strconv" "strings" - "github.com/pkg/errors" - - "github.com/docker/api/aci/login" - "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" "github.com/Azure/go-autorest/autorest/to" "github.com/compose-spec/compose-go/types" + "github.com/pkg/errors" + "github.com/docker/api/aci/login" "github.com/docker/api/containers" "github.com/docker/api/context/store" ) diff --git a/aci/login/StorageAccountHelper.go b/aci/login/StorageAccountHelper.go index 622c7a683..8b1d9dfdc 100644 --- a/aci/login/StorageAccountHelper.go +++ b/aci/login/StorageAccountHelper.go @@ -1,60 +1,34 @@ package login import ( - "encoding/json" + "context" "fmt" - "io/ioutil" - "net/http" + + "github.com/pkg/errors" "github.com/docker/api/context/store" ) -const authenticationURL = "https://management.azure.com/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/listKeys?api-version=2019-06-01" - // StorageAccountHelper helper for Azure Storage Account type StorageAccountHelper struct { LoginService AzureLoginService AciContext store.AciContext } -type storageAcountKeys struct { - Keys []storageAcountKey `json:"keys"` -} -type storageAcountKey struct { - KeyName string `json:"keyName"` - Value string `json:"value"` -} - // GetAzureStorageAccountKey retrieves the storage account ket from the current azure login func (helper StorageAccountHelper) GetAzureStorageAccountKey(accountName string) (string, error) { - token, err := helper.LoginService.GetValidToken() + client, err := GetStorageAccountsClient(helper.AciContext.SubscriptionID) if err != nil { return "", err } - authURL := fmt.Sprintf(authenticationURL, helper.AciContext.SubscriptionID, helper.AciContext.ResourceGroup, accountName) - req, err := http.NewRequest(http.MethodPost, authURL, nil) + result, err := client.ListKeys(context.TODO(), helper.AciContext.ResourceGroup, accountName, "") if err != nil { - return "", err + return "", errors.Wrap(err, fmt.Sprintf("could not access storage account acountKeys for %s, using the azure login", accountName)) } - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token.AccessToken)) - res, err := http.DefaultClient.Do(req) - if err != nil { - return "", err - } - bits, err := ioutil.ReadAll(res.Body) - if err != nil { - return "", err - } - if res.StatusCode >= 400 { - return "", fmt.Errorf("could not access storage account acountKeys for %s, using the azure login. Status %d : %s", accountName, res.StatusCode, string(bits)) - } - - acountKeys := storageAcountKeys{} - if err := json.Unmarshal(bits, &acountKeys); err != nil { - return "", err - } - if len(acountKeys.Keys) < 1 { + if result.Keys != nil && len((*result.Keys)) < 1 { return "", fmt.Errorf("no key could be obtained for storage account %s from your azure login", accountName) } - return acountKeys.Keys[0].Value, nil + + key := (*result.Keys)[0] + return *key.Value, nil } diff --git a/aci/login/clientsetup.go b/aci/login/clientsetup.go new file mode 100644 index 000000000..edd72bf6a --- /dev/null +++ b/aci/login/clientsetup.go @@ -0,0 +1,82 @@ +package login + +import ( + "time" + + "github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources" + "github.com/Azure/azure-sdk-for-go/profiles/preview/preview/subscription/mgmt/subscription" + "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-06-01/storage" + "github.com/Azure/go-autorest/autorest" + "github.com/pkg/errors" + + "github.com/docker/api/errdefs" +) + +const aciDockerUserAgent = "docker-cli" + +// GetContainerGroupsClient get client toi manipulate containerGrouos +func GetContainerGroupsClient(subscriptionID string) (containerinstance.ContainerGroupsClient, error) { + containerGroupsClient := containerinstance.NewContainerGroupsClient(subscriptionID) + err := setupClient(&containerGroupsClient.Client) + if err != nil { + return containerinstance.ContainerGroupsClient{}, err + } + containerGroupsClient.PollingDelay = 5 * time.Second + containerGroupsClient.RetryAttempts = 30 + containerGroupsClient.RetryDuration = 1 * time.Second + return containerGroupsClient, nil +} + +func setupClient(aciClient *autorest.Client) error { + aciClient.UserAgent = aciDockerUserAgent + auth, err := NewAuthorizerFromLogin() + if err != nil { + return err + } + aciClient.Authorizer = auth + return nil +} + +// GetStorageAccountsClient get client to manipulate storage accounts +func GetStorageAccountsClient(subscriptionID string) (storage.AccountsClient, error) { + containerGroupsClient := storage.NewAccountsClient(subscriptionID) + err := setupClient(&containerGroupsClient.Client) + if err != nil { + return storage.AccountsClient{}, err + } + containerGroupsClient.PollingDelay = 5 * time.Second + containerGroupsClient.RetryAttempts = 30 + containerGroupsClient.RetryDuration = 1 * time.Second + return containerGroupsClient, nil +} + +// GetSubscriptionsClient get subscription client +func GetSubscriptionsClient() (subscription.SubscriptionsClient, error) { + subc := subscription.NewSubscriptionsClient() + err := setupClient(&subc.Client) + if err != nil { + return subscription.SubscriptionsClient{}, errors.Wrap(errdefs.ErrLoginRequired, err.Error()) + } + return subc, nil +} + +// GetGroupsClient get client to manipulate groups +func GetGroupsClient(subscriptionID string) (resources.GroupsClient, error) { + groupsClient := resources.NewGroupsClient(subscriptionID) + err := setupClient(&groupsClient.Client) + if err != nil { + return resources.GroupsClient{}, err + } + return groupsClient, nil +} + +// GetContainerClient get client to manipulate containers +func GetContainerClient(subscriptionID string) (containerinstance.ContainerClient, error) { + containerClient := containerinstance.NewContainerClient(subscriptionID) + err := setupClient(&containerClient.Client) + if err != nil { + return containerinstance.ContainerClient{}, err + } + return containerClient, nil +} diff --git a/aci/resource_group.go b/aci/resource_group.go index d461936c2..8d3bb6c3c 100644 --- a/aci/resource_group.go +++ b/aci/resource_group.go @@ -19,11 +19,11 @@ package aci import ( "context" + "github.com/docker/api/aci/login" + "github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources" "github.com/Azure/azure-sdk-for-go/profiles/preview/preview/subscription/mgmt/subscription" "github.com/pkg/errors" - - "github.com/docker/api/errdefs" ) // ResourceGroupHelper interface to manage resource groups and subscription IDs @@ -45,7 +45,7 @@ func NewACIResourceGroupHelper() ResourceGroupHelper { // GetGroup get a resource group from its name func (mgt aciResourceGroupHelperImpl) GetGroup(ctx context.Context, subscriptionID string, groupName string) (resources.Group, error) { - gc, err := getGroupsClient(subscriptionID) + gc, err := login.GetGroupsClient(subscriptionID) if err != nil { return resources.Group{}, err } @@ -54,7 +54,7 @@ func (mgt aciResourceGroupHelperImpl) GetGroup(ctx context.Context, subscription // ListGroups list resource groups func (mgt aciResourceGroupHelperImpl) ListGroups(ctx context.Context, subscriptionID string) ([]resources.Group, error) { - gc, err := getGroupsClient(subscriptionID) + gc, err := login.GetGroupsClient(subscriptionID) if err != nil { return nil, err } @@ -80,7 +80,7 @@ func (mgt aciResourceGroupHelperImpl) ListGroups(ctx context.Context, subscripti // CreateOrUpdate create or update a resource group func (mgt aciResourceGroupHelperImpl) CreateOrUpdate(ctx context.Context, subscriptionID string, resourceGroupName string, parameters resources.Group) (result resources.Group, err error) { - gc, err := getGroupsClient(subscriptionID) + gc, err := login.GetGroupsClient(subscriptionID) if err != nil { return resources.Group{}, err } @@ -89,7 +89,7 @@ func (mgt aciResourceGroupHelperImpl) CreateOrUpdate(ctx context.Context, subscr // DeleteAsync deletes a resource group. Does not wait for full deletion to return (long operation) func (mgt aciResourceGroupHelperImpl) DeleteAsync(ctx context.Context, subscriptionID string, resourceGroupName string) (err error) { - gc, err := getGroupsClient(subscriptionID) + gc, err := login.GetGroupsClient(subscriptionID) if err != nil { return err } @@ -100,7 +100,7 @@ func (mgt aciResourceGroupHelperImpl) DeleteAsync(ctx context.Context, subscript // GetSubscriptionIDs Return available subscription IDs based on azure login func (mgt aciResourceGroupHelperImpl) GetSubscriptionIDs(ctx context.Context) ([]subscription.Model, error) { - c, err := getSubscriptionsClient() + c, err := login.GetSubscriptionsClient() if err != nil { return nil, err } @@ -122,21 +122,3 @@ func (mgt aciResourceGroupHelperImpl) GetSubscriptionIDs(ctx context.Context) ([ } return subs, nil } - -func getSubscriptionsClient() (subscription.SubscriptionsClient, error) { - subc := subscription.NewSubscriptionsClient() - err := setupClient(&subc.Client) - if err != nil { - return subscription.SubscriptionsClient{}, errors.Wrap(errdefs.ErrLoginRequired, err.Error()) - } - return subc, nil -} - -func getGroupsClient(subscriptionID string) (resources.GroupsClient, error) { - groupsClient := resources.NewGroupsClient(subscriptionID) - err := setupClient(&groupsClient.Client) - if err != nil { - return resources.GroupsClient{}, err - } - return groupsClient, nil -}