func (c *ClientMaster) PuppetCertificates() ([]PuppetCertificate, error) {
	ret := []PuppetCertificate{}
	err := c.Get(&ret, "/puppet-ca/v1/certificate_statuses/any")
	return ret, err
}
PuppetCertificatesreturns an array of puppet certificates
package puppetdb
import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)
type ClientMaster struct {
	BaseURL    string
	Cert       string
	Key        string
	httpClient *http.Client
	verbose    bool
}
type Profiler struct {
	Version      string          `json:"service_version"`
	StateVersion int             `json:"service_status_version"`
	DetailLevel  string          `json:"detail_level"`
	State        string          `json:"state"`
	Status       *ProfilerStatus `json:"status"`
}
type PuppetCertificate struct {
	Name            string                       `json:"name"`
	State           string                       `json:"state"`
	DNSAltNames     []string                     `json:"dns_alt_names"`
	SubjectAltNames []string                     `json:"subject_alt_names"`
	Fingerprint     string                       `json:"fingerprint"`
	Fingerprints    PuppetCertificateFingerPrint `json:"fingerprints"`
}
type PuppetCertificateFingerPrint struct {
	SHA1    string `json:"SHA1"`
	SHA256  string `json:"SHA256"`
	SHA512  string `json:"SHA512"`
	Default string `json:"default"`
}
type PuppetCertificateState struct {
	DesiredState string `json:"desired_state"`
}
type ProfilerStatus struct {
	Experimental *ProfilerExperimental `json:"experimental"`
}
type ProfilerExperimental struct {
	FunctionMetrics *[]ProfilerFunctionMetric `json:"function-metrics"`
	ResourceMetrics *[]ProfilerResourceMetric `json:"resource-metrics"`
	CatalogMetrics  *[]ProfilerCatalogMetric  `json:"catalog-metrics"`
	PuppetdbMetrics *[]ProfilerCatalogMetric  `json:"puppetdb-metrics"`
}
type ProfilerFunctionMetric struct {
	Function  string `json:"function"`
	Count     int    `json:"count"`
	Mean      int    `json:"mean"`
	Aggregate int    `json:"aggregate"`
}
type ProfilerResourceMetric struct {
	Resource  string `json:"resource"`
	Count     int    `json:"count"`
	Mean      int    `json:"mean"`
	Aggregate int    `json:"aggregate"`
}
type ProfilerCatalogMetric struct {
	Metric    string `json:"metric"`
	Count     int    `json:"count"`
	Mean      int    `json:"mean"`
	Aggregate int    `json:"aggregate"`
}
type JrubyMetrics struct {
	Version      string       `json:"service_version"`
	StateVersion int          `json:"service_status_version"`
	DetailLevel  string       `json:"detail_level"`
	State        string       `json:"state"`
	Status       *JrubyStatus `json:"status"`
}
type JrubyStatus struct {
	Experimental *JrubyExperimental `json:"experimental"`
}
type JrubyExperimental struct {
	JrubyPoolLockStatus *JrubyPoolLockStatus      `json:"jruby-pool-lock-status"`
	Metrics             *JrubyExperimentalMetrics `json:"metrics"`
}
type JrubyPoolLockStatus struct {
	State      string `json:"current-state"`
	ChangeTime string `json:"last-change-time"`
}
type JrubyExperimentalMetrics struct {
	AverageLockWaitTime     int                      `json:"average-lock-wait-time"`
	NumFreeJrubies          int                      `json:"num-free-jrubies"`
	BorrowCount             int                      `json:"borrow-count"`
	AverageRequestedJrubies float64                  `json:"average-requested-jrubies"`
	BorrowTimeoutCount      int                      `json:"borrow-timeout-count"`
	ReturnCount             int                      `json:"return-count"`
	BorrowRetryCount        int                      `json:"borrow-retry-count"`
	BorrowedInstances       *[]JrubyBorrowedInstance `json:"borrowed-instances"`
	AverageBorrowTime       int                      `json:"average-borrow-time"`
	NumJrubies              int                      `json:"num-jrubies"`
	RequestedCount          int                      `json:"requested-count"`
	QueueLimitHitRate       float64                  `json:"queue-limit-hit-rate"`
	AverageLockHeldTime     int                      `json:"average-lock-held-time"`
	QueueLimitHitCount      int                      `json:"queue-limit-hit-count"`
	AverageFreeJrubies      float64                  `json:"average-free-jrubies"`
	NumPoolLocks            int                      `json:"num-pool-locks"`
	AverageWaitTime         int                      `json:"average-wait-time"`
}
type JrubyBorrowedInstance struct {
	Time          int                          `json:"time"`
	DurationMilis int                          `json:"duration-millis"`
	Reason        *JrubyBorrowedInstanceReason `json:"reason"`
}
type JrubyBorrowedInstanceReason struct {
	Request *JrubyBorrowedInstanceReasonRequest `json:"request"`
}
type JrubyBorrowedInstanceReasonRequest struct {
	Uri     string `json:"uri"`
	Method  string `json:"request-method"`
	RouteId string `json:"route-id"`
}
type MasterMetrics struct {
	Version      string        `json:"service_version"`
	StateVersion int           `json:"service_status_version"`
	DetailLevel  string        `json:"detail_level"`
	State        string        `json:"state"`
	Status       *MasterStatus `json:"status"`
}
type MasterStatus struct {
	Experimental *MasterExperimental `json:"experimental"`
}
type MasterExperimental struct {
	HttpMetrics       *[]MasterHttpMetric       `json:"http-metrics"`
	HttpClientMetrics *[]MasterHttpClientMetric `json:"http-client-metrics"`
}
type MasterHttpMetric struct {
	RouteId   string `json:"route-id"`
	Count     int    `json:"count"`
	Mean      int    `json:"mean"`
	Aggregate int    `json:"aggregate"`
}
type MasterHttpClientMetric struct {
	MetricName string    `json:"metric-name"`
	MetricId   *[]string `json:"metric-id"`
	Count      int       `json:"count"`
	Mean       int       `json:"mean"`
	Aggregate  int       `json:"aggregate"`
}
type ServiceMetrics struct {
	Version      string         `json:"service_version"`
	StateVersion int            `json:"service_status_version"`
	DetailLevel  string         `json:"detail_level"`
	State        string         `json:"state"`
	Status       *ServiceStatus `json:"status"`
}
type ServiceStatus struct {
	Experimental *ServiceExperimental `json:"experimental"`
}
type ServiceExperimental struct {
	JVMMetrics *ServiceJVMMetric `json:"jvm-metrics"`
}
type ServiceJVMMetric struct {
	CpuUsage        float64                     `json:"cpu-usage"`
	UptimeMs        int                         `json:"up-time-ms"`
	GCCpuUsage      float64                     `json:"gc-cpu-usage"`
	StartTimeMs     int                         `json:"start-time-ms"`
	Threading       *ServiceJVMMetricThreading  `json:"threading"`
	HeapMemory      *ServiceJVMMetricHeapMemory `json:"heap-memory"`
	GCStats         *ServiceJVMMetricGCStats    `json:"gc-stats"`
	FileDescriptors *ServiceJVMMetricFile       `json:"file-descriptors"`
	NonHeapMemory   *ServiceJVMMetricHeapMemory `json:"non-heap-memory"`
}
type ServiceJVMMetricThreading struct {
	ThreadCount     int `json:"thread-count"`
	PeakThreadCount int `json:"peak-thread-count"`
}
type ServiceJVMMetricHeapMemory struct {
	Committed int `json:"committed"`
	Init      int `json:"init"`
	Max       int `json:"max"`
	Used      int `json:"used"`
}
type ServiceJVMMetricGCStats struct {
	PSScavenge *ServiceJVMMetricPS `json:"PS Scavenge"`
	PSSweep    *ServiceJVMMetricPS `json:"PS MarkSweep"`
}
type ServiceJVMMetricPS struct {
	Count       int                       `json:"count"`
	TotalTimeMs int                       `json:"total-time-ms"`
	LastGCInfo  *ServiceJVMMetricLastInfo `json:"last-gc-info"`
}
type ServiceJVMMetricLastInfo struct {
	DurationMs int `json:"duration-ms"`
}
type ServiceJVMMetricFile struct {
	Max  int `json:"max"`
	Used int `json:"used"`
}
func getURLMaster(host string, port int) string {
	return fmt.Sprintf("https://%s:%v", host, port)
}
func NewClientSSLMaster(host string, port int, key string, cert string, ca string, verbose bool) *ClientMaster {
	flag.Parse()
	cert2, err := tls.LoadX509KeyPair(cert, key)
	if err != nil {
		log.Println(err.Error())
	}
	caCert, err := ioutil.ReadFile(ca)
	if err != nil {
		log.Println(err.Error())
	}
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caCert)
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert2},
		RootCAs:      caCertPool,
	}
	tlsConfig.BuildNameToCertificate()
	transport := &http.Transport{TLSClientConfig: tlsConfig}
	client := &http.Client{Transport: transport}
	return &ClientMaster{getURLMaster(host, port), cert, key, client, verbose}
}
func NewClientSSLInsecureMaster(host string, port int, verbose bool) *ClientMaster {
	flag.Parse()
	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
	}
	tlsConfig.BuildNameToCertificate()
	transport := &http.Transport{TLSClientConfig: tlsConfig}
	client := &http.Client{Transport: transport}
	return &ClientMaster{getURLMaster(host, port), "", "", client, verbose}
}
func (c *ClientMaster) httpGet(endpoint string) (resp *http.Response, err error) {
	metrics := []string{"jruby-metrics", "master", "puppet-profiler", "status-service"}
	base := strings.TrimRight(c.BaseURL, "/")
	PUrl := ""
	if stringInSlice(endpoint, metrics) {
		PUrl = fmt.Sprintf("%s/status/v1/services/%s?level=debug", base, endpoint)
	} else {
		PUrl = fmt.Sprintf("%s%s", base, endpoint)
	}
	if PUrl == "" {
		return nil, errors.New("Endpoint does not exist")
	}
	if c.verbose == true {
		log.Printf(PUrl)
	}
	return c.httpClient.Get(PUrl)
}
func (c *ClientMaster) httpPut(endpoint string, values interface{}) (resp *http.Response, err error) {
	base := strings.TrimRight(c.BaseURL, "/")
	PUrl := fmt.Sprintf("%s%s", base, endpoint)
	if c.verbose == true {
		log.Printf(PUrl)
	}
	if values != nil {
		json, err := json.Marshal(values)
		req, err := http.NewRequest(http.MethodPut, PUrl, bytes.NewBuffer(json))
		if err != nil {
			log.Println(err.Error())
			return nil, err
		}
		req.Header.Set("Content-Type", "application/json; charset=utf-8")
		return c.httpClient.Do(req)
	}
	return nil, errors.New("No values specified")
}
func (c *ClientMaster) httpDelete(endpoint string) (resp *http.Response, err error) {
	base := strings.TrimRight(c.BaseURL, "/")
	PUrl := fmt.Sprintf("%s%s", base, endpoint)
	if c.verbose == true {
		log.Printf(PUrl)
	}
	req, err := http.NewRequest(http.MethodDelete, PUrl, nil)
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	return c.httpClient.Do(req)
}
func (c *ClientMaster) Get(v interface{}, path string) error {
	resp, err := c.httpGet(path)
	if err != nil {
		log.Print(err)
		return err
	}
	defer resp.Body.Close()
	if err != nil {
		log.Print(err)
		return err
	}
	json.NewDecoder(resp.Body).Decode(&v)
	return err
}
func (c *ClientMaster) Put(v interface{}, path string, values interface{}) (error, int) {
	resp, err := c.httpPut(path, values)
	statusCode := -1
	if resp != nil {
		statusCode = resp.StatusCode
	}
	if err != nil {
		log.Print(err.Error())
		return err, statusCode
	}
	defer resp.Body.Close()
	if err != nil {
		log.Print(err)
		return err, statusCode
	}
	if c.verbose {
		contents, _ := ioutil.ReadAll(resp.Body)
		log.Println(string(contents))
	}
	json.NewDecoder(resp.Body).Decode(&v)
	return err, statusCode
}
func (c *ClientMaster) Delete(path string) (error, int) {
	resp, err := c.httpDelete(path)
	statusCode := -1
	if resp != nil {
		statusCode = resp.StatusCode
	}
	if err != nil {
		log.Print(err.Error())
		return err, statusCode
	}
	defer resp.Body.Close()
	if err != nil {
		log.Print(err)
		return err, statusCode
	}
	if c.verbose {
		contents, _ := ioutil.ReadAll(resp.Body)
		log.Println(string(contents))
	}
	return err, statusCode
}
func (c *ClientMaster) Profiler() (Profiler, error) {
	ret := Profiler{}
	err := c.Get(&ret, "puppet-profiler")
	return ret, err
}
func (c *ClientMaster) Jruby() (JrubyMetrics, error) {
	ret := JrubyMetrics{}
	err := c.Get(&ret, "jruby-metrics")
	return ret, err
}
func (c *ClientMaster) Master() (MasterMetrics, error) {
	ret := MasterMetrics{}
	err := c.Get(&ret, "master")
	return ret, err
}
func (c *ClientMaster) Service() (ServiceMetrics, error) {
	ret := ServiceMetrics{}
	err := c.Get(&ret, "status-service")
	return ret, err
}