func (c *Client) UuidByName(typename string, fqn string) (string, error) {
	url := fmt.Sprintf("%s://%s:%d/fqname-to-id", c.scheme, c.server, c.port)
	request := struct {
		Typename string   `json:"type"`
		Fq_name  []string `json:"fq_name"`
	}{
		typename,
		strings.Split(fqn, ":"),
	}
	data, err := json.Marshal(request)
	if err != nil {
		return "", err
	}
	resp, err := c.httpPost(url, "application/json", bytes.NewReader(data))
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("%s: %s", resp.Status, body)
	}
	m := struct {
		Uuid string
	}{}
	err = json.Unmarshal(body, &m)
	if err != nil {
		return "", err
	}
	return m.Uuid, nil
}
UuidByName returns the UUID of an object as identified by its fully qualified name.
package contrail
import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"reflect"
	"strings"
	"unicode"
)
type TypeMap map[string]reflect.Type
type objectInterface interface {
	GetField(IObject, string) error
	UpdateReference(*ReferenceUpdateMsg) error
}
type Authenticator interface {
	AddAuthentication(*http.Request) error
}
type NopAuthenticator struct {
}
func (*NopAuthenticator) AddAuthentication(*http.Request) error {
	return nil
}
type Encryptor interface {
	AddEncryption(caFile string, keyFile string, certFile string, insecure bool) error
}
type NopEncryptor struct {
}
func (*NopEncryptor) AddEncryption(caFile string, keyFile string, certFile string, insecure bool) error {
	return nil
}
func (c *Client) AddEncryption(caFile string, keyFile string, certFile string, insecure bool) error {
	c.scheme = "https"
	tlsConfig := &tls.Config{}
	if insecure {
		tlsConfig.InsecureSkipVerify = true
	} else if caFile != "" {
		caCert, err := ioutil.ReadFile(caFile)
		if err != nil {
			return nil
		}
		caCertPool := x509.NewCertPool()
		caCertPool.AppendCertsFromPEM(caCert)
		tlsConfig.RootCAs = caCertPool
		if certFile != "" && keyFile != "" {
			cert, err := tls.LoadX509KeyPair(certFile, keyFile)
			if err != nil {
				return nil
			}
			tlsConfig.Certificates = []tls.Certificate{cert}
		} else {
			tlsConfig.InsecureSkipVerify = true
		}
	}
	transport := &http.Transport{
		TLSClientConfig: tlsConfig,
	}
	c.httpClient.Transport = transport
	return nil
}
type ApiClient interface {
	Create(ptr IObject) error
	Update(ptr IObject) error
	DeleteByUuid(typename, uuid string) error
	Delete(ptr IObject) error
	FindByUuid(typename string, uuid string) (IObject, error)
	UuidByName(typename string, fqn string) (string, error)
	FQNameByUuid(uuid string) ([]string, error)
	FindByName(typename string, fqn string) (IObject, error)
	List(typename string) ([]ListResult, error)
	ListByParent(typename string, parentID string) ([]ListResult, error)
	ListDetail(typename string, fields []string) ([]IObject, error)
	ListDetailByParent(typename string, parentID string, fields []string) ([]IObject, error)
}
type Client struct {
	server     string
	scheme     string
	port       int
	httpClient *http.Client
	auth       Authenticator
	encrypt    Encryptor
}
type TlsConfig struct {
	ca   string
	key  string
	cert string
}
type ListResult struct {
	Fq_name []string
	Href    string
	Uuid    string
}
var (
	typeMap TypeMap
)
func NewClient(server string, port int) *Client {
	client := new(Client)
	client.server = server
	client.port = port
	client.scheme = "http"
	client.httpClient = &http.Client{}
	client.auth = new(NopAuthenticator)
	client.encrypt = new(NopEncryptor)
	return client
}
func (c *Client) GetServer() string {
	return c.server
}
func (c *Client) SetAuthenticator(auth Authenticator) {
	c.auth = auth
}
func (c *Client) SetEncryptor(encrypt Encryptor) {
	c.encrypt = encrypt
}
func typename(ptr IObject) string {
	name := reflect.TypeOf(ptr).Elem().Name()
	var buf []rune
	for i, c := range name {
		if unicode.IsUpper(c) {
			if i > 0 {
				buf = append(buf, '-')
			}
			buf = append(buf, unicode.ToLower(c))
		} else {
			buf = append(buf, c)
		}
	}
	return string(buf)
}
func (c *Client) httpPost(url string, bodyType string, body io.Reader) (
	*http.Response, error) {
	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", bodyType)
	err = c.auth.AddAuthentication(req)
	if err != nil {
		return nil, err
	}
	return c.httpClient.Do(req)
}
func (c *Client) httpPut(url string, bodyType string, body io.Reader) (
	*http.Response, error) {
	req, err := http.NewRequest("PUT", url, body)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", bodyType)
	err = c.auth.AddAuthentication(req)
	if err != nil {
		return nil, err
	}
	return c.httpClient.Do(req)
}
func (c *Client) httpGet(url string) (*http.Response, error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	err = c.auth.AddAuthentication(req)
	if err != nil {
		return nil, err
	}
	return c.httpClient.Do(req)
}
func (c *Client) httpDelete(url string) (*http.Response, error) {
	req, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return nil, err
	}
	err = c.auth.AddAuthentication(req)
	if err != nil {
		return nil, err
	}
	return c.httpClient.Do(req)
}
func (c *Client) Create(ptr IObject) error {
	xtype := typename(ptr)
	url := fmt.Sprintf("%s://%s:%d/%ss", c.scheme, c.server, c.port, xtype)
	objJson, err := json.Marshal(ptr)
	if err != nil {
		return err
	}
	var rawJson json.RawMessage = objJson
	msg := map[string]*json.RawMessage{
		xtype: &rawJson,
	}
	data, err := json.Marshal(msg)
	resp, err := c.httpPost(url, "application/json", bytes.NewReader(data))
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("%s: %s", resp.Status, body)
	}
	ptr.SetClient(c)
	var m map[string]json.RawMessage
	err = json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	return json.Unmarshal(m[xtype], ptr)
}
func (c *Client) readObject(typename string, href string) (IObject, error) {
	url := fmt.Sprintf("%s?exclude_back_refs=true&exclude_children=true",
		href)
	resp, err := c.httpGet(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("%s: %s", resp.Status, body)
	}
	var m map[string]*json.RawMessage
	err = json.Unmarshal(body, &m)
	if err != nil {
		return nil, err
	}
	content, ok := m[typename]
	if !ok {
		return nil, fmt.Errorf("No %s in Response", typename)
	}
	var xtype reflect.Type = typeMap[typename]
	valueT := reflect.New(xtype)
	obj := valueT.Interface().(IObject)
	err = json.Unmarshal(*content, obj)
	if err != nil {
		return nil, err
	}
	obj.SetClient(c)
	return obj, err
}
func (c *Client) ReadListResult(
	typename string, result *ListResult) (IObject, error) {
	return c.readObject(typename, result.Href)
}
func (c *Client) ReadReference(
	typename string, ref *Reference) (IObject, error) {
	return c.readObject(typename, ref.Href)
}
func (c *Client) Update(ptr IObject) error {
	objJson, err := ptr.UpdateObject()
	if err != nil {
		return err
	}
	var rawJson json.RawMessage = objJson
	msg := map[string]*json.RawMessage{
		ptr.GetType(): &rawJson,
	}
	data, err := json.Marshal(msg)
	if err != nil {
		return err
	}
	resp, err := c.httpPut(ptr.GetHref(), "application/json",
		bytes.NewReader(data))
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		return fmt.Errorf("%s: %s", resp.Status, body)
	}
	err = ptr.UpdateReferences()
	if err != nil {
		return err
	}
	ptr.UpdateDone()
	return nil
}
func (c *Client) DeleteByUuid(typename, uuid string) error {
	url := fmt.Sprintf("%s://%s:%d/%s/%s", c.scheme, c.server, c.port, typename, uuid)
	resp, err := c.httpDelete(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		return fmt.Errorf("%s: %s", resp.Status, body)
	}
	return nil
}
func (c *Client) Delete(ptr IObject) error {
	resp, err := c.httpDelete(ptr.GetHref())
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		return fmt.Errorf("%s: %s", resp.Status, body)
	}
	return nil
}
func (c *Client) FindByUuid(typename string, uuid string) (IObject, error) {
	url := fmt.Sprintf("%s://%s:%d/%s/%s", c.scheme, c.server, c.port,
		typename, uuid)
	return c.readObject(typename, url)
}