func parseResponse(r io.Reader, parseTo interface{}) error {
	return json.NewDecoder(r).Decode(parseTo)
}
parseResponse marshals the given body into the given interface. It should be used just like
json.Marshal in that you pass a pointer to the function.
package cerberus
import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/Nike-Inc/cerberus-go-client/utils"
	"io"
	"net/http"
	"net/url"
	"os"
	"github.com/Nike-Inc/cerberus-go-client/auth"
	vault "github.com/hashicorp/vault/api"
)
type Client struct {
	Authentication auth.Auth
	CerberusURL    *url.URL
	vaultClient    *vault.Client
	httpClient     *http.Client
	defaultHeaders http.Header
}
func NewClient(authMethod auth.Auth, otpFile *os.File) (*Client, error) {
	token, loginErr := authMethod.GetToken(otpFile)
	if loginErr != nil {
		return nil, loginErr
	}
	vaultConfig := vault.DefaultConfig()
	vaultConfig.Address = authMethod.GetURL().String()
	vclient, clientErr := vault.NewClient(vaultConfig)
	if clientErr != nil {
		return nil, fmt.Errorf("Error while setting up vault client: %v", clientErr)
	}
	vclient.SetToken(token)
	return &Client{
		Authentication: authMethod,
		CerberusURL:    authMethod.GetURL(),
		vaultClient:    vclient,
		httpClient:     utils.DefaultHttpClient(),
	}, nil
}
func NewClientWithHeaders(authMethod auth.Auth, otpFile *os.File, defaultHeaders http.Header) (*Client, error) {
	token, loginErr := authMethod.GetToken(otpFile)
	if loginErr != nil {
		return nil, loginErr
	}
	vaultConfig := vault.DefaultConfig()
	vaultConfig.Address = authMethod.GetURL().String()
	vclient, clientErr := vault.NewClient(vaultConfig)
	if clientErr != nil {
		return nil, fmt.Errorf("Error while setting up vault client: %v", clientErr)
	}
	vclient.SetToken(token)
	return &Client{
		Authentication: authMethod,
		CerberusURL:    authMethod.GetURL(),
		vaultClient:    vclient,
		httpClient:     utils.NewHttpClient(defaultHeaders),
	}, nil
}
func (c *Client) SDB() *SDB {
	return &SDB{
		c: c,
	}
}
func (c *Client) Secret() *Secret {
	return &Secret{
		v: c.vaultClient.Logical(),
	}
}
func (c *Client) Role() *Role {
	return &Role{
		c: c,
	}
}
func (c *Client) Category() *Category {
	return &Category{
		c: c,
	}
}
func (c *Client) Metadata() *Metadata {
	return &Metadata{
		c: c,
	}
}
func (c *Client) SecureFile() *SecureFile {
	return &SecureFile{
		c: c,
	}
}
var ErrorBodyNotReturned = fmt.Errorf("No error body returned from server")
func (c *Client) DoRequestWithBody(method, path string, params map[string]string, contentType string, body io.Reader) (*http.Response, error) {
	var baseURL = *c.CerberusURL
	baseURL.Path = path
	p := baseURL.Query()
	for k, v := range params {
		p.Add(k, v)
	}
	baseURL.RawQuery = p.Encode()
	var req *http.Request
	var err error
	req, err = http.NewRequest(method, baseURL.String(), body)
	if err != nil {
		return nil, err
	}
	headers, headerErr := c.Authentication.GetHeaders()
	if headerErr != nil {
		return nil, headerErr
	}
	req.Header = headers
	if contentType != "" {
		req.Header.Set("Content-Type", contentType)
	}
	resp, respErr := c.httpClient.Do(req)
	if respErr != nil {
		return resp, respErr
	}
	if resp.Header.Get("X-Refresh-Token") == "true" {
		if err := c.Authentication.Refresh(); err != nil {
			return resp, fmt.Errorf("Error refreshing token: %v", err)
		}
		tok, err := c.Authentication.GetToken(nil)
		if err != nil {
			return nil, err
		}
		c.vaultClient.SetToken(tok)
	}
	return resp, nil
}
func (c *Client) DoRequest(method, path string, params map[string]string, data interface{}) (*http.Response, error) {
	var body io.ReadWriter
	var contentType string
	if data != nil {
		body = &bytes.Buffer{}
		contentType = "application/json"
		err := json.NewEncoder(body).Encode(data)
		if err != nil {
			return nil, err
		}
	}
	return c.DoRequestWithBody(method, path, params, contentType, body)
}