~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/joyent/gosdc/localservices/cloudapi/service_http.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
//
 
2
// gosdc - Go library to interact with the Joyent CloudAPI
 
3
//
 
4
// CloudAPI double testing service - HTTP API implementation
 
5
//
 
6
// Copyright (c) 2013 Joyent Inc.
 
7
//
 
8
// Written by Daniele Stroppa <daniele.stroppa@joyent.com>
 
9
//
 
10
 
 
11
package cloudapi
 
12
 
 
13
import (
 
14
        "encoding/json"
 
15
        "fmt"
 
16
        "io/ioutil"
 
17
        "net/http"
 
18
        "strconv"
 
19
        "strings"
 
20
 
 
21
        "github.com/joyent/gosdc/cloudapi"
 
22
)
 
23
 
 
24
// ErrorResponse defines a single HTTP error response.
 
25
type ErrorResponse struct {
 
26
        Code        int
 
27
        Body        string
 
28
        contentType string
 
29
        errorText   string
 
30
        headers     map[string]string
 
31
        cloudapi    *CloudAPI
 
32
}
 
33
 
 
34
var (
 
35
        ErrNotAllowed = &ErrorResponse{
 
36
                http.StatusMethodNotAllowed,
 
37
                "Method is not allowed",
 
38
                "text/plain; charset=UTF-8",
 
39
                "MethodNotAllowedError",
 
40
                nil,
 
41
                nil,
 
42
        }
 
43
        ErrNotFound = &ErrorResponse{
 
44
                http.StatusNotFound,
 
45
                "Resource Not Found",
 
46
                "text/plain; charset=UTF-8",
 
47
                "NotFoundError",
 
48
                nil,
 
49
                nil,
 
50
        }
 
51
        ErrBadRequest = &ErrorResponse{
 
52
                http.StatusBadRequest,
 
53
                "Malformed request url",
 
54
                "text/plain; charset=UTF-8",
 
55
                "BadRequestError",
 
56
                nil,
 
57
                nil,
 
58
        }
 
59
)
 
60
 
 
61
func (e *ErrorResponse) Error() string {
 
62
        return e.errorText
 
63
}
 
64
 
 
65
func (e *ErrorResponse) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
66
        if e.contentType != "" {
 
67
                w.Header().Set("Content-Type", e.contentType)
 
68
        }
 
69
        body := e.Body
 
70
        if e.headers != nil {
 
71
                for h, v := range e.headers {
 
72
                        w.Header().Set(h, v)
 
73
                }
 
74
        }
 
75
        // workaround for https://code.google.com/p/go/issues/detail?id=4454
 
76
        w.Header().Set("Content-Length", strconv.Itoa(len(body)))
 
77
        if e.Code != 0 {
 
78
                w.WriteHeader(e.Code)
 
79
        }
 
80
        if len(body) > 0 {
 
81
                w.Write([]byte(body))
 
82
        }
 
83
}
 
84
 
 
85
type cloudapiHandler struct {
 
86
        cloudapi *CloudAPI
 
87
        method   func(m *CloudAPI, w http.ResponseWriter, r *http.Request) error
 
88
}
 
89
 
 
90
func (h *cloudapiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
91
        path := r.URL.Path
 
92
        // handle trailing slash in the path
 
93
        if strings.HasSuffix(path, "/") && path != "/" {
 
94
                ErrNotFound.ServeHTTP(w, r)
 
95
                return
 
96
        }
 
97
        err := h.method(h.cloudapi, w, r)
 
98
        if err == nil {
 
99
                return
 
100
        }
 
101
        var resp http.Handler
 
102
        resp, _ = err.(http.Handler)
 
103
        if resp == nil {
 
104
                resp = &ErrorResponse{
 
105
                        http.StatusInternalServerError,
 
106
                        `{"internalServerError":{"message":"Unkown Error",code:500}}`,
 
107
                        "application/json",
 
108
                        err.Error(),
 
109
                        nil,
 
110
                        h.cloudapi,
 
111
                }
 
112
        }
 
113
        resp.ServeHTTP(w, r)
 
114
}
 
