func (c *Client) ProvisionResource(ctx context.Context, cbID manifold.ID,
	model ResourceBody) (string, bool, error) {
	body := models.ResourceRequest{
		ID:         model.ID,
		Product:    manifold.Label(model.Product),
		Plan:       manifold.Label(model.Plan),
		Region:     models.RegionSlug(model.Region),
		Features:   model.Features,
		PlatformID: model.PlatformID,
	}
	cbURL, err := deriveCallbackURL(c.connectorURL, cbID)
	if err != nil {
		c.log.WithError(err).Error("Could not derive callback url")
		return "", false, err
	}
	p := resource.NewPutResourcesIDParams().WithBody(&body).WithID(model.ID.String())
	p.SetXCallbackID(cbID.String())
	p.SetXCallbackURL(cbURL)
	p.SetContext(ctx)
	c.log.WithFields(logrus.Fields{
		"url":          c.url,
		"callback_url": cbURL,
		"resource_id":  model.ID,
		"platform_id":  model.PlatformID,
		"product":      model.Product,
		"plan":         model.Plan,
		"region":       model.Region,
	}).Info("Sending PUT resource/{id} request to provider")
	res, acceptedRes, noContent, err := c.api.Resource.PutResourcesID(p)
	if err != nil {
		var graftonErr error
		statusCode := 0
		switch e := err.(type) {
		case *resource.PutResourcesIDBadRequest:
			statusCode = 400
			graftonErr = NewErrWithMsg(merrors.BadRequestError, e.Payload.Message)
		case *resource.PutResourcesIDUnauthorized:
			statusCode = 401
			graftonErr = NewErrWithMsg(merrors.UnauthorizedError, e.Payload.Message)
		case *resource.PutResourcesIDConflict:
			statusCode = 402
			graftonErr = NewErrWithMsg(merrors.ConflictError, e.Payload.Message)
		case *resource.PutResourcesIDInternalServerError:
			statusCode = 500
			graftonErr = NewErrWithMsg(merrors.InternalServerError, e.Payload.Message)
		default:
			c.log.WithError(err).Info("Error unrecognized, returning directly")
			return "", false, err
		}
		c.log.WithError(graftonErr).WithFields(logrus.Fields{
			"status_code":  statusCode,
			"callback_url": cbURL,
		}).Error("Received an error from provider")
		return graftonErr.Error(), false, graftonErr
	}
	var msgPtr *string
	callback := false
	switch {
	case res != nil:
		c.log.WithField("status_code", 201).Info("Received response from provider")
		msgPtr = res.Payload.Message
	case acceptedRes != nil:
		c.log.WithFields(logrus.Fields{
			"status_code":  202,
			"callback_url": cbURL,
		}).Info("Received response from provider, will be awaiting a callback")
		callback = true
		msgPtr = acceptedRes.Payload.Message
	case noContent != nil:
		c.log.WithField("status_code", 204).Info("Received response from provider, no content")
		return "", false, nil
	}
	if msgPtr == nil {
		c.log.Error("Received no message from the provider and the response was not a 204. Failing due to missing message.")
		return "", false, ErrMissingMsg
	}
	return *msgPtr, callback, nil
}
ProvisionResource makes a resource provisioning call.

A message will be returned if a callback was used *or* a provider returned
an error with an explanation.
package grafton
import (
	"context"
	"io/ioutil"
	nurl "net/url"
	"path"
	"time"
	httptransport "github.com/go-openapi/runtime/client"
	"github.com/go-openapi/strfmt"
	"github.com/sirupsen/logrus"
	"github.com/manifoldco/go-manifold"
	merrors "github.com/manifoldco/go-manifold/errors"
	"github.com/manifoldco/grafton/generated/provider/client"
	"github.com/manifoldco/grafton/generated/provider/client/credential"
	"github.com/manifoldco/grafton/generated/provider/client/resource"
	"github.com/manifoldco/grafton/generated/provider/models"
)
var nullLogger *logrus.Logger
func init() {
	nullLogger = logrus.New()
	nullLogger.Out = ioutil.Discard
}
type Client struct {
	url          *nurl.URL
	connectorURL *nurl.URL
	api          *client.ManifoldProvider
	log          *logrus.Entry
}
type ResourceBody struct {
	ID         manifold.ID
	Product    string
	Plan       string
	Region     string
	ImportCode string
	Features   map[string]interface{}
	PlatformID *manifold.ID
}
func New(url *nurl.URL, connectorURL *nurl.URL, signer Signer, log *logrus.Entry) *Client {
	opt := ClientOptions{
		URL:          url,
		ConnectorURL: connectorURL,
		Signer:       signer,
		Log:          log,
	}
	return NewClient(opt)
}
type ClientOptions struct {
	URL          *nurl.URL
	ConnectorURL *nurl.URL
	Debug        bool
	Signer       Signer
	Log          *logrus.Entry
}
func NewClient(opt ClientOptions) *Client {
	tp := httptransport.New(opt.URL.Host, opt.URL.Path, []string{opt.URL.Scheme})
	if opt.Debug {
		debug := newDebugRoundTripper(tp.Transport)
		signing := newSigningRoundTripper(debug, opt.Signer)
		tp.Transport = signing
	} else {
		signing := newSigningRoundTripper(tp.Transport, opt.Signer)
		tp.Transport = signing
	}
	api := client.New(tp, strfmt.Default)
	if opt.Log == nil {
		opt.Log = logrus.NewEntry(nullLogger)
	}
	return &Client{
		url:          opt.URL,
		api:          api,
		connectorURL: opt.ConnectorURL,
		log:          opt.Log,
	}
}