From 3a60c957aee64ab6c198e14943410c2bdc50097a Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Thu, 13 Aug 2020 15:21:09 +0200 Subject: [PATCH 1/4] Get storage account key from azure login, no need to specify it in compose file or run -v option --- aci/convert/convert.go | 24 ++++-- aci/convert/volume.go | 75 ++++--------------- aci/convert/volume_test.go | 35 ++------- aci/login/StorageAccountHelper.go | 60 +++++++++++++++ tests/aci-e2e/e2e-aci_test.go | 2 +- .../aci_demo_port_secrets_volumes.yaml | 15 +--- 6 files changed, 101 insertions(+), 110 deletions(-) create mode 100644 aci/login/StorageAccountHelper.go diff --git a/aci/convert/convert.go b/aci/convert/convert.go index c8134b7c4..b151433ae 100644 --- a/aci/convert/convert.go +++ b/aci/convert/convert.go @@ -18,7 +18,6 @@ package convert import ( "encoding/base64" - "errors" "fmt" "io/ioutil" "math" @@ -26,6 +25,10 @@ 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" @@ -42,7 +45,6 @@ const ( azureFileDriverName = "azure_file" volumeDriveroptsShareNameKey = "share_name" volumeDriveroptsAccountNameKey = "storage_account_name" - volumeDriveroptsAccountKeyKey = "storage_account_key" secretInlineMark = "inline:" ) @@ -50,7 +52,15 @@ const ( func ToContainerGroup(aciContext store.AciContext, p types.Project) (containerinstance.ContainerGroup, error) { project := projectAciHelper(p) containerGroupName := strings.ToLower(project.Name) - volumesCache, volumesSlice, err := project.getAciFileVolumes() + loginService, err := login.NewAzureLoginService() + if err != nil { + return containerinstance.ContainerGroup{}, err + } + storageHelper := login.StorageAccountHelper{ + LoginService: *loginService, + AciContext: aciContext, + } + volumesCache, volumesSlice, err := project.getAciFileVolumes(storageHelper) if err != nil { return containerinstance.ContainerGroup{}, err } @@ -191,7 +201,7 @@ func (p projectAciHelper) getAciSecretVolumes() ([]containerinstance.Volume, err return secretVolumes, nil } -func (p projectAciHelper) getAciFileVolumes() (map[string]bool, []containerinstance.Volume, error) { +func (p projectAciHelper) getAciFileVolumes(helper login.StorageAccountHelper) (map[string]bool, []containerinstance.Volume, error) { azureFileVolumesMap := make(map[string]bool, len(p.Volumes)) var azureFileVolumesSlice []containerinstance.Volume for name, v := range p.Volumes { @@ -204,9 +214,9 @@ func (p projectAciHelper) getAciFileVolumes() (map[string]bool, []containerinsta if !ok { return nil, nil, fmt.Errorf("cannot retrieve account name for Azurefile") } - accountKey, ok := v.DriverOpts[volumeDriveroptsAccountKeyKey] - if !ok { - return nil, nil, fmt.Errorf("cannot retrieve account key for Azurefile") + accountKey, err := helper.GetAzureStorageAccountKey(accountName) + if err != nil { + return nil, nil, err } aciVolume := containerinstance.Volume{ Name: to.StringPtr(name), diff --git a/aci/convert/volume.go b/aci/convert/volume.go index e3b37a83d..bdda13618 100644 --- a/aci/convert/volume.go +++ b/aci/convert/volume.go @@ -18,7 +18,6 @@ package convert import ( "fmt" - "net/url" "strings" "github.com/pkg/errors" @@ -44,7 +43,6 @@ func GetRunVolumes(volumes []string) (map[string]types.VolumeConfig, []types.Ser Driver: azureFileDriverName, DriverOpts: map[string]string{ volumeDriveroptsAccountNameKey: vi.username, - volumeDriveroptsAccountKeyKey: vi.key, volumeDriveroptsShareNameKey: vi.share, }, } @@ -62,73 +60,26 @@ func GetRunVolumes(volumes []string) (map[string]types.VolumeConfig, []types.Ser type volumeInput struct { name string username string - key string share string target string } -func escapeKeySlashes(rawURL string) (string, error) { - urlSplit := strings.Split(rawURL, "@") - if len(urlSplit) < 1 { - return "", fmt.Errorf("invalid URL format: %s", rawURL) - } - userPasswd := strings.ReplaceAll(urlSplit[0], "/", "_") - - atIndex := strings.Index(rawURL, "@") - if atIndex < 0 { - return "", fmt.Errorf("no share specified in: %s", rawURL) - } - - scaped := userPasswd + rawURL[atIndex:] - - return scaped, nil -} - -func unescapeKey(key string) string { - return strings.ReplaceAll(key, "_", "/") -} - -// Removes the second ':' that separates the source from target -func volumeURL(pathURL string) (*url.URL, error) { - scapedURL, err := escapeKeySlashes(pathURL) - if err != nil { - return nil, err - } - pathURL = "//" + scapedURL - - count := strings.Count(pathURL, ":") - if count > 2 { - return nil, fmt.Errorf("invalid path URL: %s", pathURL) - } - if count == 2 { - tokens := strings.Split(pathURL, ":") - pathURL = fmt.Sprintf("%s:%s%s", tokens[0], tokens[1], tokens[2]) - } - return url.Parse(pathURL) -} - func (v *volumeInput) parse(name string, s string) error { - volumeURL, err := volumeURL(s) - if err != nil { - return errors.Wrapf(errdefs.ErrParsingFailed, "unable to parse volume specification: %s", err.Error()) - } - v.username = volumeURL.User.Username() - if v.username == "" { - return errors.Wrapf(errdefs.ErrParsingFailed, "volume specification %q does not include a storage username", v) - } - key, ok := volumeURL.User.Password() - if !ok || key == "" { - return errors.Wrapf(errdefs.ErrParsingFailed, "volume specification %q does not include a storage key", v) + v.name = name + tokens := strings.Split(s, "@") + if len(tokens) < 2 || tokens[0] == "" { + return errors.Wrapf(errdefs.ErrParsingFailed, "volume specification %q does not include a storage account before '@'", v) } - v.key = unescapeKey(key) - v.share = volumeURL.Host - if v.share == "" { - return errors.Wrapf(errdefs.ErrParsingFailed, "volume specification %q does not include a storage file share", v) + v.username = tokens[0] + remaining := tokens[1] + tokens = strings.Split(remaining, ":") + if tokens[0] == "" { + return errors.Wrapf(errdefs.ErrParsingFailed, "volume specification %q does not include a storage file share after '@'", v) } - v.name = name - v.target = volumeURL.Path - if v.target == "" { - // Do not use filepath.Join, on Windows it will replace / by \ + v.share = tokens[0] + if len(tokens) > 1 { + v.target = tokens[1] + } else { v.target = "/run/volumes/" + v.share } return nil diff --git a/aci/convert/volume_test.go b/aci/convert/volume_test.go index 6a9da4470..b3bdebcdd 100644 --- a/aci/convert/volume_test.go +++ b/aci/convert/volume_test.go @@ -21,21 +21,18 @@ import ( "github.com/compose-spec/compose-go/types" "gotest.tools/v3/assert" - - "github.com/docker/api/errdefs" ) const ( storageAccountNameKey = "storage_account_name" - storageAccountKeyKey = "storage_account_key" shareNameKey = "share_name" ) func TestGetRunVolumes(t *testing.T) { volumeStrings := []string{ - "myuser1:mykey1@myshare1/my/path/to/target1", - "myuser2:mykey2@myshare2/my/path/to/target2", - "myuser3:mykey3@mydefaultsharename", // Use default placement at '/run/volumes/' + "myuser1@myshare1:/my/path/to/target1", + "myuser2@myshare2:/my/path/to/target2", + "myuser3@mydefaultsharename", // Use default placement at '/run/volumes/' } var goldenVolumeConfigs = map[string]types.VolumeConfig{ "volume-0": { @@ -43,7 +40,6 @@ func TestGetRunVolumes(t *testing.T) { Driver: "azure_file", DriverOpts: map[string]string{ storageAccountNameKey: "myuser1", - storageAccountKeyKey: "mykey1", shareNameKey: "myshare1", }, }, @@ -52,7 +48,6 @@ func TestGetRunVolumes(t *testing.T) { Driver: "azure_file", DriverOpts: map[string]string{ storageAccountNameKey: "myuser2", - storageAccountKeyKey: "mykey2", shareNameKey: "myshare2", }, }, @@ -61,7 +56,6 @@ func TestGetRunVolumes(t *testing.T) { Driver: "azure_file", DriverOpts: map[string]string{ storageAccountNameKey: "myuser3", - storageAccountKeyKey: "mykey3", shareNameKey: "mydefaultsharename", }, }, @@ -95,29 +89,16 @@ func TestGetRunVolumes(t *testing.T) { } func TestGetRunVolumesMissingFileShare(t *testing.T) { - _, _, err := GetRunVolumes([]string{"myuser:mykey@"}) - assert.Assert(t, errdefs.IsErrParsingFailed(err)) - assert.ErrorContains(t, err, "does not include a storage file share") + _, _, err := GetRunVolumes([]string{"myaccount@"}) + assert.ErrorContains(t, err, "does not include a storage file share after '@'") } func TestGetRunVolumesMissingUser(t *testing.T) { - _, _, err := GetRunVolumes([]string{":mykey@myshare"}) - assert.Assert(t, errdefs.IsErrParsingFailed(err)) - assert.ErrorContains(t, err, "does not include a storage username") -} - -func TestGetRunVolumesMissingKey(t *testing.T) { - _, _, err := GetRunVolumes([]string{"userwithnokey:@myshare"}) - assert.Assert(t, errdefs.IsErrParsingFailed(err)) - assert.ErrorContains(t, err, "does not include a storage key") - - _, _, err = GetRunVolumes([]string{"userwithnokeytoo@myshare"}) - assert.Assert(t, errdefs.IsErrParsingFailed(err)) - assert.ErrorContains(t, err, "does not include a storage key") + _, _, err := GetRunVolumes([]string{"@myshare"}) + assert.ErrorContains(t, err, "does not include a storage account before '@'") } func TestGetRunVolumesNoShare(t *testing.T) { _, _, err := GetRunVolumes([]string{"noshare"}) - assert.Assert(t, errdefs.IsErrParsingFailed(err)) - assert.ErrorContains(t, err, "no share specified") + assert.ErrorContains(t, err, "does not include a storage account before '@'") } diff --git a/aci/login/StorageAccountHelper.go b/aci/login/StorageAccountHelper.go new file mode 100644 index 000000000..622c7a683 --- /dev/null +++ b/aci/login/StorageAccountHelper.go @@ -0,0 +1,60 @@ +package login + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "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() + if err != nil { + return "", err + } + authURL := fmt.Sprintf(authenticationURL, helper.AciContext.SubscriptionID, helper.AciContext.ResourceGroup, accountName) + req, err := http.NewRequest(http.MethodPost, authURL, nil) + if err != nil { + return "", err + } + 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 { + return "", fmt.Errorf("no key could be obtained for storage account %s from your azure login", accountName) + } + return acountKeys.Keys[0].Value, nil +} diff --git a/tests/aci-e2e/e2e-aci_test.go b/tests/aci-e2e/e2e-aci_test.go index 67fff876e..436abd06f 100644 --- a/tests/aci-e2e/e2e-aci_test.go +++ b/tests/aci-e2e/e2e-aci_test.go @@ -165,7 +165,7 @@ func TestContainerRun(t *testing.T) { mountTarget := "/usr/share/nginx/html" res := c.RunDockerCmd( "run", "-d", - "-v", fmt.Sprintf("%s:%s@%s:%s", saName, k, testShareName, mountTarget), + "-v", fmt.Sprintf("%s@%s:%s", saName, testShareName, mountTarget), "-p", "80:80", "nginx", ) diff --git a/tests/composefiles/aci-demo/aci_demo_port_secrets_volumes.yaml b/tests/composefiles/aci-demo/aci_demo_port_secrets_volumes.yaml index 1469e65d8..31f982ed2 100644 --- a/tests/composefiles/aci-demo/aci_demo_port_secrets_volumes.yaml +++ b/tests/composefiles/aci-demo/aci_demo_port_secrets_volumes.yaml @@ -14,10 +14,6 @@ services: image: gtardif/sentences-web ports: - "80:80" - secrets: - - source: mysecret1 - target: mytarget1 - - mysecret2 volumes: - mydata:/mount/testvolumes @@ -25,12 +21,5 @@ volumes: mydata: driver: azure_file driver_opts: - share_name: gtashare1 - storage_account_name: gtastorageaccount1 - storage_account_key: UZyyUyZJA0LYrPrXqvB+HP+gGWD0K54LNmtfV+xwGQ18JufaAQ7vtUhcJoEcFUUrm40mehLKtvi4n58w0ivDtQ== - -secrets: - mysecret1: - file: ./my_secret1.txt - mysecret2: - file: ./my_secret2.txt + share_name: minecraft-volume + storage_account_name: minecraftdocker \ No newline at end of file From 6552a000047411085928a19af3289307a730a693 Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Fri, 14 Aug 2020 16:24:43 +0200 Subject: [PATCH 2/4] 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 - } - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token.AccessToken)) - res, err := http.DefaultClient.Do(req) - if err != nil { - return "", err + return "", errors.Wrap(err, fmt.Sprintf("could not access storage account acountKeys for %s, using the azure login", accountName)) } - 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 -} From 274dc8283fe02abfd3790362b4c9ac54fe660f1a Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Fri, 14 Aug 2020 17:01:35 +0200 Subject: [PATCH 3/4] Use proper context in storage key retrieval --- aci/backend.go | 4 +-- aci/convert/convert.go | 9 ++++--- aci/convert/convert_test.go | 25 ++++++++++--------- aci/login/StorageAccountHelper.go | 4 +-- aci/login/{clientsetup.go => client.go} | 4 +-- aci/resource_group.go | 4 +-- .../aci_demo_port_secrets_volumes.yaml | 2 +- 7 files changed, 27 insertions(+), 25 deletions(-) rename aci/login/{clientsetup.go => client.go} (97%) diff --git a/aci/backend.go b/aci/backend.go index f977c59d3..005bc763d 100644 --- a/aci/backend.go +++ b/aci/backend.go @@ -209,7 +209,7 @@ func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerCo } logrus.Debugf("Running container %q with name %q\n", r.Image, r.ID) - groupDefinition, err := convert.ToContainerGroup(cs.ctx, project) + groupDefinition, err := convert.ToContainerGroup(ctx, cs.ctx, project) if err != nil { return err } @@ -410,7 +410,7 @@ func (cs *aciComposeService) Up(ctx context.Context, opts cli.ProjectOptions) er return err } logrus.Debugf("Up on project with name %q\n", project.Name) - groupDefinition, err := convert.ToContainerGroup(cs.ctx, *project) + groupDefinition, err := convert.ToContainerGroup(ctx, cs.ctx, *project) addTag(&groupDefinition, composeContainerTag) if err != nil { diff --git a/aci/convert/convert.go b/aci/convert/convert.go index f5153f1ae..ae8528c22 100644 --- a/aci/convert/convert.go +++ b/aci/convert/convert.go @@ -17,6 +17,7 @@ package convert import ( + "context" "encoding/base64" "fmt" "io/ioutil" @@ -47,7 +48,7 @@ const ( ) // ToContainerGroup converts a compose project into a ACI container group -func ToContainerGroup(aciContext store.AciContext, p types.Project) (containerinstance.ContainerGroup, error) { +func ToContainerGroup(ctx context.Context, aciContext store.AciContext, p types.Project) (containerinstance.ContainerGroup, error) { project := projectAciHelper(p) containerGroupName := strings.ToLower(project.Name) loginService, err := login.NewAzureLoginService() @@ -58,7 +59,7 @@ func ToContainerGroup(aciContext store.AciContext, p types.Project) (containerin LoginService: *loginService, AciContext: aciContext, } - volumesCache, volumesSlice, err := project.getAciFileVolumes(storageHelper) + volumesCache, volumesSlice, err := project.getAciFileVolumes(ctx, storageHelper) if err != nil { return containerinstance.ContainerGroup{}, err } @@ -199,7 +200,7 @@ func (p projectAciHelper) getAciSecretVolumes() ([]containerinstance.Volume, err return secretVolumes, nil } -func (p projectAciHelper) getAciFileVolumes(helper login.StorageAccountHelper) (map[string]bool, []containerinstance.Volume, error) { +func (p projectAciHelper) getAciFileVolumes(ctx context.Context, helper login.StorageAccountHelper) (map[string]bool, []containerinstance.Volume, error) { azureFileVolumesMap := make(map[string]bool, len(p.Volumes)) var azureFileVolumesSlice []containerinstance.Volume for name, v := range p.Volumes { @@ -212,7 +213,7 @@ func (p projectAciHelper) getAciFileVolumes(helper login.StorageAccountHelper) ( if !ok { return nil, nil, fmt.Errorf("cannot retrieve account name for Azurefile") } - accountKey, err := helper.GetAzureStorageAccountKey(accountName) + accountKey, err := helper.GetAzureStorageAccountKey(ctx, accountName) if err != nil { return nil, nil, err } diff --git a/aci/convert/convert_test.go b/aci/convert/convert_test.go index 2667e8756..60c6b1650 100644 --- a/aci/convert/convert_test.go +++ b/aci/convert/convert_test.go @@ -17,6 +17,7 @@ package convert import ( + "context" "os" "testing" @@ -40,7 +41,7 @@ func TestProjectName(t *testing.T) { project := types.Project{ Name: "TEST", } - containerGroup, err := ToContainerGroup(convertCtx, project) + containerGroup, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) assert.Equal(t, *containerGroup.Name, "test") } @@ -117,7 +118,7 @@ func TestComposeContainerGroupToContainerWithDnsSideCarSide(t *testing.T) { }, } - group, err := ToContainerGroup(convertCtx, project) + group, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) assert.Assert(t, is.Len(*group.Containers, 3)) @@ -142,7 +143,7 @@ func TestComposeSingleContainerGroupToContainerNoDnsSideCarSide(t *testing.T) { }, } - group, err := ToContainerGroup(convertCtx, project) + group, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) assert.Assert(t, is.Len(*group.Containers, 1)) @@ -165,7 +166,7 @@ func TestComposeSingleContainerRestartPolicy(t *testing.T) { }, } - group, err := ToContainerGroup(convertCtx, project) + group, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) assert.Assert(t, is.Len(*group.Containers, 1)) @@ -197,7 +198,7 @@ func TestComposeMultiContainerRestartPolicy(t *testing.T) { }, } - group, err := ToContainerGroup(convertCtx, project) + group, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) assert.Assert(t, is.Len(*group.Containers, 3)) @@ -231,7 +232,7 @@ func TestComposeInconsistentMultiContainerRestartPolicy(t *testing.T) { }, } - _, err := ToContainerGroup(convertCtx, project) + _, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.Error(t, err, "ACI integration does not support specifying different restart policies on containers in the same compose application") } @@ -248,7 +249,7 @@ func TestLabelsErrorMessage(t *testing.T) { }, } - _, err := ToContainerGroup(convertCtx, project) + _, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.Error(t, err, "ACI integration does not support labels in compose applications") } @@ -262,7 +263,7 @@ func TestComposeSingleContainerGroupToContainerDefaultRestartPolicy(t *testing.T }, } - group, err := ToContainerGroup(convertCtx, project) + group, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) assert.Assert(t, is.Len(*group.Containers, 1)) @@ -296,7 +297,7 @@ func TestComposeContainerGroupToContainerMultiplePorts(t *testing.T) { }, } - group, err := ToContainerGroup(convertCtx, project) + group, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) assert.Assert(t, is.Len(*group.Containers, 3)) @@ -335,7 +336,7 @@ func TestComposeContainerGroupToContainerResourceLimits(t *testing.T) { }, } - group, err := ToContainerGroup(convertCtx, project) + group, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) limits := *((*group.Containers)[0]).Resources.Limits @@ -361,7 +362,7 @@ func TestComposeContainerGroupToContainerResourceLimitsDefaults(t *testing.T) { }, } - group, err := ToContainerGroup(convertCtx, project) + group, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) limits := *((*group.Containers)[0]).Resources.Limits @@ -385,7 +386,7 @@ func TestComposeContainerGroupToContainerenvVar(t *testing.T) { }, } - group, err := ToContainerGroup(convertCtx, project) + group, err := ToContainerGroup(context.TODO(), convertCtx, project) assert.NilError(t, err) envVars := *((*group.Containers)[0]).EnvironmentVariables diff --git a/aci/login/StorageAccountHelper.go b/aci/login/StorageAccountHelper.go index 8b1d9dfdc..42f7a23f0 100644 --- a/aci/login/StorageAccountHelper.go +++ b/aci/login/StorageAccountHelper.go @@ -16,12 +16,12 @@ type StorageAccountHelper struct { } // GetAzureStorageAccountKey retrieves the storage account ket from the current azure login -func (helper StorageAccountHelper) GetAzureStorageAccountKey(accountName string) (string, error) { +func (helper StorageAccountHelper) GetAzureStorageAccountKey(ctx context.Context, accountName string) (string, error) { client, err := GetStorageAccountsClient(helper.AciContext.SubscriptionID) if err != nil { return "", err } - result, err := client.ListKeys(context.TODO(), helper.AciContext.ResourceGroup, accountName, "") + result, err := client.ListKeys(ctx, helper.AciContext.ResourceGroup, accountName, "") if err != nil { return "", errors.Wrap(err, fmt.Sprintf("could not access storage account acountKeys for %s, using the azure login", accountName)) } diff --git a/aci/login/clientsetup.go b/aci/login/client.go similarity index 97% rename from aci/login/clientsetup.go rename to aci/login/client.go index edd72bf6a..afaad6c30 100644 --- a/aci/login/clientsetup.go +++ b/aci/login/client.go @@ -13,7 +13,7 @@ import ( "github.com/docker/api/errdefs" ) -const aciDockerUserAgent = "docker-cli" +const userAgent = "docker-cli" // GetContainerGroupsClient get client toi manipulate containerGrouos func GetContainerGroupsClient(subscriptionID string) (containerinstance.ContainerGroupsClient, error) { @@ -29,7 +29,7 @@ func GetContainerGroupsClient(subscriptionID string) (containerinstance.Containe } func setupClient(aciClient *autorest.Client) error { - aciClient.UserAgent = aciDockerUserAgent + aciClient.UserAgent = userAgent auth, err := NewAuthorizerFromLogin() if err != nil { return err diff --git a/aci/resource_group.go b/aci/resource_group.go index 8d3bb6c3c..3776e348d 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/aci/login" ) // ResourceGroupHelper interface to manage resource groups and subscription IDs diff --git a/tests/composefiles/aci-demo/aci_demo_port_secrets_volumes.yaml b/tests/composefiles/aci-demo/aci_demo_port_secrets_volumes.yaml index 31f982ed2..eb4f1b25b 100644 --- a/tests/composefiles/aci-demo/aci_demo_port_secrets_volumes.yaml +++ b/tests/composefiles/aci-demo/aci_demo_port_secrets_volumes.yaml @@ -22,4 +22,4 @@ volumes: driver: azure_file driver_opts: share_name: minecraft-volume - storage_account_name: minecraftdocker \ No newline at end of file + storage_account_name: minecraftdocker From 4ee5aa6267aee1c96ab8a5a51898c54e346d52b8 Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Fri, 14 Aug 2020 17:07:33 +0200 Subject: [PATCH 4/4] More renaming --- aci/aci.go | 14 ++++++------- aci/backend.go | 6 +++--- aci/login/client.go | 20 +++++++++---------- ...rageAccountHelper.go => storage_helper.go} | 2 +- aci/resource_group.go | 10 +++++----- 5 files changed, 26 insertions(+), 26 deletions(-) rename aci/login/{StorageAccountHelper.go => storage_helper.go} (93%) diff --git a/aci/aci.go b/aci/aci.go index 2b5dfbb91..c22994d75 100644 --- a/aci/aci.go +++ b/aci/aci.go @@ -42,7 +42,7 @@ import ( ) func createACIContainers(ctx context.Context, aciContext store.AciContext, groupDefinition containerinstance.ContainerGroup) error { - containerGroupsClient, err := login.GetContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.NewContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return errors.Wrapf(err, "cannot get container group client") } @@ -66,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 := login.GetContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.NewContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return errors.Wrapf(err, "cannot get container group client") } @@ -121,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 := login.GetContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.NewContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return containerinstance.ContainerGroup{}, fmt.Errorf("cannot get container group client: %v", err) } @@ -130,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 := login.GetContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.NewContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return containerinstance.ContainerGroup{}, fmt.Errorf("cannot get container group client: %v", err) } @@ -139,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 := login.GetContainerGroupsClient(aciContext.SubscriptionID) + containerGroupsClient, err := login.NewContainerGroupsClient(aciContext.SubscriptionID) if err != nil { return fmt.Errorf("cannot get container group client: %v", err) } @@ -152,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 := login.GetContainerClient(aciContext.SubscriptionID) + containerClient, err := login.NewContainerClient(aciContext.SubscriptionID) if err != nil { return c, errors.Wrapf(err, "cannot get container client") } @@ -245,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 := login.GetContainerClient(aciContext.SubscriptionID) + containerClient, err := login.NewContainerClient(aciContext.SubscriptionID) if err != nil { return "", errors.Wrapf(err, "cannot get container client") } diff --git a/aci/backend.go b/aci/backend.go index 005bc763d..71679a070 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 := login.GetContainerGroupsClient(cs.ctx.SubscriptionID) + groupsClient, err := login.NewContainerGroupsClient(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 := login.GetContainerGroupsClient(cs.ctx.SubscriptionID) + containerGroupsClient, err := login.NewContainerGroupsClient(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 := login.GetContainerGroupsClient(cs.ctx.SubscriptionID) + containerGroupsClient, err := login.NewContainerGroupsClient(cs.ctx.SubscriptionID) if err != nil { return err } diff --git a/aci/login/client.go b/aci/login/client.go index afaad6c30..ad92441bb 100644 --- a/aci/login/client.go +++ b/aci/login/client.go @@ -15,8 +15,8 @@ import ( const userAgent = "docker-cli" -// GetContainerGroupsClient get client toi manipulate containerGrouos -func GetContainerGroupsClient(subscriptionID string) (containerinstance.ContainerGroupsClient, error) { +// NewContainerGroupsClient get client toi manipulate containerGrouos +func NewContainerGroupsClient(subscriptionID string) (containerinstance.ContainerGroupsClient, error) { containerGroupsClient := containerinstance.NewContainerGroupsClient(subscriptionID) err := setupClient(&containerGroupsClient.Client) if err != nil { @@ -38,8 +38,8 @@ func setupClient(aciClient *autorest.Client) error { return nil } -// GetStorageAccountsClient get client to manipulate storage accounts -func GetStorageAccountsClient(subscriptionID string) (storage.AccountsClient, error) { +// NewStorageAccountsClient get client to manipulate storage accounts +func NewStorageAccountsClient(subscriptionID string) (storage.AccountsClient, error) { containerGroupsClient := storage.NewAccountsClient(subscriptionID) err := setupClient(&containerGroupsClient.Client) if err != nil { @@ -51,8 +51,8 @@ func GetStorageAccountsClient(subscriptionID string) (storage.AccountsClient, er return containerGroupsClient, nil } -// GetSubscriptionsClient get subscription client -func GetSubscriptionsClient() (subscription.SubscriptionsClient, error) { +// NewSubscriptionsClient get subscription client +func NewSubscriptionsClient() (subscription.SubscriptionsClient, error) { subc := subscription.NewSubscriptionsClient() err := setupClient(&subc.Client) if err != nil { @@ -61,8 +61,8 @@ func GetSubscriptionsClient() (subscription.SubscriptionsClient, error) { return subc, nil } -// GetGroupsClient get client to manipulate groups -func GetGroupsClient(subscriptionID string) (resources.GroupsClient, error) { +// NewGroupsClient get client to manipulate groups +func NewGroupsClient(subscriptionID string) (resources.GroupsClient, error) { groupsClient := resources.NewGroupsClient(subscriptionID) err := setupClient(&groupsClient.Client) if err != nil { @@ -71,8 +71,8 @@ func GetGroupsClient(subscriptionID string) (resources.GroupsClient, error) { return groupsClient, nil } -// GetContainerClient get client to manipulate containers -func GetContainerClient(subscriptionID string) (containerinstance.ContainerClient, error) { +// NewContainerClient get client to manipulate containers +func NewContainerClient(subscriptionID string) (containerinstance.ContainerClient, error) { containerClient := containerinstance.NewContainerClient(subscriptionID) err := setupClient(&containerClient.Client) if err != nil { diff --git a/aci/login/StorageAccountHelper.go b/aci/login/storage_helper.go similarity index 93% rename from aci/login/StorageAccountHelper.go rename to aci/login/storage_helper.go index 42f7a23f0..51d047462 100644 --- a/aci/login/StorageAccountHelper.go +++ b/aci/login/storage_helper.go @@ -17,7 +17,7 @@ type StorageAccountHelper struct { // GetAzureStorageAccountKey retrieves the storage account ket from the current azure login func (helper StorageAccountHelper) GetAzureStorageAccountKey(ctx context.Context, accountName string) (string, error) { - client, err := GetStorageAccountsClient(helper.AciContext.SubscriptionID) + client, err := NewStorageAccountsClient(helper.AciContext.SubscriptionID) if err != nil { return "", err } diff --git a/aci/resource_group.go b/aci/resource_group.go index 3776e348d..e5f623f5c 100644 --- a/aci/resource_group.go +++ b/aci/resource_group.go @@ -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 := login.GetGroupsClient(subscriptionID) + gc, err := login.NewGroupsClient(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 := login.GetGroupsClient(subscriptionID) + gc, err := login.NewGroupsClient(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 := login.GetGroupsClient(subscriptionID) + gc, err := login.NewGroupsClient(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 := login.GetGroupsClient(subscriptionID) + gc, err := login.NewGroupsClient(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 := login.GetSubscriptionsClient() + c, err := login.NewSubscriptionsClient() if err != nil { return nil, err }