func setEndpoint(rancherURL string, component string, resourceLimit string) string {
	var endpoint string
	endpoint = (rancherURL + "/" + component + "/" + "?limit=" + resourceLimit)
	endpoint = strings.Replace(endpoint, "v1", "v2-beta", 1)
	return endpoint
}
setEndpoint - Determines the correct URL endpoint to use, gives us backwards compatibility
package main
import (
	"encoding/json"
	"net/http"
	"strconv"
	"strings"
	"time"
	"github.com/infinityworks/prometheus-rancher-exporter/measure"
	"github.com/prometheus/client_golang/prometheus"
)
type Data struct {
	Data []struct {
		HealthState string            `json:"healthState"`
		Name        string            `json:"name"`
		State       string            `json:"state"`
		System      bool              `json:"system"`
		Scale       int               `json:"scale"`
		HostName    string            `json:"hostname"`
		ID          string            `json:"id"`
		StackID     string            `json:"stackId"`
		EnvID       string            `json:"environmentId"`
		BaseType    string            `json:"basetype"`
		Type        string            `json:"type"`
		AgentState  string            `json:"agentState"`
		Labels      map[string]string `json:"labels"`
		ClusterID   string            `json:"clusterId"`
		NodeName    string            `json:"nodeName"`
		HostInfo *HostInfo `json:"info"`
		LaunchConfig *LaunchConfig `json:"launchConfig"`
		ComponentStatuses []*ComponentStatuses `json:"componentStatuses"`
	} `json:"data"`
}
type HostInfo struct {
	CPUInfo struct {
		Count int `json:"count"`
	} `json:"cpuInfo"`
	MemoryInfo struct {
		MemTotal int `json:"memTotal"`
		MemFree  int `json:"memFree"`
	} `json:"memoryInfo"`
	DiskInfo struct {
		MountPoints map[string]MountPoint `json:"mountPoints"`
	} `json:"diskInfo"`
}
type MountPoint struct {
	Total int `json:"total"`
	Used  int `json:"used"`
}
type LaunchConfig struct {
	Labels map[string]string `json:"labels"`
}
type ComponentStatuses struct {
	Conditions []*Condition `json:"conditions"`
	Name       string       `json:"name"`
}
type Condition struct {
	Status string `json:"status"`
}
func (e *Exporter) processMetrics(data *Data, endpoint string, hideSys bool, ch chan<- prometheus.Metric) error {
	var filteredLabels map[string]string
	for _, x := range data.Data {
		if hideSys && x.System {
			continue
		}
		dataType := x.BaseType
		if dataType == "" {
			dataType = x.Type
		}
		if !checkMetric(endpoint, dataType) {
			continue
		}
		log.Debugf("Processing metrics for %s", endpoint)
		if endpoint == "hosts" {
			filteredLabels = e.allowedLabels(x.Labels)
			var s = x.HostName
			if x.Name != "" {
				s = x.Name
			}
			e.setHostStateMetrics(s, x.State, x.AgentState, filteredLabels)
			if x.HostInfo != nil {
				e.setHostInfoMetrics(s, x.HostInfo, filteredLabels)
			}
		} else if endpoint == "stacks" {
			stackRef = storeStackRef(x.ID, x.Name)
			e.setStackMetrics(x.Name, x.State, x.HealthState, strconv.FormatBool(x.System))
		} else if endpoint == "services" {
			var stackName = retrieveStackRef(x.StackID)
			if stackName == "unknown" {
				log.Warnf("Failed to obtain stack_name for %s from the API", x.Name)
			}
			if x.LaunchConfig != nil && len(x.LaunchConfig.Labels) > 0 {
				filteredLabels = e.allowedLabels(x.LaunchConfig.Labels)
			}
			e.setServiceMetrics(x.Name, stackName, x.State, x.HealthState, x.Scale, filteredLabels)
		} else if endpoint == "clusters" {
			clusterRef = storeClusterRef(x.ID, x.Name)
			e.setClusterMetrics(x.Name, x.State, x.ComponentStatuses)
		} else if endpoint == "nodes" {
			var clusterName = retrieveClusterRef(x.ClusterID)
			if clusterName == "unknown" {
				log.Warnf("Failed to obtain cluster_name for %s from the API", x.NodeName)
			}
			e.setNodeMetrics(x.NodeName, x.State, clusterName)
		}
	}
	return nil
}
func (e *Exporter) gatherData(rancherURL string, resourceLimit string, accessKey string, secretKey string, endpoint string, ch chan<- prometheus.Metric) (*Data, error) {
	url := setEndpoint(rancherURL, endpoint, resourceLimit)
	var data = new(Data)
	err := getJSON(url, accessKey, secretKey, &data)
	if err != nil {
		log.Error("Error getting JSON from endpoint ", endpoint)
		return nil, err
	}
	log.Debugf("JSON Fetched for: "+endpoint+": %+v", data)
	return data, err
}
func (e *Exporter) allowedLabels(labels map[string]string) map[string]string {
	result := make(map[string]string)
	for name, val := range labels {
		if e.labelsFilter.MatchString(name) {
			result[name] = val
		}
	}
	return result
}
func getJSON(url string, accessKey string, secretKey string, target interface{}) error {
	start := time.Now()
	measure.FunctionCountTotal.With(prometheus.Labels{"pkg": "main", "fnc": "getJSON"}).Inc()
	log.Info("Scraping: ", url)
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Error("Error Collecting JSON from API: ", err)
	}
	req.SetBasicAuth(accessKey, secretKey)
	resp, err := client.Do(req)
	if err != nil {
		log.Error("Error Collecting JSON from API: ", err)
	}
	if resp.StatusCode != 200 {
		log.Error("Error Collecting JSON from API: ", resp.Status)
	}
	respFormatted := json.NewDecoder(resp.Body).Decode(target)
	elapsed := float64((time.Since(start)) / time.Microsecond)
	measure.FunctionDurations.WithLabelValues("main", "getJSON").Observe(elapsed)
	resp.Body.Close()
	return respFormatted
}