func (c *Credentials) OnDemandSnapshotPhysical(hostName, slaName, fileset, hostOS string, timeout ...int) (string, error) {
	httpTimeout := httpTimeout(timeout)
	if httpTimeout == 15 {
		httpTimeout = 180
	}
	validHostOs := map[string]bool{
		"Linux":   true,
		"Windows": true,
	}
	if validHostOs[hostOS] == false {
		return "", fmt.Errorf("The 'hostOS' must be 'Linux' or 'Windows")
	}
	hostID, err := c.ObjectID(hostName, "physicalHost", httpTimeout)
	if err != nil {
		return "", err
	}
	filesetTemplateID, err := c.ObjectID(fileset, "filesetTemplate", httpTimeout, hostOS)
	if err != nil {
		return "", err
	}
	filesetSummary, err := c.Get("v1", fmt.Sprintf("/fileset?primary_cluster_id=local&host_id=%s&is_relic=false&template_id=%s", hostID, filesetTemplateID))
	if err != nil {
		return "", err
	}
	if filesetSummary.(map[string]interface{})["total"] == 0 {
		return "", fmt.Errorf("The Physical Host '%s' is not assigned to the '%s' Fileset", hostName, fileset)
	}
	filesetID := filesetSummary.(map[string]interface{})["data"].([]interface{})[0].(map[string]interface{})["id"].(string)
	var slaID string
	switch slaName {
	case "current":
		slaID = filesetSummary.(map[string]interface{})["data"].([]interface{})[0].(map[string]interface{})["effectiveSlaDomainId"].(string)
	default:
		slaID, err = c.ObjectID(slaName, "sla", httpTimeout)
		if err != nil {
			return "", err
		}
	}
	config := map[string]string{}
	config["slaId"] = slaID
	apiRequeset, err := c.Post("v1", fmt.Sprintf("/fileset/%s/snapshot", filesetID), config, httpTimeout)
	if err != nil {
		return "", err
	}
	return apiRequeset.(map[string]interface{})["links"].([]interface{})[0].(map[string]interface{})["href"].(string), nil
}
OnDemandSnapshotPhysical initiates an on-demand snapshot for a physical host ("hostname"). To use the currently  assigned SLA Domain for the
snapshot use "current" for the slaName.

Valid "hostOS" choices are:

Linux and Windows

