~juju-qa/ubuntu/xenial/juju/2.0-rc2

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/provider/azure/credentials.go

  • Committer: Nicholas Skaggs
  • Date: 2016-09-30 14:39:30 UTC
  • mfrom: (1.8.1)
  • Revision ID: nicholas.skaggs@canonical.com-20160930143930-vwwhrefh6ftckccy
import upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
package azure
5
5
 
6
6
import (
 
7
        "fmt"
 
8
 
 
9
        "github.com/Azure/go-autorest/autorest"
7
10
        "github.com/juju/errors"
 
11
        "github.com/juju/utils"
 
12
        "github.com/juju/utils/clock"
8
13
 
9
14
        "github.com/juju/juju/cloud"
 
15
        "github.com/juju/juju/environs"
 
16
        "github.com/juju/juju/provider/azure/internal/azureauth"
10
17
)
11
18
 
12
19
const (
14
21
        credAttrSubscriptionId = "subscription-id"
15
22
        credAttrTenantId       = "tenant-id"
16
23
        credAttrAppPassword    = "application-password"
 
24
 
 
25
        // clientCredentialsAuthType is the auth-type for the
 
26
        // "client credentials" OAuth flow, which requires a
 
27
        // service principal with a password.
 
28
        clientCredentialsAuthType cloud.AuthType = "service-principal-secret"
 
29
 
 
30
        // deviceCodeAuthType is the auth-type for the interactive
 
31
        // "device code" OAuth flow.
 
32
        deviceCodeAuthType cloud.AuthType = "interactive"
17
33
)
18
34
 
19
35
// environPoviderCredentials is an implementation of
20
36
// environs.ProviderCredentials for the Azure Resource
21
37
// Manager cloud provider.
22
 
type environProviderCredentials struct{}
 
38
type environProviderCredentials struct {
 
39
        sender                            autorest.Sender
 
40
        requestInspector                  autorest.PrepareDecorator
 
41
        interactiveCreateServicePrincipal azureauth.InteractiveCreateServicePrincipalFunc
 
42
}
23
43
 
24
44
// CredentialSchemas is part of the environs.ProviderCredentials interface.
25
45
func (environProviderCredentials) CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema {
26
46
        return map[cloud.AuthType]cloud.CredentialSchema{
 
47
                // TODO(axw) 2016-09-15 #1623761
 
48
                // UserPassAuthType is here for backwards
 
49
                // compatibility. Drop it when rc1 is out.
27
50
                cloud.UserPassAuthType: {
28
51
                        {
29
52
                                credAttrAppId, cloud.CredentialAttr{Description: "Azure Active Directory application ID"},
30
53
                        }, {
31
54
                                credAttrSubscriptionId, cloud.CredentialAttr{Description: "Azure subscription ID"},
32
55
                        }, {
33
 
                                credAttrTenantId, cloud.CredentialAttr{Description: "Azure Active Directory tenant ID"},
 
56
                                credAttrTenantId, cloud.CredentialAttr{
 
57
                                        Description: "Azure Active Directory tenant ID",
 
58
                                        Optional:    true,
 
59
                                },
 
60
                        }, {
 
61
                                credAttrAppPassword, cloud.CredentialAttr{
 
62
                                        Description: "Azure Active Directory application password",
 
63
                                        Hidden:      true,
 
64
                                },
 
65
                        },
 
66
                },
 
67
 
 
68
                // deviceCodeAuthType is the interactive device-code oauth
 
69
                // flow. This is only supported on the client side; it will
 
70
                // be used to generate a service principal, and transformed
 
71
                // into clientCredentialsAuthType.
 
72
                deviceCodeAuthType: {{
 
73
                        credAttrSubscriptionId, cloud.CredentialAttr{Description: "Azure subscription ID"},
 
74
                }},
 
75
 
 
76
                // clientCredentialsAuthType is the "client credentials"
 
77
                // oauth flow, which requires a service principal with a
 
78
                // password.
 
79
                clientCredentialsAuthType: {
 
80
                        {
 
81
                                credAttrAppId, cloud.CredentialAttr{Description: "Azure Active Directory application ID"},
 
82
                        }, {
 
83
                                credAttrSubscriptionId, cloud.CredentialAttr{Description: "Azure subscription ID"},
34
84
                        }, {
35
85
                                credAttrAppPassword, cloud.CredentialAttr{
36
86
                                        Description: "Azure Active Directory application password",
45
95
func (environProviderCredentials) DetectCredentials() (*cloud.CloudCredential, error) {
46
96
        return nil, errors.NotFoundf("credentials")
47
97
}
 
98
 
 
99
// FinalizeCredential is part of the environs.ProviderCredentials interface.
 
100
func (c environProviderCredentials) FinalizeCredential(
 
101
        ctx environs.FinalizeCredentialContext,
 
102
        args environs.FinalizeCredentialParams,
 
103
) (*cloud.Credential, error) {
 
104
        switch authType := args.Credential.AuthType(); authType {
 
105
        case cloud.UserPassAuthType:
 
106
                fmt.Fprintf(ctx.GetStderr(), `
 
107
WARNING: The %q auth-type is deprecated, and will be removed soon.
 
108
 
 
109
Please update the credential in ~/.local/share/juju/credentials.yaml,
 
110
changing auth-type to %q, and dropping the tenant-id field.
 
111
 
 
112
`[1:],
 
113
                        authType, clientCredentialsAuthType,
 
114
                )
 
115
                attrs := args.Credential.Attributes()
 
116
                delete(attrs, credAttrTenantId)
 
117
                out := cloud.NewCredential(clientCredentialsAuthType, attrs)
 
118
                out.Label = args.Credential.Label
 
119
                return &out, nil
 
120
 
 
121
        case deviceCodeAuthType:
 
122
                subscriptionId := args.Credential.Attributes()[credAttrSubscriptionId]
 
123
                applicationId, password, err := c.interactiveCreateServicePrincipal(
 
124
                        ctx.GetStderr(),
 
125
                        c.sender,
 
126
                        c.requestInspector,
 
127
                        args.CloudEndpoint,
 
128
                        args.CloudIdentityEndpoint,
 
129
                        subscriptionId,
 
130
                        clock.WallClock,
 
131
                        utils.NewUUID,
 
132
                )
 
133
                if err != nil {
 
134
                        return nil, errors.Trace(err)
 
135
                }
 
136
                out := cloud.NewCredential(clientCredentialsAuthType, map[string]string{
 
137
                        credAttrSubscriptionId: subscriptionId,
 
138
                        credAttrAppId:          applicationId,
 
139
                        credAttrAppPassword:    password,
 
140
                })
 
141
                out.Label = args.Credential.Label
 
142
                return &out, nil
 
143
 
 
144
        case clientCredentialsAuthType:
 
145
                return &args.Credential, nil
 
146
        default:
 
147
                return nil, errors.NotSupportedf("%q auth-type", authType)
 
148
        }
 
149
}