~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/apiserver/cloud/cloud.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2016 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
// Package cloud defines an API end point for functions dealing with
 
5
// the controller's cloud definition, and cloud credentials.
 
6
package cloud
 
7
 
 
8
import (
 
9
        "github.com/juju/loggo"
 
10
        "gopkg.in/juju/names.v2"
 
11
 
 
12
        "github.com/juju/juju/apiserver/common"
 
13
        "github.com/juju/juju/apiserver/facade"
 
14
        "github.com/juju/juju/apiserver/params"
 
15
        "github.com/juju/juju/cloud"
 
16
        "github.com/juju/juju/state"
 
17
)
 
18
 
 
19
var logger = loggo.GetLogger("juju.apiserver.cloud")
 
20
 
 
21
func init() {
 
22
        common.RegisterStandardFacade("Cloud", 1, newFacade)
 
23
}
 
24
 
 
25
// CloudAPI implements the model manager interface and is
 
26
// the concrete implementation of the api end point.
 
27
type CloudAPI struct {
 
28
        backend                  Backend
 
29
        authorizer               facade.Authorizer
 
30
        apiUser                  names.UserTag
 
31
        getCredentialsAuthFunc   common.GetAuthFunc
 
32
        getCloudDefaultsAuthFunc common.GetAuthFunc
 
33
}
 
34
 
 
35
func newFacade(st *state.State, resources facade.Resources, auth facade.Authorizer) (*CloudAPI, error) {
 
36
        return NewCloudAPI(NewStateBackend(st), auth)
 
37
}
 
38
 
 
39
// NewCloudAPI creates a new API server endpoint for managing the controller's
 
40
// cloud definition and cloud credentials.
 
41
func NewCloudAPI(backend Backend, authorizer facade.Authorizer) (*CloudAPI, error) {
 
42
        if !authorizer.AuthClient() {
 
43
                return nil, common.ErrPerm
 
44
        }
 
45
        getUserAuthFunc := func() (common.AuthFunc, error) {
 
46
                authUser, _ := authorizer.GetAuthTag().(names.UserTag)
 
47
                isAdmin, err := backend.IsControllerAdministrator(authUser)
 
48
                if err != nil {
 
49
                        return nil, err
 
50
                }
 
51
                return func(tag names.Tag) bool {
 
52
                        userTag, ok := tag.(names.UserTag)
 
53
                        if !ok {
 
54
                                return false
 
55
                        }
 
56
                        return isAdmin || userTag.Canonical() == authUser.Canonical()
 
57
                }, nil
 
58
        }
 
59
        return &CloudAPI{
 
60
                backend:                  backend,
 
61
                authorizer:               authorizer,
 
62
                getCredentialsAuthFunc:   getUserAuthFunc,
 
63
                getCloudDefaultsAuthFunc: getUserAuthFunc,
 
64
        }, nil
 
65
}
 
66
 
 
67
// Cloud returns the cloud definitions for the specified clouds.
 
68
func (mm *CloudAPI) Cloud(args params.Entities) (params.CloudResults, error) {
 
69
        results := params.CloudResults{
 
70
                Results: make([]params.CloudResult, len(args.Entities)),
 
71
        }
 
72
        one := func(arg params.Entity) (*params.Cloud, error) {
 
73
                tag, err := names.ParseCloudTag(arg.Tag)
 
74
                if err != nil {
 
75
                        return nil, err
 
76
                }
 
77
                cloud, err := mm.backend.Cloud(tag.Id())
 
78
                if err != nil {
 
79
                        return nil, err
 
80
                }
 
81
                authTypes := make([]string, len(cloud.AuthTypes))
 
82
                for i, authType := range cloud.AuthTypes {
 
83
                        authTypes[i] = string(authType)
 
84
                }
 
85
                regions := make([]params.CloudRegion, len(cloud.Regions))
 
86
                for i, region := range cloud.Regions {
 
87
                        regions[i] = params.CloudRegion{
 
88
                                Name:            region.Name,
 
89
                                Endpoint:        region.Endpoint,
 
90
                                StorageEndpoint: region.StorageEndpoint,
 
91
                        }
 
92
                }
 
93
                return &params.Cloud{
 
94
                        Type:            cloud.Type,
 
95
                        AuthTypes:       authTypes,
 
96
                        Endpoint:        cloud.Endpoint,
 
97
                        StorageEndpoint: cloud.StorageEndpoint,
 
98
                        Regions:         regions,
 
99
                }, nil
 
100
        }
 
101
        for i, arg := range args.Entities {
 
102
                cloud, err := one(arg)
 
103
                if err != nil {
 
104
                        results.Results[i].Error = common.ServerError(err)
 
105
                } else {
 
106
                        results.Results[i].Cloud = cloud
 
107
                }
 
108
        }
 
109
        return results, nil
 
110
}
 
111
 
 
112
// CloudDefaults returns the cloud defaults for a set of users.
 
