Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
Get sub from azure CLI when not provided (#3519)
Browse files Browse the repository at this point in the history
thanks @cpuguy83!
  • Loading branch information
cpuguy83 authored and jackfrancis committed Jul 23, 2018
1 parent d67883c commit 03e6909
Show file tree
Hide file tree
Showing 17 changed files with 3,097 additions and 2 deletions.
8 changes: 7 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,7 @@
[prune]
go-tests = true
unused-packages = true

[[constraint]]
name = "gopkg.in/ini.v1"
version = "1.38.1"
49 changes: 48 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ package cmd

import (
"os"
"path/filepath"

"github.com/Azure/acs-engine/pkg/armhelpers"
"github.com/Azure/acs-engine/pkg/helpers"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/pkg/errors"
uuid "github.com/satori/go.uuid"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
flag "github.com/spf13/pflag"
ini "gopkg.in/ini.v1"
)

const (
Expand Down Expand Up @@ -91,7 +94,12 @@ func (authArgs *authArgs) validateAuthArgs() error {
}

if authArgs.SubscriptionID.String() == "00000000-0000-0000-0000-000000000000" {
return errors.New("--subscription-id is required (and must be a valid UUID)")
subID, err := getSubFromAzDir(filepath.Join(helpers.GetHomeDir(), ".azure"))
if err != nil || subID.String() == "00000000-0000-0000-0000-000000000000" {
return errors.New("--subscription-id is required (and must be a valid UUID)")
}
log.Infoln("No subscription provided, using selected subscription from azure CLI:", subID.String())
authArgs.SubscriptionID = subID
}

_, err := azure.EnvironmentFromName(authArgs.RawAzureEnvironment)
Expand All @@ -101,6 +109,45 @@ func (authArgs *authArgs) validateAuthArgs() error {
return nil
}

func getSubFromAzDir(root string) (uuid.UUID, error) {
subConfig, err := ini.Load(filepath.Join(root, "clouds.config"))
if err != nil {
return uuid.UUID{}, errors.Wrap(err, "error decoding cloud subscription config")
}

cloudConfig, err := ini.Load(filepath.Join(root, "config"))
if err != nil {
return uuid.UUID{}, errors.Wrap(err, "error decoding cloud config")
}

cloud := getSelectedCloudFromAzConfig(cloudConfig)
return getCloudSubFromAzConfig(cloud, subConfig)
}

func getSelectedCloudFromAzConfig(f *ini.File) string {
selectedCloud := "AzureCloud"
if cloud, err := f.GetSection("cloud"); err == nil {
if name, err := cloud.GetKey("name"); err == nil {
if s := name.String(); s != "" {
selectedCloud = s
}
}
}
return selectedCloud
}

func getCloudSubFromAzConfig(cloud string, f *ini.File) (uuid.UUID, error) {
cfg, err := f.GetSection(cloud)
if err != nil {
return uuid.UUID{}, errors.New("could not find user defined subscription id")
}
sub, err := cfg.GetKey("subscription")
if err != nil {
return uuid.UUID{}, errors.Wrap(err, "error reading subscription id from cloud config")
}
return uuid.FromString(sub.String())
}

func (authArgs *authArgs) getClient() (*armhelpers.AzureClient, error) {
var client *armhelpers.AzureClient
env, err := azure.EnvironmentFromName(authArgs.RawAzureEnvironment)
Expand Down
87 changes: 87 additions & 0 deletions cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package cmd
import (
"testing"

uuid "github.com/satori/go.uuid"
"github.com/spf13/cobra"
ini "gopkg.in/ini.v1"
)

func TestNewRootCmd(t *testing.T) {
Expand All @@ -19,3 +21,88 @@ func TestNewRootCmd(t *testing.T) {
}
}
}

func TestGetSelectedCloudFromAzConfig(t *testing.T) {
for _, test := range []struct {
desc string
data []byte
expect string
}{
{"nil file", nil, "AzureCloud"},
{"empty file", []byte{}, "AzureCloud"},
{"no cloud section", []byte(`
[key]
foo = bar
`), "AzureCloud"},
{"cloud section empty", []byte(`
[cloud]
[foo]
foo = bar
`), "AzureCloud"},
{"AzureCloud selected", []byte(`
[cloud]
name = AzureCloud
`), "AzureCloud"},
{"custom cloud", []byte(`
[cloud]
name = myCloud
`), "myCloud"},
} {
t.Run(test.desc, func(t *testing.T) {
f, err := ini.Load(test.data)
if err != nil {
t.Fatal(err)
}

cloud := getSelectedCloudFromAzConfig(f)
if cloud != test.expect {
t.Fatalf("exepcted %q, got %q", test.expect, cloud)
}
})
}
}

func TestGetCloudSubFromAzConfig(t *testing.T) {
goodUUID, err := uuid.FromString("ccabad21-ea42-4ea1-affc-17ae73f9df66")
if err != nil {
t.Fatal(err)
}
for _, test := range []struct {
desc string
data []byte
expect uuid.UUID
err bool
}{
{"empty file", []byte{}, uuid.UUID{}, true},
{"no entry for cloud", []byte(`
[SomeCloud]
subscription = 00000000-0000-0000-0000-000000000000
`), uuid.UUID{}, true},
{"invalid UUID", []byte(`
[AzureCloud]
subscription = not-a-good-value
`), uuid.UUID{}, true},
{"real UUID", []byte(`
[AzureCloud]
subscription = ` + goodUUID.String() + `
`), goodUUID, false},
} {
t.Run(test.desc, func(t *testing.T) {
f, err := ini.Load(test.data)
if err != nil {
t.Fatal(err)
}

uuid, err := getCloudSubFromAzConfig("AzureCloud", f)
if test.err != (err != nil) {
t.Fatalf("expected err=%v, got: %v", test.err, err)
}
if test.err {
return
}
if uuid.String() != test.expect.String() {
t.Fatalf("expected %s, got %s", test.expect, uuid)
}
})
}
}
14 changes: 14 additions & 0 deletions pkg/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"crypto/rsa"
"encoding/json"
"io"
"os"
"runtime"
"strings"

"github.com/Azure/acs-engine/pkg/i18n"
Expand Down Expand Up @@ -118,3 +120,15 @@ func AcceleratedNetworkingSupported(sku string) bool {
}
return true
}

// GetHomeDir attempts to get the home dir from env
func GetHomeDir() string {
if runtime.GOOS == "windows" {
home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
if home == "" {
home = os.Getenv("USERPROFILE")
}
return home
}
return os.Getenv("HOME")
}
6 changes: 6 additions & 0 deletions vendor/gopkg.in/ini.v1/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions vendor/gopkg.in/ini.v1/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 03e6909

Please sign in to comment.