cord-776 create build / runtime containers for autmation uservices
Change-Id: I246973192adef56a250ffe93a5f65fff488840c1
diff --git a/automation/vendor/github.com/juju/gomaasapi/maasobject.go b/automation/vendor/github.com/juju/gomaasapi/maasobject.go
new file mode 100644
index 0000000..3978252
--- /dev/null
+++ b/automation/vendor/github.com/juju/gomaasapi/maasobject.go
@@ -0,0 +1,197 @@
+// Copyright 2012-2016 Canonical Ltd.
+// Licensed under the LGPLv3, see LICENCE file for details.
+
+package gomaasapi
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/url"
+)
+
+// MAASObject represents a MAAS object as returned by the MAAS API, such as a
+// Node or a Tag.
+// You can extract a MAASObject out of a JSONObject using
+// JSONObject.GetMAASObject. A MAAS API call will usually return either a
+// MAASObject or a list of MAASObjects. The list itself would be wrapped in
+// a JSONObject, so if an API call returns a list of objects "l," you first
+// obtain the array using l.GetArray(). Then, for each item "i" in the array,
+// obtain the matching MAASObject using i.GetMAASObject().
+type MAASObject struct {
+ values map[string]JSONObject
+ client Client
+ uri *url.URL
+}
+
+// newJSONMAASObject creates a new MAAS object. It will panic if the given map
+// does not contain a valid URL for the 'resource_uri' key.
+func newJSONMAASObject(jmap map[string]interface{}, client Client) MAASObject {
+ obj, err := maasify(client, jmap).GetMAASObject()
+ if err != nil {
+ panic(err)
+ }
+ return obj
+}
+
+// MarshalJSON tells the standard json package how to serialize a MAASObject.
+func (obj MAASObject) MarshalJSON() ([]byte, error) {
+ return json.MarshalIndent(obj.GetMap(), "", " ")
+}
+
+// With MarshalJSON, MAASObject implements json.Marshaler.
+var _ json.Marshaler = (*MAASObject)(nil)
+
+func marshalNode(node MAASObject) string {
+ res, _ := json.MarshalIndent(node, "", " ")
+ return string(res)
+
+}
+
+var noResourceURI = errors.New("not a MAAS object: no 'resource_uri' key")
+
+// extractURI obtains the "resource_uri" string from a JSONObject map.
+func extractURI(attrs map[string]JSONObject) (*url.URL, error) {
+ uriEntry, ok := attrs[resourceURI]
+ if !ok {
+ return nil, noResourceURI
+ }
+ uri, err := uriEntry.GetString()
+ if err != nil {
+ return nil, fmt.Errorf("invalid resource_uri: %v", uri)
+ }
+ resourceURL, err := url.Parse(uri)
+ if err != nil {
+ return nil, fmt.Errorf("resource_uri does not contain a valid URL: %v", uri)
+ }
+ return resourceURL, nil
+}
+
+// JSONObject getter for a MAAS object. From a decoding perspective, a
+// MAASObject is just like a map except it contains a key "resource_uri", and
+// it keeps track of the Client you got it from so that you can invoke API
+// methods directly on their MAAS objects.
+func (obj JSONObject) GetMAASObject() (MAASObject, error) {
+ attrs, err := obj.GetMap()
+ if err != nil {
+ return MAASObject{}, err
+ }
+ uri, err := extractURI(attrs)
+ if err != nil {
+ return MAASObject{}, err
+ }
+ return MAASObject{values: attrs, client: obj.client, uri: uri}, nil
+}
+
+// GetField extracts a string field from this MAAS object.
+func (obj MAASObject) GetField(name string) (string, error) {
+ return obj.values[name].GetString()
+}
+
+// URI is the resource URI for this MAAS object. It is an absolute path, but
+// without a network part.
+func (obj MAASObject) URI() *url.URL {
+ // Duplicate the URL.
+ uri, err := url.Parse(obj.uri.String())
+ if err != nil {
+ panic(err)
+ }
+ return uri
+}
+
+// URL returns a full absolute URL (including network part) for this MAAS
+// object on the API.
+func (obj MAASObject) URL() *url.URL {
+ return obj.client.GetURL(obj.URI())
+}
+
+// GetMap returns all of the object's attributes in the form of a map.
+func (obj MAASObject) GetMap() map[string]JSONObject {
+ return obj.values
+}
+
+// GetSubObject returns a new MAASObject representing the API resource found
+// at a given sub-path of the current object's resource URI.
+func (obj MAASObject) GetSubObject(name string) MAASObject {
+ uri := obj.URI()
+ newURL := url.URL{Path: name}
+ resUrl := uri.ResolveReference(&newURL)
+ resUrl.Path = EnsureTrailingSlash(resUrl.Path)
+ input := map[string]interface{}{resourceURI: resUrl.String()}
+ return newJSONMAASObject(input, obj.client)
+}
+
+var NotImplemented = errors.New("Not implemented")
+
+// Get retrieves a fresh copy of this MAAS object from the API.
+func (obj MAASObject) Get() (MAASObject, error) {
+ uri := obj.URI()
+ result, err := obj.client.Get(uri, "", url.Values{})
+ if err != nil {
+ return MAASObject{}, err
+ }
+ jsonObj, err := Parse(obj.client, result)
+ if err != nil {
+ return MAASObject{}, err
+ }
+ return jsonObj.GetMAASObject()
+}
+
+// Post overwrites this object's existing value on the API with those given
+// in "params." It returns the object's new value as received from the API.
+func (obj MAASObject) Post(params url.Values) (JSONObject, error) {
+ uri := obj.URI()
+ result, err := obj.client.Post(uri, "", params, nil)
+ if err != nil {
+ return JSONObject{}, err
+ }
+ return Parse(obj.client, result)
+}
+
+// Update modifies this object on the API, based on the values given in
+// "params." It returns the object's new value as received from the API.
+func (obj MAASObject) Update(params url.Values) (MAASObject, error) {
+ uri := obj.URI()
+ result, err := obj.client.Put(uri, params)
+ if err != nil {
+ return MAASObject{}, err
+ }
+ jsonObj, err := Parse(obj.client, result)
+ if err != nil {
+ return MAASObject{}, err
+ }
+ return jsonObj.GetMAASObject()
+}
+
+// Delete removes this object on the API.
+func (obj MAASObject) Delete() error {
+ uri := obj.URI()
+ return obj.client.Delete(uri)
+}
+
+// CallGet invokes an idempotent API method on this object.
+func (obj MAASObject) CallGet(operation string, params url.Values) (JSONObject, error) {
+ uri := obj.URI()
+ result, err := obj.client.Get(uri, operation, params)
+ if err != nil {
+ return JSONObject{}, err
+ }
+ return Parse(obj.client, result)
+}
+
+// CallPost invokes a non-idempotent API method on this object.
+func (obj MAASObject) CallPost(operation string, params url.Values) (JSONObject, error) {
+ return obj.CallPostFiles(operation, params, nil)
+}
+
+// CallPostFiles invokes a non-idempotent API method on this object. It is
+// similar to CallPost but has an extra parameter, 'files', which should
+// contain the files that will be uploaded to the API.
+func (obj MAASObject) CallPostFiles(operation string, params url.Values, files map[string][]byte) (JSONObject, error) {
+ uri := obj.URI()
+ result, err := obj.client.Post(uri, operation, params, files)
+ if err != nil {
+ return JSONObject{}, err
+ }
+ return Parse(obj.client, result)
+}