func getDownloadURLsHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: get download URLs"
	util.LogHandlerEntry(handler, r)
	registryName, err := getPathVariable(w, r, "registry", handler)
	if err != nil {
		return
	}

	typeName, err := getPathVariable(w, r, "type", handler)
	if err != nil {
		return
	}

	tt, err := registry.ParseType(typeName)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusInternalServerError, err, w)
		return
	}

	c, err := backend.GetDownloadURLs(registryName, tt)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return
	}

	urls := []string{}
	for _, u := range c {
		urls = append(urls, u.String())
	}
	util.LogHandlerExitWithJSON(handler, w, urls, http.StatusOK)
}
func createRegistryHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: create registry"
	util.LogHandlerEntry(handler, r)
	defer r.Body.Close()
	registryName, err := getPathVariable(w, r, "registry", handler)
	if err != nil {
		return
	}

	reg := getRegistry(w, r, handler)
	if reg.Name != registryName {
		e := fmt.Errorf("Registry name does not match %s != %s", reg.Name, registryName)
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return
	}
	if reg != nil {
		err = backend.CreateRegistry(reg)
		if err != nil {
			util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
			return
		}
	}

	util.LogHandlerExitWithJSON(handler, w, reg, http.StatusOK)
}
func listRegistryTypesHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: list registry types"
	util.LogHandlerEntry(handler, r)
	registryName, err := getPathVariable(w, r, "registry", handler)
	if err != nil {
		return
	}

	var regex *regexp.Regexp
	regexString, err := getPathVariable(w, r, "regex", handler)
	if err == nil {
		regex, err = regexp.Compile(regexString)
		if err != nil {
			util.LogAndReturnError(handler, http.StatusInternalServerError, err, w)
			return
		}
	}

	registryTypes, err := backend.ListRegistryTypes(registryName, regex)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusInternalServerError, err, w)
		return
	}

	util.LogHandlerExitWithJSON(handler, w, registryTypes, http.StatusOK)
}
func getConfigurationHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "resourcifier: get configuration"
	util.LogHandlerEntry(handler, r)
	rtype, err := getPathVariable(w, r, "type", handler)
	if err != nil {
		return
	}

	rname, err := getPathVariable(w, r, "name", handler)
	if err != nil {
		return
	}

	c := &common.Configuration{
		[]*common.Resource{
			{Name: rname, Type: rtype},
		},
	}

	output, err := backend.Configure(c, configurator.GetOperation)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return
	}

	util.LogHandlerExit(handler, http.StatusOK, output, w)
	util.WriteYAML(handler, w, []byte(output), http.StatusOK)
}
func getPathVariable(w http.ResponseWriter, r *http.Request, variable, handler string) (string, error) {
	vars := mux.Vars(r)
	escaped, ok := vars[variable]
	if !ok {
		e := errors.New(fmt.Sprintf("%s name not found in URL", variable))
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return "", e
	}

	unescaped, err := url.QueryUnescape(escaped)
	if err != nil {
		e := fmt.Errorf("cannot decode name (%v)", variable)
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return "", e
	}

	return unescaped, nil
}
func getPathVariable(w http.ResponseWriter, r *http.Request, variable, handler string) (string, error) {
	vars := mux.Vars(r)
	ret, ok := vars[variable]
	if !ok {
		e := fmt.Errorf("%s parameter not found in URL", variable)
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return "", e
	}
	return ret, nil
}
// Putting Type handlers here for now because deployments.go
// currently owns its own Manager backend and doesn't like to share.
func listTypesHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: list types"
	util.LogHandlerEntry(handler, r)
	types, err := backend.ListTypes()
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return
	}

	util.LogHandlerExitWithJSON(handler, w, types, http.StatusOK)
}
func getConfiguration(w http.ResponseWriter, r *http.Request, handler string) *common.Configuration {
	b := io.LimitReader(r.Body, *maxLength*1024)
	y, err := ioutil.ReadAll(b)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return nil
	}

	// Reject the input if it exceeded the length limit,
	// since we may not have read all of it into the buffer.
	if _, err = b.Read(make([]byte, 0, 1)); err != io.EOF {
		e := fmt.Errorf("configuration exceeds maximum length of %d KB.", *maxLength)
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return nil
	}

	j, err := yaml.YAMLToJSON(y)
	if err != nil {
		e := errors.New(err.Error() + "\n" + string(y))
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return nil
	}

	c := &common.Configuration{}
	if err := json.Unmarshal(j, c); err != nil {
		e := errors.New(err.Error() + "\n" + string(j))
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return nil
	}

	if len(c.Resources) < 1 {
		e := fmt.Errorf("configuration is empty")
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return nil
	}

	return c
}
func getTemplate(w http.ResponseWriter, r *http.Request, handler string) *manager.Template {
	util.LogHandlerEntry(handler, r)
	b := io.LimitReader(r.Body, *maxLength*1024)
	y, err := ioutil.ReadAll(b)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return nil
	}

	// Reject the input if it exceeded the length limit,
	// since we may not have read all of it into the buffer.
	if _, err = b.Read(make([]byte, 0, 1)); err != io.EOF {
		e := fmt.Errorf("template exceeds maximum length of %d KB", *maxLength)
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return nil
	}

	if err := r.Body.Close(); err != nil {
		util.LogAndReturnError(handler, http.StatusInternalServerError, err, w)
		return nil
	}

	j, err := yaml.YAMLToJSON(y)
	if err != nil {
		e := fmt.Errorf("%v\n%v", err, string(y))
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return nil
	}

	t := &manager.Template{}
	if err := json.Unmarshal(j, t); err != nil {
		e := fmt.Errorf("%v\n%v", err, string(j))
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return nil
	}

	return t
}
func listDeploymentsHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: list deployments"
	util.LogHandlerEntry(handler, r)
	l, err := backend.ListDeployments()
	if err != nil {
		util.LogAndReturnError(handler, http.StatusInternalServerError, err, w)
		return
	}
	var names []string
	for _, d := range l {
		names = append(names, d.Name)
	}

	util.LogHandlerExitWithJSON(handler, w, names, http.StatusOK)
}
func getJsonFromRequest(w http.ResponseWriter, r *http.Request, handler string) ([]byte, error) {
	util.LogHandlerEntry(handler, r)
	b := io.LimitReader(r.Body, *maxLength*1024)
	y, err := ioutil.ReadAll(b)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return []byte{}, err
	}

	// Reject the input if it exceeded the length limit,
	// since we may not have read all of it into the buffer.
	if _, err = b.Read(make([]byte, 0, 1)); err != io.EOF {
		e := fmt.Errorf("template exceeds maximum length of %d KB", *maxLength)
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return []byte{}, err
	}

	if err := r.Body.Close(); err != nil {
		util.LogAndReturnError(handler, http.StatusInternalServerError, err, w)
		return []byte{}, err
	}

	return yaml.YAMLToJSON(y)
}
func expandHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: expand config"
	util.LogHandlerEntry(handler, r)
	defer r.Body.Close()
	t := getTemplate(w, r, handler)
	if t != nil {
		c, err := backend.Expand(t)
		if err != nil {
			util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
			return
		}

		util.LogHandlerExitWithJSON(handler, w, c, http.StatusCreated)
		return
	}
}
func createDeploymentHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: create deployment"
	util.LogHandlerEntry(handler, r)
	defer r.Body.Close()
	t := getTemplate(w, r, handler)
	if t != nil {
		d, err := backend.CreateDeployment(t)
		if err != nil {
			util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
			return
		}

		util.LogHandlerExitWithJSON(handler, w, d, http.StatusCreated)
		return
	}
}
func getDeploymentHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: get deployment"
	util.LogHandlerEntry(handler, r)
	name, err := getPathVariable(w, r, "deployment", handler)
	if err != nil {
		return
	}

	d, err := backend.GetDeployment(name)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return
	}

	util.LogHandlerExitWithJSON(handler, w, d, http.StatusOK)
}
func listTypeInstancesHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: list instances"
	util.LogHandlerEntry(handler, r)
	typeName, err := getPathVariable(w, r, "type", handler)
	if err != nil {
		return
	}

	instances, err := backend.ListInstances(typeName)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return
	}

	util.LogHandlerExitWithJSON(handler, w, instances, http.StatusOK)
}
func getCredentialHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: get credential"
	util.LogHandlerEntry(handler, r)
	credentialName, err := getPathVariable(w, r, "credential", handler)
	if err != nil {
		return
	}

	c, err := backend.GetCredential(credentialName)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return
	}

	util.LogHandlerExitWithJSON(handler, w, c, http.StatusOK)
}
func getCredential(w http.ResponseWriter, r *http.Request, handler string) *common.RegistryCredential {
	util.LogHandlerEntry(handler, r)
	j, err := getJsonFromRequest(w, r, handler)
	if err != nil {
		return nil
	}

	t := &common.RegistryCredential{}
	if err := json.Unmarshal(j, t); err != nil {
		e := fmt.Errorf("%v\n%v", err, string(j))
		util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
		return nil
	}

	return t
}
func getRegistryHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: get registry"
	util.LogHandlerEntry(handler, r)
	registryName, err := getPathVariable(w, r, "registry", handler)
	if err != nil {
		return
	}

	cr, err := backend.GetRegistry(registryName)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return
	}

	util.LogHandlerExitWithJSON(handler, w, cr, http.StatusOK)
}
func putConfigurationHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "resourcifier: update configuration"
	util.LogHandlerEntry(handler, r)
	defer r.Body.Close()
	c := getConfiguration(w, r, handler)
	if c != nil {
		if _, err := backend.Configure(c, configurator.ReplaceOperation); err != nil {
			e := errors.New("cannot replace configuration: " + err.Error() + "\n")
			util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
			return
		}

		util.LogHandlerExitWithYAML(handler, w, c, http.StatusCreated)
		return
	}

	util.LogHandlerExit(handler, http.StatusOK, "OK", w)
}
func createConfigurationHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "resourcifier: create configuration"
	util.LogHandlerEntry(handler, r)
	defer r.Body.Close()
	c := getConfiguration(w, r, handler)
	if c != nil {
		_, err := backend.Configure(c, configurator.CreateOperation)
		if err != nil {
			util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
			return
		}

		util.LogHandlerExitWithYAML(handler, w, c, http.StatusCreated)
		return
	}

	util.LogHandlerExit(handler, http.StatusOK, "OK", w)
}
func deleteConfigurationHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "resourcifier: delete configuration"
	util.LogHandlerEntry(handler, r)
	defer r.Body.Close()
	c := getConfiguration(w, r, handler)
	if c != nil {
		if _, err := backend.Configure(c, configurator.DeleteOperation); err != nil {
			e := errors.New("cannot delete configuration: " + err.Error() + "\n")
			util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
			return
		}

		w.WriteHeader(http.StatusNoContent)
		util.LogHandlerExit(handler, http.StatusNoContent, "No Content", w)
		return
	}

	util.LogHandlerExit(handler, http.StatusOK, "OK", w)
}
func putDeploymentHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: update deployment"
	util.LogHandlerEntry(handler, r)
	defer r.Body.Close()
	name, err := getPathVariable(w, r, "deployment", handler)
	if err != nil {
		return
	}

	t := getTemplate(w, r, handler)
	if t != nil {
		d, err := backend.PutDeployment(name, t)
		if err != nil {
			util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
			return
		}

		util.LogHandlerExitWithJSON(handler, w, d, http.StatusCreated)
	}
}
func createCredentialHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: create credential"
	util.LogHandlerEntry(handler, r)
	defer r.Body.Close()
	credentialName, err := getPathVariable(w, r, "credential", handler)
	if err != nil {
		return
	}

	c := getCredential(w, r, handler)
	if c != nil {
		err = backend.CreateCredential(credentialName, c)
		if err != nil {
			util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
			return
		}
	}

	util.LogHandlerExitWithJSON(handler, w, c, http.StatusOK)
}
func getFileHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: get file"
	util.LogHandlerEntry(handler, r)
	registryName, err := getPathVariable(w, r, "registry", handler)
	if err != nil {
		return
	}

	file := r.FormValue("file")
	if file == "" {
		return
	}

	b, err := backend.GetFile(registryName, file)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
		return
	}

	util.LogHandlerExitWithJSON(handler, w, b, http.StatusOK)
}
func listManifestsHandlerFunc(w http.ResponseWriter, r *http.Request) {
	handler := "manager: list manifests"
	util.LogHandlerEntry(handler, r)
	deploymentName, err := getPathVariable(w, r, "deployment", handler)
	if err != nil {
		return
	}

	m, err := backend.ListManifests(deploymentName)
	if err != nil {
		util.LogAndReturnError(handler, http.StatusInternalServerError, err, w)
		return
	}

	var manifestNames []string
	for _, manifest := range m {
		manifestNames = append(manifestNames, manifest.Name)
	}

	util.LogHandlerExitWithJSON(handler, w, manifestNames, http.StatusOK)
}