115
 
 
116
func writeResponse(w http.ResponseWriter, code int, body []byte) {
 
117
        // workaround for https://code.google.com/p/go/issues/detail?id=4454
 
118
        w.Header().Set("Content-Length", strconv.Itoa(len(body)))
 
119
        w.WriteHeader(code)
 
120
        w.Write(body)
 
121
}
 
122
 
 
123
// sendJSON sends the specified response serialized as JSON.
 
124
func sendJSON(code int, resp interface{}, w http.ResponseWriter, r *http.Request) error {
 
125
        data, err := json.Marshal(resp)
 
126
        if err != nil {
 
127
                return err
 
128
        }
 
129
        writeResponse(w, code, data)
 
130
        return nil
 
131
}
 
132
 
 
133
func processFilter(rawQuery string) map[string]string {
 
134
        var filters map[string]string
 
135
        if rawQuery != "" {
 
136
                filters = make(map[string]string)
 
137
                for _, filter := range strings.Split(rawQuery, "&") {
 
138
                        filters[filter[:strings.Index(filter, "=")]] = filter[strings.Index(filter, "=")+1:]
 
139
                }
 
140
        }
 
141
 
 
142
        return filters
 
143
}
 
144
 
 
145
func (cloudapi *CloudAPI) handler(method func(m *CloudAPI, w http.ResponseWriter, r *http.Request) error) http.Handler {
 
146
        return &cloudapiHandler{cloudapi, method}
 
147
}
 
148
 
 
149
// handleKeys handles the keys HTTP API.
 
150
func (c *CloudAPI) handleKeys(w http.ResponseWriter, r *http.Request) error {
 
151
        prefix := fmt.Sprintf("/%s/keys/", c.ServiceInstance.UserAccount)
 
152
        keyName := strings.TrimPrefix(r.URL.Path, prefix)
 
153
        switch r.Method {
 
154
        case "GET":
 
155
                if strings.HasSuffix(r.URL.Path, "keys") {
 
156
                        // ListKeys
 
157
                        keys, err := c.ListKeys()
 
158
                        if err != nil {
 
159
                                return err
 
160
                        }
 
161
                        if keys == nil {
 
162
                                keys = []cloudapi.Key{}
 
163
                        }
 
164
                        resp := keys
 
165
                        return sendJSON(http.StatusOK, resp, w, r)
 
166
                } else {
 
167
                        // GetKey
 
168
                        key, err := c.GetKey(keyName)
 
169
                        if err != nil {
 
170
                                return err
 
171
                        }
 
172
                        if key == nil {
 
173
                                key = &cloudapi.Key{}
 
174
                        }
 
175
                        resp := key
 
176
                        return sendJSON(http.StatusOK, resp, w, r)
 
177
                }
 
178
        case "POST":
 
179
                if strings.HasSuffix(r.URL.Path, "keys") {
 
180
                        // CreateKey
 
181
                        var (
 
182
                                name string
 
183
                                key  string
 
184
                        )
 
185
                        opts := &cloudapi.CreateKeyOpts{}
 
186
                        body, errB := ioutil.ReadAll(r.Body)
 
187
                        if errB != nil {
 
188
                                return errB
 
189
                        }
 
190
                        if len(body) > 0 {
 
191
                                if errJ := json.Unmarshal(body, opts); errJ != nil {
 
192
                                        return errJ
 
193
                                }
 
194
                                name = opts.Name
 
195
                                key = opts.Key
 
196
                        }
 
197
                        k, err := c.CreateKey(name, key)
 
198
                        if err != nil {
 
199
                                return err
 
200
                        }
 
201
                        if k == nil {
 
202
                                k = &cloudapi.Key{}
 
203
                        }
 
204
                        resp := k
 
205
                        return sendJSON(http.StatusCreated, resp, w, r)
 
206
                } else {
 
207
                        return ErrNotAllowed
 
208
                }
 
209
        case "PUT":
 
210
                return ErrNotAllowed
 
211
        case "DELETE":
 
212
                if strings.HasSuffix(r.URL.Path, "keys") {
 
213
                        return ErrNotAllowed
 
214
                } else {
 
215
                        // DeleteKey
 
216
                        err := c.DeleteKey(keyName)
 
217
                        if err != nil {
 
218
                                return err
 
219
                        }
 
220
                        return sendJSON(http.StatusNoContent, nil, w, r)
 
221
                }
 
222
        }
 
223
        return fmt.Errorf("unknown request method %q for %s", r.Method, r.URL.Path)
 
224
}
 
