/
namespace.go
120 lines (110 loc) · 3.68 KB
/
namespace.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright 2015 Diffeo, Inc.
// This software is released under an MIT/X11 open source license.
package restserver
import (
"github.com/diffeo/go-coordinate/coordinate"
"github.com/diffeo/go-coordinate/restdata"
"github.com/gorilla/mux"
)
func (api *restAPI) fillNamespaceShort(namespace coordinate.Namespace, summary *restdata.NamespaceShort) error {
summary.Name = namespace.Name()
return buildURLs(api.Router, "namespace", summary.Name).
URL(&summary.URL, "namespace").
Error
}
func (api *restAPI) fillNamespace(namespace coordinate.Namespace, result *restdata.Namespace) error {
err := api.fillNamespaceShort(namespace, &result.NamespaceShort)
if err == nil {
err = buildURLs(api.Router, "namespace", result.Name).
URL(&result.SummaryURL, "namespaceSummary").
URL(&result.WorkSpecsURL, "workSpecs").
Template(&result.WorkSpecURL, "workSpec", "spec").
URL(&result.WorkersURL, "workers").
Template(&result.WorkerURL, "worker", "worker").
Error
}
return err
}
// NamespaceList gets a list of all namespaces known in the system.
func (api *restAPI) NamespaceList(ctx *context) (interface{}, error) {
namespaces, err := api.Coordinate.Namespaces()
if err != nil {
return nil, err
}
result := restdata.NamespaceList{}
for _, ns := range namespaces {
summary := restdata.NamespaceShort{}
err = api.fillNamespaceShort(ns, &summary)
if err != nil {
return nil, err
}
result.Namespaces = append(result.Namespaces, summary)
}
return result, nil
}
// NamespacePost creates a new namespace, or retrieves a pointer to
// an existing one.
func (api *restAPI) NamespacePost(ctx *context, in interface{}) (interface{}, error) {
req, valid := in.(restdata.NamespaceShort)
if !valid {
return nil, errUnmarshal
}
ns, err := api.Coordinate.Namespace(req.Name)
if err != nil {
return nil, err
}
// We will return "created", where the content is the full
// namespace data
result := restdata.Namespace{}
err = api.fillNamespace(ns, &result)
if err != nil {
return nil, err
}
return responseCreated{
Location: result.URL,
Body: result,
}, nil
}
// NamespaceGet retrieves an existing namespace, or creates a new one.
func (api *restAPI) NamespaceGet(ctx *context) (interface{}, error) {
// If we've gotten here, we're just returning ctx.Namespace
result := restdata.Namespace{}
err := api.fillNamespace(ctx.Namespace, &result)
if err != nil {
return nil, err
}
return result, nil
}
// NamespaceDelete destroys an existing namespace.
func (api *restAPI) NamespaceDelete(ctx *context) (interface{}, error) {
err := ctx.Namespace.Destroy()
return nil, err
}
// NamespaceSummaryGet produces a summary for a namespace.
func (api *restAPI) NamespaceSummaryGet(ctx *context) (interface{}, error) {
return ctx.Namespace.Summarize()
}
// PopulateNamespace adds namespace-specific routes to a router.
// r should be rooted at the root of the Coordinate URL tree, e.g. "/".
func (api *restAPI) PopulateNamespace(r *mux.Router) {
r.Path("/namespace").Name("namespaces").Handler(&resourceHandler{
Representation: restdata.NamespaceShort{},
Context: api.Context,
Get: api.NamespaceList,
Post: api.NamespacePost,
})
r.Path("/namespace/{namespace}").Name("namespace").Handler(&resourceHandler{
Representation: restdata.Namespace{},
Context: api.Context,
Get: api.NamespaceGet,
Delete: api.NamespaceDelete,
})
r.Path("/namespace/{namespace}/summary").Name("namespaceSummary").Handler(&resourceHandler{
Representation: coordinate.Summary{},
Context: api.Context,
Get: api.NamespaceSummaryGet,
})
sr := r.PathPrefix("/namespace/{namespace}").Subrouter()
api.PopulateWorkSpec(sr)
api.PopulateWorker(sr)
}