package handler import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/cfnerr" "github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/encoding" ) const ( // marshalingError occurs when we can't marshal data from one format into another. marshalingError = "Marshaling" // bodyEmptyError happens when the resource body is empty bodyEmptyError = "BodyEmpty" ) // Request is passed to actions with customer related data // such as resource states type Request struct { // The logical ID of the resource in the CloudFormation stack LogicalResourceID string // The callback context is an arbitrary datum which the handler can return in an // IN_PROGRESS event to allow the passing through of additional state or // metadata between subsequent retries; for example to pass through a Resource // identifier which can be used to continue polling for stabilization CallbackContext map[string]interface{} // The RequestContext is information about the current // invocation. RequestContext RequestContext // An authenticated AWS session that can be used with the AWS Go SDK Session *session.Session previousResourcePropertiesBody []byte resourcePropertiesBody []byte typeConfigurationBody []byte } // RequestContext represents information about the current // invocation request of the handler. type RequestContext struct { // The stack ID of the CloudFormation stack StackID string // The Region of the requester Region string // The Account ID of the requester AccountID string // The stack tags associated with the cloudformation stack StackTags map[string]string // The SystemTags associated with the request SystemTags map[string]string // The NextToken provided in the request NextToken string } // NewRequest returns a new Request based on the provided parameters func NewRequest(id string, ctx map[string]interface{}, requestCTX RequestContext, sess *session.Session, previousBody, body, typeConfig []byte) Request { return Request{ LogicalResourceID: id, CallbackContext: ctx, Session: sess, previousResourcePropertiesBody: previousBody, resourcePropertiesBody: body, RequestContext: requestCTX, typeConfigurationBody: typeConfig, } } // UnmarshalPrevious populates the provided interface // with the previous properties of the resource func (r *Request) UnmarshalPrevious(v interface{}) cfnerr.Error { if len(r.previousResourcePropertiesBody) == 0 { return nil } if err := encoding.Unmarshal(r.previousResourcePropertiesBody, v); err != nil { return cfnerr.New(marshalingError, "Unable to convert type", err) } return nil } // Unmarshal populates the provided interface // with the current properties of the resource func (r *Request) Unmarshal(v interface{}) cfnerr.Error { if len(r.resourcePropertiesBody) == 0 { return cfnerr.New(bodyEmptyError, "Body is empty", nil) } if err := encoding.Unmarshal(r.resourcePropertiesBody, v); err != nil { return cfnerr.New(marshalingError, "Unable to convert type", err) } return nil } // UnmarshalTypeConfig populates the provided interface // with the current properties of the model func (r *Request) UnmarshalTypeConfig(v interface{}) error { if len(r.typeConfigurationBody) == 0 { return cfnerr.New(bodyEmptyError, "Type Config is empty", nil) } if err := encoding.Unmarshal(r.typeConfigurationBody, v); err != nil { return cfnerr.New(marshalingError, "Unable to convert type", err) } return nil }