225
 
 
226
// handleImages handles the images HTTP API.
 
227
func (c *CloudAPI) handleImages(w http.ResponseWriter, r *http.Request) error {
 
228
        prefix := fmt.Sprintf("/%s/images/", c.ServiceInstance.UserAccount)
 
229
        imageId := strings.TrimPrefix(r.URL.Path, prefix)
 
230
        switch r.Method {
 
231
        case "GET":
 
232
                if strings.HasSuffix(r.URL.Path, "images") {
 
233
                        // ListImages
 
234
                        images, err := c.ListImages(processFilter(r.URL.RawQuery))
 
235
                        if err != nil {
 
236
                                return err
 
237
                        }
 
238
                        if images == nil {
 
239
                                images = []cloudapi.Image{}
 
240
                        }
 
241
                        resp := images
 
242
                        return sendJSON(http.StatusOK, resp, w, r)
 
243
                } else {
 
244
                        // GetImage
 
245
                        image, err := c.GetImage(imageId)
 
246
                        if err != nil {
 
247
                                return err
 
248
                        }
 
249
                        if image == nil {
 
250
                                image = &cloudapi.Image{}
 
251
                        }
 
252
                        resp := image
 
253
                        return sendJSON(http.StatusOK, resp, w, r)
 
254
                }
 
255
        case "POST":
 
256
                if strings.HasSuffix(r.URL.Path, "images") {
 
257
                        // CreateImageFromMachine
 
258
                        return ErrNotFound
 
259
                } else {
 
260
                        return ErrNotAllowed
 
261
                }
 
262
        case "PUT":
 
263
                return ErrNotAllowed
 
264
        case "DELETE":
 
265
                /*if strings.HasSuffix(r.URL.Path, "images") {
 
266
                        return ErrNotAllowed
 
267
                } else {
 
268
                        err := c.DeleteImage(imageId)
 
269
                        if err != nil {
 
270
                                return err
 
271
                        }
 
272
                        return sendJSON(http.StatusNoContent, nil, w, r)
 
273
                }*/
 
274
                return ErrNotAllowed
 
275
        }
 
276
        return fmt.Errorf("unknown request method %q for %s", r.Method, r.URL.Path)
 
277
}
 
278
 
 
279
// handlePackages handles the packages HTTP API.
 
280
func (c *CloudAPI) handlePackages(w http.ResponseWriter, r *http.Request) error {
 
281
        prefix := fmt.Sprintf("/%s/packages/", c.ServiceInstance.UserAccount)
 
282
        pkgName := strings.TrimPrefix(r.URL.Path, prefix)
 
283
        switch r.Method {
 
284
        case "GET":
 
285
                if strings.HasSuffix(r.URL.Path, "packages") {
 
286
                        // ListPackages
 
287
                        pkgs, err := c.ListPackages(processFilter(r.URL.RawQuery))
 
288
                        if err != nil {
 
289
                                return err
 
290
                        }
 
291
                        if pkgs == nil {
 
292
                                pkgs = []cloudapi.Package{}
 
293
                        }
 
294
                        resp := pkgs
 
295
                        return sendJSON(http.StatusOK, resp, w, r)
 
296
                } else {
 
297
                        // GetPackage
 
298
                        pkg, err := c.GetPackage(pkgName)
 
299
                        if err != nil {
 
300
                                return err
 
301
                        }
 
302
                        if pkg == nil {
 
303
                                pkg = &cloudapi.Package{}
 
304
                        }
 
305
                        resp := pkg
 
306
                        return sendJSON(http.StatusOK, resp, w, r)
 
307
                }
 
308
        case "POST":
 
309
                return ErrNotAllowed
 
310
        case "PUT":
 
311
                return ErrNotAllowed
 
312
        case "DELETE":
 
313
                return ErrNotAllowed
 
314
        }
 
315
        return fmt.Errorf("unknown request method %q for %s", r.Method, r.URL.Path)
 
316
}
 