113
func (mm *CloudAPI) CloudDefaults(args params.Entities) (params.CloudDefaultsResults, error) {
 
114
        results := params.CloudDefaultsResults{
 
115
                Results: make([]params.CloudDefaultsResult, len(args.Entities)),
 
116
        }
 
117
        authFunc, err := mm.getCloudDefaultsAuthFunc()
 
118
        if err != nil {
 
119
                return results, err
 
120
        }
 
121
        controllerModel, err := mm.backend.ControllerModel()
 
122
        if err != nil {
 
123
                return results, err
 
124
        }
 
125
        for i, arg := range args.Entities {
 
126
                userTag, err := names.ParseUserTag(arg.Tag)
 
127
                if err != nil {
 
128
                        results.Results[i].Error = common.ServerError(err)
 
129
                        continue
 
130
                }
 
131
                if !authFunc(userTag) {
 
132
                        results.Results[i].Error = common.ServerError(common.ErrPerm)
 
133
                        continue
 
134
                }
 
135
                isAdmin, err := mm.backend.IsControllerAdministrator(userTag)
 
136
                if err != nil {
 
137
                        results.Results[i].Error = common.ServerError(err)
 
138
                        continue
 
139
                }
 
140
                cloudDefaults := params.CloudDefaults{
 
141
                        CloudTag:    names.NewCloudTag(controllerModel.Cloud()).String(),
 
142
                        CloudRegion: controllerModel.CloudRegion(),
 
143
                }
 
144
                if isAdmin {
 
145
                        // As a special case, controller admins will default to
 
146
                        // using the same credential that was used to bootstrap.
 
147
                        cloudDefaults.CloudCredential = controllerModel.CloudCredential()
 
148
                }
 
149
                results.Results[i].Result = &cloudDefaults
 
150
        }
 
151
        return results, nil
 
152
}
 
153
 
 
154
// Credentials returns the cloud credentials for a set of users.
 
155
func (mm *CloudAPI) Credentials(args params.UserClouds) (params.CloudCredentialsResults, error) {
 
156
        results := params.CloudCredentialsResults{
 
157
                Results: make([]params.CloudCredentialsResult, len(args.UserClouds)),
 
158
        }
 
159
        authFunc, err := mm.getCredentialsAuthFunc()
 
160
        if err != nil {
 
161
                return results, err
 
162
        }
 
163
        for i, arg := range args.UserClouds {
 
164
                userTag, err := names.ParseUserTag(arg.UserTag)
 
165
                if err != nil {
 
166
                        results.Results[i].Error = common.ServerError(err)
 
167
                        continue
 
168
                }
 
169
                if !authFunc(userTag) {
 
170
                        results.Results[i].Error = common.ServerError(common.ErrPerm)
 
171
                        continue
 
172
                }
 
173
                cloudTag, err := names.ParseCloudTag(arg.CloudTag)
 
174
                if err != nil {
 
175
                        results.Results[i].Error = common.ServerError(err)
 
176
                        continue
 
177
                }
 
178
                cloudCredentials, err := mm.backend.CloudCredentials(userTag, cloudTag.Id())
 
179
                if err != nil {
 
180
                        results.Results[i].Error = common.ServerError(err)
 
181
                        continue
 
182
                }
 
183
                out := make(map[string]params.CloudCredential)
 
184
                for name, credential := range cloudCredentials {
 
185
                        out[name] = params.CloudCredential{
 
186
                                string(credential.AuthType()),
 
187
                                credential.Attributes(),
 
188
                        }
 
189
                }
 
190
                results.Results[i].Credentials = out
 
191
        }
 
192
        return results, nil
 
193
}
 
194
 
 
195
// UpdateCredentials updates the cloud credentials for a set of users.
 
196
func (mm *CloudAPI) UpdateCredentials(args params.UsersCloudCredentials) (params.ErrorResults, error) {
 
197
        results := params.ErrorResults{
 
198
                Results: make([]params.ErrorResult, len(args.Users)),
 
199
        }
 
200
        authFunc, err := mm.getCredentialsAuthFunc()
 
201
        if err != nil {
 
202
                return results, err
 
203
        }
 
204
        for i, arg := range args.Users {
 
205
                userTag, err := names.ParseUserTag(arg.UserTag)
 
206
                if err != nil {
 
207
                        results.Results[i].Error = common.ServerError(err)
 
208
                        continue
 
209
                }
 
210
                if !authFunc(userTag) {
 
211
                        results.Results[i].Error = common.ServerError(common.ErrPerm)
 
212
                        continue
 
213
                }
 
214
                cloudTag, err := names.ParseCloudTag(arg.CloudTag)
 
215
                if err != nil {
 
216
                        results.Results[i].Error = common.ServerError(err)
 
217
                        continue
 
218
                }
 
219
                in := make(map[string]cloud.Credential)
 
220
                for name, credential := range arg.Credentials {
 
221
                        in[name] = cloud.NewCredential(
 
222
                                cloud.AuthType(credential.AuthType), credential.Attributes,
 
223
                        )
 
224
                }
 
225
                if err := mm.backend.UpdateCloudCredentials(userTag, cloudTag.Id(), in); err != nil {
 
226
                        results.Results[i].Error = common.ServerError(err)
 
227
                        continue
 
228
                }
 
229
        }
 
230
        return results, nil
 
231
}