Merge pull request #625 from docker/aci_context_create_no_sub

Check specified subscription in context create and if not found, prompt users they might need to login with -—tenant-id.
This commit is contained in:
Guillaume Tardif 2020-09-17 22:29:06 +02:00 committed by GitHub
commit 10372b7098
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 16 deletions

View File

@ -44,14 +44,6 @@ const (
composeContainerSeparator = "_"
)
// ContextParams options for creating ACI context
type ContextParams struct {
Description string
Location string
SubscriptionID string
ResourceGroup string
}
// LoginParams azure login options
type LoginParams struct {
TenantID string

View File

@ -31,6 +31,22 @@ import (
"github.com/docker/compose-cli/prompt"
)
// ContextParams options for creating ACI context
type ContextParams struct {
Description string
Location string
SubscriptionID string
ResourceGroup string
}
// ErrSubscriptionNotFound is returned when a required subscription is not found
var ErrSubscriptionNotFound = errors.New("subscription not found")
// IsSubscriptionNotFoundError returns true if the unwrapped error is IsSubscriptionNotFoundError
func IsSubscriptionNotFoundError(err error) bool {
return errors.Is(err, ErrSubscriptionNotFound)
}
type contextCreateACIHelper struct {
selector prompt.UI
resourceGroupHelper ResourceGroupHelper
@ -44,14 +60,21 @@ func newContextCreateHelper() contextCreateACIHelper {
}
func (helper contextCreateACIHelper) createContextData(ctx context.Context, opts ContextParams) (interface{}, string, error) {
var subscriptionID string
if opts.SubscriptionID != "" {
subscriptionID = opts.SubscriptionID
} else {
subs, err := helper.resourceGroupHelper.GetSubscriptionIDs(ctx)
if err != nil {
return nil, "", err
}
subscriptionID := ""
if opts.SubscriptionID != "" {
for _, sub := range subs {
if *sub.SubscriptionID == opts.SubscriptionID {
subscriptionID = opts.SubscriptionID
}
}
if subscriptionID == "" {
return nil, "", ErrSubscriptionNotFound
}
} else {
subscriptionID, err = helper.chooseSub(subs)
if err != nil {
return nil, "", err
@ -59,8 +82,6 @@ func (helper contextCreateACIHelper) createContextData(ctx context.Context, opts
}
var group resources.Group
var err error
if opts.ResourceGroup != "" {
group, err = helper.resourceGroupHelper.GetGroup(ctx, subscriptionID, opts.ResourceGroup)
if err != nil {

View File

@ -51,6 +51,7 @@ func TestCreateSpecifiedSubscriptionAndGroup(t *testing.T) {
ctx := context.TODO()
opts := options("1234", "myResourceGroup")
m := testContextMocks()
m.resourceGroupHelper.On("GetSubscriptionIDs", ctx).Return([]subscription.Model{subModel("1234", "Subscription1")}, nil)
m.resourceGroupHelper.On("GetGroup", ctx, "1234", "myResourceGroup").Return(group("myResourceGroup", "eastus"), nil)
data, description, err := m.contextCreateHelper.createContextData(ctx, opts)
@ -64,6 +65,7 @@ func TestErrorOnNonExistentResourceGroup(t *testing.T) {
opts := options("1234", "myResourceGroup")
notFoundError := errors.New(`Not Found: "myResourceGroup"`)
m := testContextMocks()
m.resourceGroupHelper.On("GetSubscriptionIDs", ctx).Return([]subscription.Model{subModel("1234", "Subscription1")}, nil)
m.resourceGroupHelper.On("GetGroup", ctx, "1234", "myResourceGroup").Return(resources.Group{}, notFoundError)
data, description, err := m.contextCreateHelper.createContextData(ctx, opts)
@ -72,10 +74,23 @@ func TestErrorOnNonExistentResourceGroup(t *testing.T) {
assert.Error(t, err, "Could not find resource group \"myResourceGroup\": Not Found: \"myResourceGroup\"")
}
func TestErrorOnNonExistentSubscriptionID(t *testing.T) {
ctx := context.TODO()
opts := options("otherSubscription", "myResourceGroup")
m := testContextMocks()
m.resourceGroupHelper.On("GetSubscriptionIDs", ctx).Return([]subscription.Model{subModel("1234", "Subscription1")}, nil)
data, description, err := m.contextCreateHelper.createContextData(ctx, opts)
assert.Assert(t, cmp.Nil(data))
assert.Equal(t, description, "")
assert.Assert(t, err == ErrSubscriptionNotFound)
}
func TestCreateNewResourceGroup(t *testing.T) {
ctx := context.TODO()
opts := options("1234", "")
m := testContextMocks()
m.resourceGroupHelper.On("GetSubscriptionIDs", ctx).Return([]subscription.Model{subModel("1234", "Subscription1")}, nil)
m.resourceGroupHelper.On("GetGroup", ctx, "1234", "myResourceGroup").Return(group("myResourceGroup", "eastus"), nil)
selectOptions := []string{"create a new resource group", "group1 (eastus)", "group2 (westeurope)"}
@ -97,6 +112,7 @@ func TestSelectExistingResourceGroup(t *testing.T) {
opts := options("1234", "")
selectOptions := []string{"create a new resource group", "group1 (eastus)", "group2 (westeurope)"}
m := testContextMocks()
m.resourceGroupHelper.On("GetSubscriptionIDs", ctx).Return([]subscription.Model{subModel("1234", "Subscription1")}, nil)
m.userPrompt.On("Select", "Select a resource group", selectOptions).Return(2, nil)
m.resourceGroupHelper.On("ListGroups", ctx, "1234").Return([]resources.Group{
group("group1", "eastus"),

View File

@ -62,6 +62,9 @@ func runCreateAci(ctx context.Context, contextName string, opts aci.ContextParam
}
contextData, description, err := getAciContextData(ctx, opts)
if err != nil {
if aci.IsSubscriptionNotFoundError(err) {
return errors.New("could not find the requested subscription from your Azure login. You might need to specify a tenant ID with docker login azure --tenant-id xxx")
}
return err
}
return createDockerContext(ctx, contextName, store.AciContextType, description, contextData)