317
 
 
318
// handleMachines handles the machine HTTP API.
 
319
func (c *CloudAPI) handleMachines(w http.ResponseWriter, r *http.Request) error {
 
320
        prefix := fmt.Sprintf("/%s/machines/", c.ServiceInstance.UserAccount)
 
321
        machineId := strings.TrimPrefix(r.URL.Path, prefix)
 
322
        switch r.Method {
 
323
        case "GET":
 
324
                if strings.HasSuffix(r.URL.Path, "machines") {
 
325
                        // ListMachines
 
326
                        machines, err := c.ListMachines(processFilter(r.URL.RawQuery))
 
327
                        if err != nil {
 
328
                                return err
 
329
                        }
 
330
                        if machines == nil {
 
331
                                machines = []*cloudapi.Machine{}
 
332
                        }
 
333
                        resp := machines
 
334
                        return sendJSON(http.StatusOK, resp, w, r)
 
335
                } else if strings.HasSuffix(r.URL.Path, "fwrules") {
 
336
                        // ListMachineFirewallRules
 
337
                        machineId = strings.TrimSuffix(machineId, "/fwrules")
 
338
                        fwRules, err := c.ListMachineFirewallRules(machineId)
 
339
                        if err != nil {
 
340
                                return err
 
341
                        }
 
342
                        if fwRules == nil {
 
343
                                fwRules = []*cloudapi.FirewallRule{}
 
344
                        }
 
345
                        resp := fwRules
 
346
                        return sendJSON(http.StatusOK, resp, w, r)
 
347
                } else {
 
348
                        // GetMachine
 
349
                        machine, err := c.GetMachine(machineId)
 
350
                        if err != nil {
 
351
                                return err
 
352
                        }
 
353
                        if machine == nil {
 
354
                                machine = &cloudapi.Machine{}
 
355
                        }
 
356
                        resp := machine
 
357
                        return sendJSON(http.StatusOK, resp, w, r)
 
358
                }
 
359
        case "HEAD":
 
360
                if strings.HasSuffix(r.URL.Path, "machines") {
 
361
                        // CountMachines
 
362
                        count, err := c.CountMachines()
 
363
                        if err != nil {
 
364
                                return err
 
365
                        }
 
366
                        resp := count
 
367
                        return sendJSON(http.StatusOK, resp, w, r)
 
368
                } else {
 
369
                        return ErrNotAllowed
 
370
                }
 
371
        case "POST":
 
372
                if strings.HasSuffix(r.URL.Path, "machines") {
 
373
                        // CreateMachine
 
374
                        var (
 
375
                                name     string
 
376
                                pkg      string
 
377
                                image    string
 
378
                                metadata map[string]string
 
379
                                tags     map[string]string
 
380
                        )
 
381
                        opts := &cloudapi.CreateMachineOpts{}
 
382
                        body, errB := ioutil.ReadAll(r.Body)
 
383
                        if errB != nil {
 
384
                                return errB
 
385
                        }
 
386
                        if len(body) > 0 {
 
387
                                if errJ := json.Unmarshal(body, opts); errJ != nil {
 
388
                                        return errJ
 
389
                                }
 
390
                                name = opts.Name
 
391
                                pkg = opts.Package
 
392
                                image = opts.Image
 
393
                                metadata = opts.Metadata
 
394
                                tags = opts.Tags
 
395
                        }
 
396
                        machine, err := c.CreateMachine(name, pkg, image, metadata, tags)
 
397
                        if err != nil {
 
398
                                return err
 
399
                        }
 
400
                        if machine == nil {
 
401
                                machine = &cloudapi.Machine{}
 
402
                        }
 
403
                        resp := machine
 
404
                        return sendJSON(http.StatusCreated, resp, w, r)
 
405
                } else if r.URL.Query().Get("action") == "stop" {
 
406
                        //StopMachine
 
407
                        err := c.StopMachine(machineId)
 
408
                        if err != nil {
 
409
                                return err
 
410
                        }
 
411
                        return sendJSON(http.StatusAccepted, nil, w, r)
 
412
                } else if r.URL.Query().Get("action") == "start" {
 
413
                        //StartMachine
 
414
                        err := c.StartMachine(machineId)
 
415
                        if err != nil {
 
416
                                return err
 
417
                        }
 
418
                        return sendJSON(http.StatusAccepted, nil, w, r)
 
419
                } else if r.URL.Query().Get("action") == "reboot" {
 
420
                        //RebootMachine
 
421
                        err := c.RebootMachine(machineId)
 
422
                        if err != nil {
 
423
                                return err
 
424
                        }
 
425
                        return sendJSON(http.StatusAccepted, nil, w, r)
 
426
                } else if r.URL.Query().Get("action") == "resize" {
 
427
                        //ResizeMachine
 
428
                        err := c.ResizeMachine(machineId, r.URL.Query().Get("package"))
 
429
                        if err != nil {
 
430
                                return err
 
431
                        }
 
432
                        return sendJSON(http.StatusAccepted, nil, w, r)
 
433
                } else if r.URL.Query().Get("action") == "rename" {
 
434
                        //RenameMachine
 
435
                        err := c.RenameMachine(machineId, r.URL.Query().Get("name"))
 
436
                        if err != nil {
 
437
                                return err
 
438
                        }
 
439
                        return sendJSON(http.StatusAccepted, nil, w, r)
 
440
                } else if r.URL.Query().Get("action") == "enable_firewall" {
 
441
                        //EnableFirewallMachine
 
442
                        err := c.EnableFirewallMachine(machineId)
 
443
                        if err != nil {
 
444
                                return err
 
445
                        }
 
446
                        return sendJSON(http.StatusAccepted, nil, w, r)
 
447
                } else if r.URL.Query().Get("action") == "disable_firewall" {
 
448
                        //DisableFirewallMachine
 
449
                        err := c.DisableFirewallMachine(machineId)
 
450
                        if err != nil {
 
451
                                return err
 
452
                        }
 
453
                        return sendJSON(http.StatusAccepted, nil, w, r)
 
454
                } else {
 
455
                        return ErrNotAllowed
 
456
                }
 
457
        case "PUT":
 
458
                return ErrNotAllowed
 
459
        case "DELETE":
 
460
                if strings.HasSuffix(r.URL.Path, "machines") {
 
461
                        return ErrNotAllowed
 
462
                } else {
 
463
                        // DeleteMachine
 
464
                        err := c.DeleteMachine(machineId)
 
465
                        if err != nil {
 
466
                                return err
 
467
                        }
 
468
                        return sendJSON(http.StatusNoContent, nil, w, r)
 
469
                }
 
470
        }
 
471
        return fmt.Errorf("unknown request method %q for %s", r.Method, r.URL.Path)
 
472
}
 
