Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(637)

Side by Side Diff: state/apiserver/root.go

Issue 10044043: state/apiserver: Split Machiner into subpackage (Closed)
Patch Set: state/apiserver: Split Machiner into subpackage Created 11 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « state/apiserver/machiner/machiner_test.go ('k') | state/apiserver/user.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 Canonical Ltd. 1 // Copyright 2013 Canonical Ltd.
2 // Licensed under the AGPLv3, see LICENCE file for details. 2 // Licensed under the AGPLv3, see LICENCE file for details.
3 3
4 package apiserver 4 package apiserver
5 5
6 import ( 6 import (
7 "launchpad.net/juju-core/state" 7 "launchpad.net/juju-core/state"
8 "launchpad.net/juju-core/state/apiserver/common"
9 "launchpad.net/juju-core/state/apiserver/machiner"
8 "launchpad.net/juju-core/state/multiwatcher" 10 "launchpad.net/juju-core/state/multiwatcher"
9 ) 11 )
10 12
11 // srvRoot represents a single client's connection to the state. 13 // srvRoot represents a single client's connection to the state.
12 type srvRoot struct { 14 type srvRoot struct {
13 admin *srvAdmin 15 admin *srvAdmin
14 client *srvClient 16 client *srvClient
15 state *srvState 17 state *srvState
16 srv *Server 18 srv *Server
17 machiner *srvMachiner
18 resources *resources 19 resources *resources
19 20
20 user authUser 21 user authUser
21 } 22 }
22 23
23 func newStateServer(srv *Server) *srvRoot { 24 func newStateServer(srv *Server) *srvRoot {
24 r := &srvRoot{ 25 r := &srvRoot{
25 srv: srv, 26 srv: srv,
26 resources: newResources(), 27 resources: newResources(),
27 } 28 }
28 r.admin = &srvAdmin{ 29 r.admin = &srvAdmin{
29 root: r, 30 root: r,
30 } 31 }
31 r.client = &srvClient{ 32 r.client = &srvClient{
32 root: r, 33 root: r,
33 } 34 }
34 r.state = &srvState{ 35 r.state = &srvState{
35 root: r, 36 root: r,
36 } 37 }
37 r.machiner = &srvMachiner{
38 st: r.srv.state,
39 auth: r,
40 }
41 return r 38 return r
42 } 39 }
43 40
44 // Kill implements rpc.Killer. It cleans up any resources that need 41 // Kill implements rpc.Killer. It cleans up any resources that need
45 // cleaning up to ensure that all outstanding requests return. 42 // cleaning up to ensure that all outstanding requests return.
46 func (r *srvRoot) Kill() { 43 func (r *srvRoot) Kill() {
47 r.resources.stopAll() 44 r.resources.stopAll()
48 } 45 }
49 46
50 // Admin returns an object that provides API access 47 // Admin returns an object that provides API access
51 // to methods that can be called even when not 48 // to methods that can be called even when not
52 // authenticated. 49 // authenticated.
53 func (r *srvRoot) Admin(id string) (*srvAdmin, error) { 50 func (r *srvRoot) Admin(id string) (*srvAdmin, error) {
54 if id != "" { 51 if id != "" {
55 // Safeguard id for possible future use. 52 // Safeguard id for possible future use.
56 » » return nil, errBadId 53 » » return nil, common.ErrBadId
57 } 54 }
58 return r.admin, nil 55 return r.admin, nil
59 } 56 }
60 57
61 // requireAgent checks whether the current client is an agent and hence 58 // requireAgent checks whether the current client is an agent and hence
62 // may access the agent APIs. We filter out non-agents when calling one 59 // may access the agent APIs. We filter out non-agents when calling one
63 // of the accessor functions (Machine, Unit, etc) which avoids us making 60 // of the accessor functions (Machine, Unit, etc) which avoids us making
64 // the check in every single request method. 61 // the check in every single request method.
65 func (r *srvRoot) requireAgent() error { 62 func (r *srvRoot) requireAgent() error {
66 e := r.user.authenticator() 63 e := r.user.authenticator()
67 if e == nil { 64 if e == nil {
68 » » return errNotLoggedIn 65 » » return common.ErrNotLoggedIn
69 } 66 }
70 if !isAgent(e) { 67 if !isAgent(e) {
71 » » return errPerm 68 » » return common.ErrPerm
72 } 69 }
73 return nil 70 return nil
74 } 71 }
75 72
76 // requireClient returns an error unless the current 73 // requireClient returns an error unless the current
77 // client is a juju client user. 74 // client is a juju client user.
78 func (r *srvRoot) requireClient() error { 75 func (r *srvRoot) requireClient() error {
79 e := r.user.authenticator() 76 e := r.user.authenticator()
80 if e == nil { 77 if e == nil {
81 » » return errNotLoggedIn 78 » » return common.ErrNotLoggedIn
82 } 79 }
83 if isAgent(e) { 80 if isAgent(e) {
84 » » return errPerm 81 » » return common.ErrPerm
85 } 82 }
86 return nil 83 return nil
87 } 84 }
88 85
89 // Machiner returns an object that provides access to the Machiner API 86 // Machiner returns an object that provides access to the Machiner API
90 // facade. Version argument is reserved for future use and currently 87 // facade. The id argument is reserved for future use and currently
91 // needs to be empty. 88 // needs to be empty.
92 func (r *srvRoot) Machiner(version string) (*srvMachiner, error) { 89 func (r *srvRoot) Machiner(id string) (*machiner.Machiner, error) {
93 » if err := r.requireAgent(); err != nil { 90 » if id != "" {
94 » » return nil, err 91 » » // Safeguard id for possible future use.
92 » » return nil, common.ErrBadId
95 } 93 }
96 » if version != "" { 94 » return machiner.New(r.srv.state, r)
97 » » return nil, errBadVersion
98 » }
99 » return r.machiner, nil
100 } 95 }
101 96
102 // User returns an object that provides 97 // User returns an object that provides
103 // API access to methods on a state.User. 98 // API access to methods on a state.User.
104 func (r *srvRoot) User(name string) (*srvUser, error) { 99 func (r *srvRoot) User(name string) (*srvUser, error) {
105 // Any user is allowed to access their own user object. 100 // Any user is allowed to access their own user object.
106 // We check at this level rather than at the operation 101 // We check at this level rather than at the operation
107 // level to stop malicious probing for current user names. 102 // level to stop malicious probing for current user names.
108 // When we provide support for user administration, 103 // When we provide support for user administration,
109 // this will need to be changed to allow access to 104 // this will need to be changed to allow access to
110 // the administrator. 105 // the administrator.
111 e := r.user.authenticator() 106 e := r.user.authenticator()
112 if e == nil { 107 if e == nil {
113 » » return nil, errNotLoggedIn 108 » » return nil, common.ErrNotLoggedIn
114 } 109 }
115 if e.Tag() != name { 110 if e.Tag() != name {
116 » » return nil, errPerm 111 » » return nil, common.ErrPerm
117 } 112 }
118 u, err := r.srv.state.User(name) 113 u, err := r.srv.state.User(name)
119 if err != nil { 114 if err != nil {
120 return nil, err 115 return nil, err
121 } 116 }
122 return &srvUser{ 117 return &srvUser{
123 root: r, 118 root: r,
124 u: u, 119 u: u,
125 }, nil 120 }, nil
126 } 121 }
127 122
128 // EntityWatcher returns an object that provides 123 // EntityWatcher returns an object that provides
129 // API access to methods on a state.EntityWatcher. 124 // API access to methods on a state.EntityWatcher.
130 // Each client has its own current set of watchers, stored 125 // Each client has its own current set of watchers, stored
131 // in r.resources. 126 // in r.resources.
132 func (r *srvRoot) EntityWatcher(id string) (srvEntityWatcher, error) { 127 func (r *srvRoot) EntityWatcher(id string) (srvEntityWatcher, error) {
133 if err := r.requireAgent(); err != nil { 128 if err := r.requireAgent(); err != nil {
134 return srvEntityWatcher{}, err 129 return srvEntityWatcher{}, err
135 } 130 }
136 watcher := r.resources.get(id) 131 watcher := r.resources.get(id)
137 if watcher == nil { 132 if watcher == nil {
138 » » return srvEntityWatcher{}, errUnknownWatcher 133 » » return srvEntityWatcher{}, common.ErrUnknownWatcher
139 } 134 }
140 if _, ok := watcher.resource.(*state.EntityWatcher); !ok { 135 if _, ok := watcher.resource.(*state.EntityWatcher); !ok {
141 » » return srvEntityWatcher{}, errUnknownWatcher 136 » » return srvEntityWatcher{}, common.ErrUnknownWatcher
142 } 137 }
143 return srvEntityWatcher{watcher}, nil 138 return srvEntityWatcher{watcher}, nil
144 } 139 }
145 140
146 // LifecycleWatcher returns an object that provides 141 // LifecycleWatcher returns an object that provides
147 // API access to methods on a state.LifecycleWatcher. 142 // API access to methods on a state.LifecycleWatcher.
148 // Each client has its own current set of watchers, stored 143 // Each client has its own current set of watchers, stored
149 // in r.resources. 144 // in r.resources.
150 func (r *srvRoot) LifecycleWatcher(id string) (srvLifecycleWatcher, error) { 145 func (r *srvRoot) LifecycleWatcher(id string) (srvLifecycleWatcher, error) {
151 if err := r.requireAgent(); err != nil { 146 if err := r.requireAgent(); err != nil {
152 return srvLifecycleWatcher{}, err 147 return srvLifecycleWatcher{}, err
153 } 148 }
154 watcher := r.resources.get(id) 149 watcher := r.resources.get(id)
155 if watcher == nil { 150 if watcher == nil {
156 » » return srvLifecycleWatcher{}, errUnknownWatcher 151 » » return srvLifecycleWatcher{}, common.ErrUnknownWatcher
157 } 152 }
158 if _, ok := watcher.resource.(*state.LifecycleWatcher); !ok { 153 if _, ok := watcher.resource.(*state.LifecycleWatcher); !ok {
159 » » return srvLifecycleWatcher{}, errUnknownWatcher 154 » » return srvLifecycleWatcher{}, common.ErrUnknownWatcher
160 } 155 }
161 return srvLifecycleWatcher{watcher}, nil 156 return srvLifecycleWatcher{watcher}, nil
162 } 157 }
163 158
164 // EnvironConfigWatcher returns an object that provides 159 // EnvironConfigWatcher returns an object that provides
165 // API access to methods on a state.EnvironConfigWatcher. 160 // API access to methods on a state.EnvironConfigWatcher.
166 // Each client has its own current set of watchers, stored 161 // Each client has its own current set of watchers, stored
167 // in r.resources. 162 // in r.resources.
168 func (r *srvRoot) EnvironConfigWatcher(id string) (srvEnvironConfigWatcher, erro r) { 163 func (r *srvRoot) EnvironConfigWatcher(id string) (srvEnvironConfigWatcher, erro r) {
169 if err := r.requireAgent(); err != nil { 164 if err := r.requireAgent(); err != nil {
170 return srvEnvironConfigWatcher{}, err 165 return srvEnvironConfigWatcher{}, err
171 } 166 }
172 watcher := r.resources.get(id) 167 watcher := r.resources.get(id)
173 if watcher == nil { 168 if watcher == nil {
174 » » return srvEnvironConfigWatcher{}, errUnknownWatcher 169 » » return srvEnvironConfigWatcher{}, common.ErrUnknownWatcher
175 } 170 }
176 if _, ok := watcher.resource.(*state.EnvironConfigWatcher); !ok { 171 if _, ok := watcher.resource.(*state.EnvironConfigWatcher); !ok {
177 » » return srvEnvironConfigWatcher{}, errUnknownWatcher 172 » » return srvEnvironConfigWatcher{}, common.ErrUnknownWatcher
178 } 173 }
179 return srvEnvironConfigWatcher{watcher}, nil 174 return srvEnvironConfigWatcher{watcher}, nil
180 } 175 }
181 176
182 // AllWatcher returns an object that provides API access to methods on 177 // AllWatcher returns an object that provides API access to methods on
183 // a state/multiwatcher.Watcher, which watches any changes to the 178 // a state/multiwatcher.Watcher, which watches any changes to the
184 // state. Each client has its own current set of watchers, stored in 179 // state. Each client has its own current set of watchers, stored in
185 // r.resources. 180 // r.resources.
186 func (r *srvRoot) AllWatcher(id string) (srvClientAllWatcher, error) { 181 func (r *srvRoot) AllWatcher(id string) (srvClientAllWatcher, error) {
187 if err := r.requireClient(); err != nil { 182 if err := r.requireClient(); err != nil {
188 return srvClientAllWatcher{}, err 183 return srvClientAllWatcher{}, err
189 } 184 }
190 watcher := r.resources.get(id) 185 watcher := r.resources.get(id)
191 if watcher == nil { 186 if watcher == nil {
192 » » return srvClientAllWatcher{}, errUnknownWatcher 187 » » return srvClientAllWatcher{}, common.ErrUnknownWatcher
193 } 188 }
194 if _, ok := watcher.resource.(*multiwatcher.Watcher); !ok { 189 if _, ok := watcher.resource.(*multiwatcher.Watcher); !ok {
195 » » return srvClientAllWatcher{}, errUnknownWatcher 190 » » return srvClientAllWatcher{}, common.ErrUnknownWatcher
196 } 191 }
197 return srvClientAllWatcher{watcher}, nil 192 return srvClientAllWatcher{watcher}, nil
198 193
199 } 194 }
200 195
201 // State returns an object that provides API access to top-level state methods. 196 // State returns an object that provides API access to top-level state methods.
202 func (r *srvRoot) State(id string) (*srvState, error) { 197 func (r *srvRoot) State(id string) (*srvState, error) {
203 if err := r.requireAgent(); err != nil { 198 if err := r.requireAgent(); err != nil {
204 return nil, err 199 return nil, err
205 } 200 }
206 if id != "" { 201 if id != "" {
207 // Safeguard id for possible future use. 202 // Safeguard id for possible future use.
208 » » return nil, errBadId 203 » » return nil, common.ErrBadId
209 } 204 }
210 return r.state, nil 205 return r.state, nil
211 } 206 }
212 207
213 // Client returns an object that provides access 208 // Client returns an object that provides access
214 // to methods accessible to non-agent clients. 209 // to methods accessible to non-agent clients.
215 func (r *srvRoot) Client(id string) (*srvClient, error) { 210 func (r *srvRoot) Client(id string) (*srvClient, error) {
216 if err := r.requireClient(); err != nil { 211 if err := r.requireClient(); err != nil {
217 return nil, err 212 return nil, err
218 } 213 }
219 if id != "" { 214 if id != "" {
220 // Safeguard id for possible future use. 215 // Safeguard id for possible future use.
221 » » return nil, errBadId 216 » » return nil, common.ErrBadId
222 } 217 }
223 return r.client, nil 218 return r.client, nil
224 } 219 }
225 220
226 type Tagger interface { 221 // IsLoggedIn returns whether the user is currently logged in and
227 » Tag() string 222 // authenticated.
223 func (r *srvRoot) IsLoggedIn() bool {
224 » return r.user.authenticator() != nil
228 } 225 }
229 226
230 // Authorizer interface defines per-method authorization calls. 227 // AuthMachineAgent returns whether the current client is a machine agent.
231 type Authorizer interface { 228 func (r *srvRoot) AuthMachineAgent() bool {
232 » AuthOwner(entity Tagger) bool 229 » if !r.IsLoggedIn() {
233 » AuthEnvironManager() bool 230 » » return false
231 » }
232 » e := r.user.authenticator()
233 » if _, ok := e.(*state.Machine); !ok {
234 » » return false
235 » }
236 » return true
234 } 237 }
235 238
236 // AuthOwner returns whether the authenticated user's tag matches the 239 // AuthOwner returns whether the authenticated user's tag matches the
237 // given entity's tag. 240 // given entity's tag.
238 func (r *srvRoot) AuthOwner(entity Tagger) bool { 241 func (r *srvRoot) AuthOwner(entity common.Tagger) bool {
239 authUser := r.user.authenticator() 242 authUser := r.user.authenticator()
240 return authUser.Tag() == entity.Tag() 243 return authUser.Tag() == entity.Tag()
241 } 244 }
242 245
243 // AuthEnvironManager returns whether the authenticated user is a 246 // AuthEnvironManager returns whether the authenticated user is a
244 // machine with running the ManageEnviron job. 247 // machine with running the ManageEnviron job.
245 func (r *srvRoot) AuthEnvironManager() bool { 248 func (r *srvRoot) AuthEnvironManager() bool {
246 authUser := r.user.authenticator() 249 authUser := r.user.authenticator()
247 return isMachineWithJob(authUser, state.JobManageEnviron) 250 return isMachineWithJob(authUser, state.JobManageEnviron)
248 } 251 }
OLDNEW
« no previous file with comments | « state/apiserver/machiner/machiner_test.go ('k') | state/apiserver/user.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b