1package hns
2
3import (
4	"encoding/json"
5	"fmt"
6	"os"
7	"path"
8	"strings"
9)
10
11type namespaceRequest struct {
12	IsDefault bool `json:",omitempty"`
13}
14
15type namespaceEndpointRequest struct {
16	ID string `json:"Id"`
17}
18
19type NamespaceResource struct {
20	Type string
21	Data json.RawMessage
22}
23
24type namespaceResourceRequest struct {
25	Type string
26	Data interface{}
27}
28
29type Namespace struct {
30	ID            string
31	IsDefault     bool                `json:",omitempty"`
32	ResourceList  []NamespaceResource `json:",omitempty"`
33	CompartmentId uint32              `json:",omitempty"`
34}
35
36func issueNamespaceRequest(id *string, method, subpath string, request interface{}) (*Namespace, error) {
37	var err error
38	hnspath := "/namespaces/"
39	if id != nil {
40		hnspath = path.Join(hnspath, *id)
41	}
42	if subpath != "" {
43		hnspath = path.Join(hnspath, subpath)
44	}
45	var reqJSON []byte
46	if request != nil {
47		if reqJSON, err = json.Marshal(request); err != nil {
48			return nil, err
49		}
50	}
51	var ns Namespace
52	err = hnsCall(method, hnspath, string(reqJSON), &ns)
53	if err != nil {
54		if strings.Contains(err.Error(), "Element not found.") {
55			return nil, os.ErrNotExist
56		}
57		return nil, fmt.Errorf("%s %s: %s", method, hnspath, err)
58	}
59	return &ns, err
60}
61
62func CreateNamespace() (string, error) {
63	req := namespaceRequest{}
64	ns, err := issueNamespaceRequest(nil, "POST", "", &req)
65	if err != nil {
66		return "", err
67	}
68	return ns.ID, nil
69}
70
71func RemoveNamespace(id string) error {
72	_, err := issueNamespaceRequest(&id, "DELETE", "", nil)
73	return err
74}
75
76func GetNamespaceEndpoints(id string) ([]string, error) {
77	ns, err := issueNamespaceRequest(&id, "GET", "", nil)
78	if err != nil {
79		return nil, err
80	}
81	var endpoints []string
82	for _, rsrc := range ns.ResourceList {
83		if rsrc.Type == "Endpoint" {
84			var endpoint namespaceEndpointRequest
85			err = json.Unmarshal(rsrc.Data, &endpoint)
86			if err != nil {
87				return nil, fmt.Errorf("unmarshal endpoint: %s", err)
88			}
89			endpoints = append(endpoints, endpoint.ID)
90		}
91	}
92	return endpoints, nil
93}
94
95func AddNamespaceEndpoint(id string, endpointID string) error {
96	resource := namespaceResourceRequest{
97		Type: "Endpoint",
98		Data: namespaceEndpointRequest{endpointID},
99	}
100	_, err := issueNamespaceRequest(&id, "POST", "addresource", &resource)
101	return err
102}
103
104func RemoveNamespaceEndpoint(id string, endpointID string) error {
105	resource := namespaceResourceRequest{
106		Type: "Endpoint",
107		Data: namespaceEndpointRequest{endpointID},
108	}
109	_, err := issueNamespaceRequest(&id, "POST", "removeresource", &resource)
110	return err
111}
112