473
 
 
474
// handleFwRules handles the firewall rules HTTP API.
 
475
func (c *CloudAPI) handleFwRules(w http.ResponseWriter, r *http.Request) error {
 
476
        prefix := fmt.Sprintf("/%s/fwrules/", c.ServiceInstance.UserAccount)
 
477
        fwRuleId := strings.TrimPrefix(r.URL.Path, prefix)
 
478
        switch r.Method {
 
479
        case "GET":
 
480
                if strings.HasSuffix(r.URL.Path, "fwrules") {
 
481
                        // ListFirewallRules
 
482
                        fwRules, err := c.ListFirewallRules()
 
483
                        if err != nil {
 
484
                                return err
 
485
                        }
 
486
                        if fwRules == nil {
 
487
                                fwRules = []*cloudapi.FirewallRule{}
 
488
                        }
 
489
                        resp := fwRules
 
490
                        return sendJSON(http.StatusOK, resp, w, r)
 
491
                } else {
 
492
                        // GetFirewallRule
 
493
                        fwRule, err := c.GetFirewallRule(fwRuleId)
 
494
                        if err != nil {
 
495
                                return err
 
496
                        }
 
497
                        if fwRule == nil {
 
498
                                fwRule = &cloudapi.FirewallRule{}
 
499
                        }
 
500
                        resp := fwRule
 
501
                        return sendJSON(http.StatusOK, resp, w, r)
 
502
                }
 
503
        case "POST":
 
504
                if strings.HasSuffix(r.URL.Path, "fwrules") {
 
505
                        // CreateFirewallRule
 
506
                        var (
 
507
                                rule    string
 
508
                                enabled bool
 
509
                        )
 
510
                        opts := &cloudapi.CreateFwRuleOpts{}
 
511
                        body, errB := ioutil.ReadAll(r.Body)
 
512
                        if errB != nil {
 
513
                                return errB
 
514
                        }
 
515
                        if len(body) > 0 {
 
516
                                if errJ := json.Unmarshal(body, opts); errJ != nil {
 
517
                                        return errJ
 
518
                                }
 
519
                                rule = opts.Rule
 
520
                                enabled = opts.Enabled
 
521
                        }
 
522
                        fwRule, err := c.CreateFirewallRule(rule, enabled)
 
523
                        if err != nil {
 
524
                                return err
 
525
                        }
 
526
                        if fwRule == nil {
 
527
                                fwRule = &cloudapi.FirewallRule{}
 
528
                        }
 
529
                        resp := fwRule
 
530
                        return sendJSON(http.StatusCreated, resp, w, r)
 
531
                } else if strings.HasSuffix(r.URL.Path, "enable") {
 
532
                        // EnableFirewallRule
 
533
                        fwRuleId = strings.TrimSuffix(fwRuleId, "/enable")
 
534
                        fwRule, err := c.EnableFirewallRule(fwRuleId)
 
535
                        if err != nil {
 
536
                                return err
 
537
                        }
 
538
                        if fwRule == nil {
 
539
                                fwRule = &cloudapi.FirewallRule{}
 
540
                        }
 
541
                        resp := fwRule
 
542
                        return sendJSON(http.StatusOK, resp, w, r)
 
543
                } else if strings.HasSuffix(r.URL.Path, "disable") {
 
544
                        // DisableFirewallRule
 
545
                        fwRuleId = strings.TrimSuffix(fwRuleId, "/disable")
 
546
                        fwRule, err := c.DisableFirewallRule(fwRuleId)
 
547
                        if err != nil {
 
548
                                return err
 
549
                        }
 
550
                        if fwRule == nil {
 
551
                                fwRule = &cloudapi.FirewallRule{}
 
552
                        }
 
553
                        resp := fwRule
 
554
                        return sendJSON(http.StatusOK, resp, w, r)
 
555
                } else {
 
556
                        // UpdateFirewallRule
 
557
                        var (
 
558
                                rule    string
 
559
                                enabled bool
 
560
                        )
 
561
                        opts := &cloudapi.CreateFwRuleOpts{}
 
562
                        body, errB := ioutil.ReadAll(r.Body)
 
563
                        if errB != nil {
 
564
                                return errB
 
565
                        }
 
566
                        if len(body) > 0 {
 
567
                                if errJ := json.Unmarshal(body, opts); errJ != nil {
 
568
                                        return errJ
 
569
                                }
 
570
                                rule = opts.Rule
 
571
                                enabled = opts.Enabled
 
572
                        }
 
573
                        fwRule, err := c.UpdateFirewallRule(fwRuleId, rule, enabled)
 
574
                        if err != nil {
 
575
                                return err
 
576
                        }
 
577
                        if fwRule == nil {
 
578
                                fwRule = &cloudapi.FirewallRule{}
 
579
                        }
 
580
                        resp := fwRule
 
581
                        return sendJSON(http.StatusOK, resp, w, r)
 
582
                }
 
583
        case "PUT":
 
584
                return ErrNotAllowed
 
585
        case "DELETE":
 
586
                if strings.HasSuffix(r.URL.Path, "fwrules") {
 
587
                        return ErrNotAllowed
 
588
                } else {
 
589
                        // DeleteFirewallRule
 
590
                        err := c.DeleteFirewallRule(fwRuleId)
 
591
                        if err != nil {
 
592
                                return err
 
593
                        }
 
594
                        return sendJSON(http.StatusNoContent, nil, w, r)
 
595
                }
 
596
        }
 
597
        return fmt.Errorf("unknown request method %q for %s", r.Method, r.URL.Path)
 
598
}
 