The function will return:
The job status URL for the on-demand Snapshot
package rubrikcdm
import (
	"errors"
	"fmt"
	"time"
	"github.com/mitchellh/mapstructure"
)
type EndManagedVolumeSnapshot struct {
	ID                     string   `json:"id"`
	Date                   string   `json:"date"`
	ExpirationDate         string   `json:"expirationDate"`
	SourceObjectType       string   `json:"sourceObjectType"`
	IsOnDemandSnapshot     bool     `json:"isOnDemandSnapshot"`
	CloudState             int      `json:"cloudState"`
	ConsistencyLevel       string   `json:"consistencyLevel"`
	IndexState             int      `json:"indexState"`
	ReplicationLocationIds []string `json:"replicationLocationIds"`
	ArchivalLocationIds    []string `json:"archivalLocationIds"`
	SLAID                  string   `json:"slaId"`
	SLAName                string   `json:"slaName"`
	Links                  struct {
		Self struct {
			Href string `json:"href"`
			Rel  string `json:"rel"`
		} `json:"self"`
	} `json:"links"`
}
type Cluster struct {
	ID         string `json:"id"`
	Version    string `json:"version"`
	APIVersion string `json:"apiVersion"`
	Name       string `json:"name"`
	Timezone   struct {
		Timezone string `json:"timezone"`
	} `json:"timezone"`
	Geolocation struct {
		Address string `json:"address"`
	} `json:"geolocation"`
	AcceptedEulaVersion string `json:"acceptedEulaVersion"`
	LatestEulaVersion   string `json:"latestEulaVersion"`
}
func (c *Credentials) ObjectID(objectName, objectType string, timeout int, hostOS ...string) (string, error) {
	validObjectType := map[string]bool{
		"vmware":          true,
		"sla":             true,
		"vmwareHost":      true,
		"physicalHost":    true,
		"filesetTemplate": true,
		"managedVolume":   true,
		"vcenter":         true,
		"ec2":             true,
		"ahv":             true,
	}
	if validObjectType[objectType] == false {
		return "", fmt.Errorf("The 'objectType' must be 'vmware', 'sla', 'vmwareHost', 'physicalHost', 'filesetTemplate', 'managedVolume', or 'vcenter'")
	}
	var objectSummaryAPIVersion string
	var objectSummaryAPIEndpoint string
	switch objectType {
	case "vmware":
		objectSummaryAPIVersion = "v1"
		objectSummaryAPIEndpoint = fmt.Sprintf("/vmware/vm?primary_cluster_id=local&is_relic=false&name=%s", objectName)
	case "sla":
		objectSummaryAPIVersion = "v1"
		objectSummaryAPIEndpoint = fmt.Sprintf("/sla_domain?primary_cluster_id=local&name=%s", objectName)
	case "vmwareHost":
		objectSummaryAPIVersion = "v1"
		objectSummaryAPIEndpoint = "/vmware/host?primary_cluster_id=local"
	case "physicalHost":
		objectSummaryAPIVersion = "v1"
		objectSummaryAPIEndpoint = fmt.Sprintf("/host?primary_cluster_id=local&hostname=%s", objectName)
	case "filesetTemplate":
		var hostOperatingSystem string
		if len(hostOS) > 0 {
			hostOperatingSystem = hostOS[0]
			switch hostOperatingSystem {
			case "Linux":
			case "Windows":
			default:
				return "", errors.New("The hostOS must be either 'Linux' or 'Windows'")
			}
		} else if len(hostOS) == 0 {
			return "", errors.New("You must provide the Fileset Tempalte OS type")
		}
		objectSummaryAPIVersion = "v1"
		objectSummaryAPIEndpoint = fmt.Sprintf("/fileset_template?primary_cluster_id=local&operating_system_type=%s&name=%s", hostOperatingSystem, objectName)
	case "managedVolume":
		objectSummaryAPIVersion = "internal"
		objectSummaryAPIEndpoint = fmt.Sprintf("/managed_volume?is_relic=false&primary_cluster_id=local&name=%s", objectName)
	case "vcenter":
		objectSummaryAPIVersion = "v1"
		objectSummaryAPIEndpoint = "/vmware/vcenter"
	case "ec2":
		objectSummaryAPIVersion = "internal"
		objectSummaryAPIEndpoint = fmt.Sprintf("/aws/ec2_instance?name=%s&is_relic=false&sort_by=instanceId&sort_order=asc", objectName)
	case "ahv":
		objectSummaryAPIVersion = "internal"
		objectSummaryAPIEndpoint = fmt.Sprintf("/nutanix/vm?primary_cluster_id=local&is_relic=false&name=%s", objectName)
	}
	apiRequest, err := c.Get(objectSummaryAPIVersion, objectSummaryAPIEndpoint, timeout)
	if err != nil {
		return "", err
	}
	if apiRequest.(map[string]interface{})["total"] == 0 {
		return "", fmt.Errorf("The %s object '%s' was not found on the Rubrik cluster", objectType, objectName)
	} else if apiRequest.(map[string]interface{})["total"].(float64) > 0 {
		objectIDs := make([]string, 0)
		var nameValue string
		if objectType == "physicalHost" {
			nameValue = "hostname"
		} else if objectType == "ec2" {
			nameValue = "instanceId"
		} else {
			nameValue = "name"
		}
		for _, v := range apiRequest.(map[string]interface{})["data"].([]interface{}) {
			if v.(interface{}).(map[string]interface{})[nameValue].(string) == objectName {
				objectIDs = append(objectIDs, v.(interface{}).(map[string]interface{})["id"].(string))
			}
		}
		if len(objectIDs) > 1 {
			return "", fmt.Errorf("Multiple %s objects named '%s' were found on the Rubrik cluster. Unable to return a specific object id", objectType, objectName)
		} else if len(objectIDs) == 0 {
			return "", fmt.Errorf("The %s object '%s' was not found on the Rubrik cluster", objectType, objectName)
		} else {
			return objectIDs[0], nil
		}
	}
	return "", fmt.Errorf("The %s object '%s' was not found on the Rubrik cluster", objectType, objectName)
}
func (c *Credentials) AssignSLA(objectName, objectType, slaName string, timeout ...int) (*StatusCode, error) {
	httpTimeout := httpTimeout(timeout)
	validObjectType := map[string]bool{
		"vmware": true,
		"ahv":    true,
	}
	if validObjectType[objectType] == false {
		return nil, fmt.Errorf("The 'objectType' must be 'vmware' or 'ahv'.")
	}
	var slaID string
	var err error
	switch slaName {
	case "do not protect":
		slaID = "UNPROTECTED"
	case "clear":
		slaID = "INHERIT"
	default:
		slaID, err = c.ObjectID(slaName, "sla", httpTimeout)
		if err != nil {
			return nil, err
		}
	}
	config := map[string]interface{}{}
	switch objectType {
	case "vmware":
		vmID, err := c.ObjectID(objectName, "vmware", httpTimeout)
		if err != nil {
			return nil, err
		}
		vmSummary, err := c.Get("v1", fmt.Sprintf("/vmware/vm/%s", vmID), httpTimeout)
		if err != nil {
			return nil, err
		}
		var currentSLAID string
		switch slaID {
		case "INHERIT":
			currentSLAID = vmSummary.(map[string]interface{})["configuredSlaDomainId"].(string)
		default:
			currentSLAID = vmSummary.(map[string]interface{})["effectiveSlaDomainId"].(string)
		}
		if slaID == currentSLAID {
			return nil, fmt.Errorf("No change required. The vSphere VM '%s' is already assigned to the '%s' SLA Domain", objectName, slaName)
		}
		config["managedIds"] = []string{vmID}
	case "ahv":
		vmID, err := c.ObjectID(objectName, "ahv", httpTimeout)
		if err != nil {
			return nil, err
		}
		vmSummary, err := c.Get("internal", fmt.Sprintf("/nutanix/vm/%s", vmID), httpTimeout)
		if err != nil {
			return nil, err
		}
		var currentSLAID string
		switch slaID {
		case "INHERIT":
			currentSLAID = vmSummary.(map[string]interface{})["configuredSlaDomainId"].(string)
		default:
			currentSLAID = vmSummary.(map[string]interface{})["effectiveSlaDomainId"].(string)
		}
		if slaID == currentSLAID {
			return nil, fmt.Errorf("No change required. The AHV VM '%s' is already assigned to the '%s' SLA Domain", objectName, slaName)
		}
		config["managedIds"] = []string{vmID}
	}
	apiRequest, err := c.Post("internal", fmt.Sprintf("/sla_domain/%s/assign", slaID), config, httpTimeout)
	if err != nil {
		return nil, err
	}
	var apiResponse StatusCode
	mapErr := mapstructure.Decode(apiRequest, &apiResponse)
	if mapErr != nil {
		return nil, mapErr
	}
	return &apiResponse, nil
}
func (c *Credentials) BeginManagedVolumeSnapshot(name string, timeout ...int) (*StatusCode, error) {
	httpTimeout := httpTimeout(timeout)
	managedVolumeID, err := c.ObjectID(name, "managedVolume", httpTimeout)
	if err != nil {
		return nil, err
	}
	managedVolumeSummary, err := c.Get("internal", fmt.Sprintf("/managed_volume/%s", managedVolumeID), httpTimeout)
	if err != nil {
		return nil, err
	}
	if managedVolumeSummary.(map[string]interface{})["isWritable"].(bool) {
		return nil, fmt.Errorf("No change required. The Managed Volume '%s' is already in a writeable state", name)
	}
	config := map[string]string{}
	apiRequest, err := c.Post("internal", fmt.Sprintf("/managed_volume/%s/begin_snapshot", managedVolumeID), config, httpTimeout)
	if err != nil {
		return nil, err
	}
	var apiResponse StatusCode
	mapErr := mapstructure.Decode(apiRequest, &apiResponse)
	if mapErr != nil {
		return nil, mapErr
	}
	return &apiResponse, nil
}
func (c *Credentials) EndManagedVolumeSnapshot(name, slaName string, timeout ...int) (*EndManagedVolumeSnapshot, error) {
	httpTimeout := httpTimeout(timeout)
	managedVolumeID, err := c.ObjectID(name, "managedVolume", httpTimeout)
	if err != nil {
		return nil, err
	}
	managedVolumeSummary, err := c.Get("internal", fmt.Sprintf("/managed_volume/%s", managedVolumeID), httpTimeout)
	if err != nil {
		return nil, err
	}
	if managedVolumeSummary.(map[string]interface{})["isWritable"].(bool) == false {
		return nil, fmt.Errorf("No change required. The Managed Volume '%s' is already in a read-only state", name)
	}
	var slaID string
	config := map[string]interface{}{}
	switch slaName {
	case "current":
	default:
		slaID, err = c.ObjectID(slaName, "sla", httpTimeout)
		if err != nil {
			return nil, err
		}
		config["retentionConfig"] = map[string]interface{}{}
		config["retentionConfig"].(map[string]interface{})["slaId"] = slaID
	}
	apiRequest, err := c.Post("internal", fmt.Sprintf("/managed_volume/%s/end_snapshot", managedVolumeID), config, httpTimeout)
	if err != nil {
		return nil, err
	}
	var endSnapshot EndManagedVolumeSnapshot
	mapErr := mapstructure.Decode(apiRequest, &endSnapshot)
	if mapErr != nil {
		return nil, mapErr
	}
	return &endSnapshot, nil
}
func (c *Credentials) GetSLAObjects(slaName, objectType string, timeout ...int) (interface{}, error) {
	httpTimeout := httpTimeout(timeout)
	validObjectType := map[string]bool{
		"vmware": true,
	}
	if validObjectType[objectType] == false {
		return nil, fmt.Errorf("The 'objectType' must be 'vmware'")
	}
	switch objectType {
	case "vmware":
		slaID, err := c.ObjectID(slaName, "sla", httpTimeout)
		if err != nil {
			return nil, err
		}
		allVMinSLA, err := c.Get("v1", fmt.Sprintf("/vmware/vm?effective_sla_domain_id=%s&is_relic=false", slaID), httpTimeout)
		if err != nil {
			return nil, err
		}
		if allVMinSLA.(map[string]interface{})["total"].(float64) == 0 {
			return fmt.Sprintf("The SLA '%s' is currently not protecting any %s objects.", slaName, objectType), nil
		}
		vmNameID := map[interface{}]interface{}{}
		for _, v := range allVMinSLA.(map[string]interface{})["data"].([]interface{}) {
			vmNameID[v.(map[string]interface{})["name"]] = v.(map[string]interface{})["id"]
		}
		return vmNameID, nil
	}
	return "", nil
}
func (c *Credentials) PauseSnapshot(objectName, objectType string, timeout ...int) (interface{}, error) {
	httpTimeout := httpTimeout(timeout)
	if httpTimeout == 15 {
		httpTimeout = 180
	}
	validObjectType := map[string]bool{
		"vmware": true,
	}
	if validObjectType[objectType] == false {
		return nil, fmt.Errorf("The 'objectType' must be 'vmware'")
	}
	switch objectType {
	case "vmware":
		vmID, err := c.ObjectID(objectName, "vmware", httpTimeout)
		if err != nil {
			return nil, err
		}
		vmSummary, err := c.Get("v1", fmt.Sprintf("/vmware/vm/%s", vmID), httpTimeout)
		if err != nil {
			return nil, err
		}
		if vmSummary.(map[string]interface{})["blackoutWindowStatus"].(map[string]interface{})["isSnappableBlackoutActive"].(bool) {
			return fmt.Sprintf("No change required. The '%s' '%s' is already paused.", objectName, objectType), nil
		}
		config := map[string]bool{}
		config["isVmPaused"] = true
		apiRequest, err := c.Patch("v1", fmt.Sprintf("/vmware/vm/%s", vmID), config, httpTimeout)
		if err != nil {
			return nil, err
		}
		return apiRequest, nil
	}
	return "", nil
}
func (c *Credentials) ResumeSnapshot(objectName, objectType string, timeout ...int) (interface{}, error) {
	httpTimeout := httpTimeout(timeout)
	if httpTimeout == 15 {
		httpTimeout = 180
	}
	validObjectType := map[string]bool{
		"vmware": true,
	}
	if validObjectType[objectType] == false {
		return nil, fmt.Errorf("The 'objectType' must be 'vmware'")
	}
	switch objectType {
	case "vmware":
		vmID, err := c.ObjectID(objectName, "vmware", httpTimeout)
		if err != nil {
			return nil, err
		}
		vmSummary, err := c.Get("v1", fmt.Sprintf("/vmware/vm/%s", vmID), httpTimeout)
		if err != nil {
			return nil, err
		}
		if vmSummary.(map[string]interface{})["blackoutWindowStatus"].(map[string]interface{})["isSnappableBlackoutActive"].(bool) == false {
			return fmt.Sprintf("No change required. The '%s' '%s' is currently not paused.", objectName, objectType), nil
		}
		config := map[string]bool{}
		config["isVmPaused"] = false
		apiRequest, err := c.Patch("v1", fmt.Sprintf("/vmware/vm/%s", vmID), config, httpTimeout)
		if err != nil {
			return nil, err
		}
		return apiRequest, nil
	}
	return "", nil
}
func (c *Credentials) OnDemandSnapshotVM(objectName, objectType, slaName string, timeout ...int) (string, error) {
	httpTimeout := httpTimeout(timeout)
	if httpTimeout == 15 {
		httpTimeout = 180
	}
	validObjectType := map[string]bool{
		"vmware": true,
	}
	if validObjectType[objectType] == false {
		return "", fmt.Errorf("The 'objectType' must be 'vmware'")
	}
	switch objectType {
	case "vmware":
		vmID, err := c.ObjectID(objectName, "vmware", httpTimeout)
		if err != nil {
			return "", err
		}
		var slaID interface{}
		switch slaName {
		case "current":
			slaID, err = c.Get("v1", fmt.Sprintf("/vmware/vm/%s", vmID))
			if err != nil {
				return "", err
			}
		default:
			slaID, err = c.ObjectID(slaName, "sla", httpTimeout)
			if err != nil {
				return "", err
			}
		}
		config := map[string]string{}
		config["slaId"] = slaID.(map[string]interface{})["effectiveSlaDomainId"].(string)
		apiRequest, err := c.Post("v1", fmt.Sprintf("/vmware/vm/%s/snapshot", vmID), config, httpTimeout)
		if err != nil {
			return "", err
		}
		return apiRequest.(map[string]interface{})["links"].([]interface{})[0].(map[string]interface{})["href"].(string), nil
	}
	return "", nil
}