599
 
 
600
// handleNetworks handles the networks HTTP API.
 
601
func (c *CloudAPI) handleNetworks(w http.ResponseWriter, r *http.Request) error {
 
602
        prefix := fmt.Sprintf("/%s/networks/", c.ServiceInstance.UserAccount)
 
603
        networkId := strings.TrimPrefix(r.URL.Path, prefix)
 
604
        switch r.Method {
 
605
        case "GET":
 
606
                if strings.HasSuffix(r.URL.Path, "networks") {
 
607
                        // ListNetworks
 
608
                        networks, err := c.ListNetworks()
 
609
                        if err != nil {
 
610
                                return err
 
611
                        }
 
612
                        if networks == nil {
 
613
                                networks = []cloudapi.Network{}
 
614
                        }
 
615
                        resp := networks
 
616
                        return sendJSON(http.StatusOK, resp, w, r)
 
617
                } else {
 
618
                        // GetNetwork
 
619
                        network, err := c.GetNetwork(networkId)
 
620
                        if err != nil {
 
621
                                return err
 
622
                        }
 
623
                        if network == nil {
 
624
                                network = &cloudapi.Network{}
 
625
                        }
 
626
                        resp := network
 
627
                        return sendJSON(http.StatusOK, resp, w, r)
 
628
                }
 
629
        case "POST":
 
630
                return ErrNotAllowed
 
631
        case "PUT":
 
632
                return ErrNotAllowed
 
633
        case "DELETE":
 
634
                return ErrNotAllowed
 
635
        }
 
636
        return fmt.Errorf("unknown request method %q for %s", r.Method, r.URL.Path)
 
637
}
 
638
 
 
639
// setupHTTP attaches all the needed handlers to provide the HTTP API.
 
640
func (c *CloudAPI) SetupHTTP(mux *http.ServeMux) {
 
641
        handlers := map[string]http.Handler{
 
642
                "/":               ErrNotFound,
 
643
                "/$user/":         ErrBadRequest,
 
644
                "/$user/keys":     c.handler((*CloudAPI).handleKeys),
 
645
                "/$user/images":   c.handler((*CloudAPI).handleImages),
 
646
                "/$user/packages": c.handler((*CloudAPI).handlePackages),
 
647
                "/$user/machines": c.handler((*CloudAPI).handleMachines),
 
648
                //"/$user/datacenters":         c.handler((*CloudAPI).handleDatacenters),
 
649
                "/$user/fwrules":  c.handler((*CloudAPI).handleFwRules),
 
650
                "/$user/networks": c.handler((*CloudAPI).handleNetworks),
 
651
        }
 
652
        for path, h := range handlers {
 
653
                path = strings.Replace(path, "$user", c.ServiceInstance.UserAccount, 1)
 
654
                if !strings.HasSuffix(path, "/") {
 
655
                        mux.Handle(path+"/", h)
 
656
                }
 
657
                mux.Handle(path, h)
 
658
        }
 
659
}