summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/goamz/goamz/cloudformation/cloudformation.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goamz/goamz/cloudformation/cloudformation.go')
-rw-r--r--vendor/github.com/goamz/goamz/cloudformation/cloudformation.go837
1 files changed, 837 insertions, 0 deletions
diff --git a/vendor/github.com/goamz/goamz/cloudformation/cloudformation.go b/vendor/github.com/goamz/goamz/cloudformation/cloudformation.go
new file mode 100644
index 000000000..00081d0c2
--- /dev/null
+++ b/vendor/github.com/goamz/goamz/cloudformation/cloudformation.go
@@ -0,0 +1,837 @@
+//
+// cloudformation: This package provides types and functions to interact with the AWS CloudFormation API
+//
+// Depends on https://github.com/goamz/goamz
+//
+
+package cloudformation
+
+import (
+ "encoding/xml"
+ "fmt"
+ "log"
+ "net/http"
+ "net/http/httputil"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/goamz/goamz/aws"
+)
+
+// The CloudFormation type encapsulates operations within a specific EC2 region.
+type CloudFormation struct {
+ aws.Auth
+ aws.Region
+}
+
+// New creates a new CloudFormation Client.
+func New(auth aws.Auth, region aws.Region) *CloudFormation {
+
+ return &CloudFormation{auth, region}
+
+}
+
+const debug = false
+
+// ----------------------------------------------------------------------------
+// Request dispatching logic.
+
+// Error encapsulates an error returned by the AWS CloudFormation API.
+//
+// See http://goo.gl/zDZbuQ for more details.
+type Error struct {
+ // HTTP status code (200, 403, ...)
+ StatusCode int
+ // Error type
+ Type string `xml:"Type"`
+ // CloudFormation error code
+ Code string `xml:"Code"`
+ // The human-oriented error message
+ Message string `xml:"Message"`
+ RequestId string `xml:"RequestID"`
+}
+
+func (err *Error) Error() string {
+ if err.Code == "" {
+ return err.Message
+ }
+
+ return fmt.Sprintf("%s (%s)", err.Message, err.Code)
+}
+
+type xmlErrors struct {
+ RequestId string `xml:"RequestId"`
+ Errors []Error `xml:"Error"`
+}
+
+func (c *CloudFormation) query(params map[string]string, resp interface{}) error {
+ params["Version"] = "2010-05-15"
+
+ data := strings.NewReader(multimap(params).Encode())
+
+ hreq, err := http.NewRequest("POST", c.Region.CloudFormationEndpoint+"/", data)
+ if err != nil {
+ return err
+ }
+
+ hreq.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
+
+ token := c.Auth.Token()
+ if token != "" {
+ hreq.Header.Set("X-Amz-Security-Token", token)
+ }
+
+ signer := aws.NewV4Signer(c.Auth, "cloudformation", c.Region)
+ signer.Sign(hreq)
+
+ if debug {
+ log.Printf("%v -> {\n", hreq)
+ }
+ r, err := http.DefaultClient.Do(hreq)
+
+ if err != nil {
+ log.Printf("Error calling Amazon")
+ return err
+ }
+
+ defer r.Body.Close()
+
+ if debug {
+ dump, _ := httputil.DumpResponse(r, true)
+ log.Printf("response:\n")
+ log.Printf("%v\n}\n", string(dump))
+ }
+ if r.StatusCode != 200 {
+ return buildError(r)
+ }
+ err = xml.NewDecoder(r.Body).Decode(resp)
+ return err
+}
+
+func buildError(r *http.Response) error {
+ var (
+ err Error
+ errors xmlErrors
+ )
+ xml.NewDecoder(r.Body).Decode(&errors)
+ if len(errors.Errors) > 0 {
+ err = errors.Errors[0]
+ }
+
+ err.RequestId = errors.RequestId
+ err.StatusCode = r.StatusCode
+ if err.Message == "" {
+ err.Message = r.Status
+ }
+ return &err
+}
+
+func makeParams(action string) map[string]string {
+ params := make(map[string]string)
+ params["Action"] = action
+ return params
+}
+
+func multimap(p map[string]string) url.Values {
+ q := make(url.Values, len(p))
+ for k, v := range p {
+ q[k] = []string{v}
+ }
+ return q
+}
+
+// addParamsList adds params in the form of param.member.N to the params map
+func addParamsList(params map[string]string, label string, ids []string) {
+ for i, id := range ids {
+ params[label+"."+strconv.Itoa(i+1)] = id
+ }
+}
+
+// -----------------------------------------------------------------------
+// API Supported Types and Methods
+
+// SimpleResp is the basic response from most actions.
+type SimpleResp struct {
+ XMLName xml.Name
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// CancelUpdateStack cancels an update on the specified stack.
+// If the call completes successfully, the stack will roll back the update and revert
+// to the previous stack configuration.
+//
+// See http://goo.gl/ZE6fOa for more details
+func (c *CloudFormation) CancelUpdateStack(stackName string) (resp *SimpleResp, err error) {
+ params := makeParams("CancelUpdateStack")
+
+ params["StackName"] = stackName
+
+ resp = new(SimpleResp)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// Parameter encapsulates the cloudstack paramter data type
+//
+// See http://goo.gl/2rg9eG for more details
+type Parameter struct {
+ ParameterKey string `xml:"ParameterKey"`
+ ParameterValue string `xml:"ParameterValue"`
+ UsePreviousValue bool `xml:"UsePreviousValue"`
+}
+
+type Tag struct {
+ Key string `xml:"Key"`
+ Value string `xml:"Value"`
+}
+
+// CreateStackParams wraps CreateStack request options
+//
+// See http://goo.gl/yDZYuV for more information
+type CreateStackParams struct {
+ Capabilities []string
+ DisableRollback bool
+ NotificationARNs []string
+ OnFailure string
+ Parameters []Parameter
+ StackName string
+ StackPolicyBody string
+ StackPolicyURL string
+ Tags []Tag
+ TemplateBody string
+ TemplateURL string
+ TimeoutInMinutes int
+}
+
+// CreateStackResponse wraps a CreateStack call response
+//
+// See http://goo.gl/yDZYuV for more details
+type CreateStackResponse struct {
+ StackId string `xml:"CreateStackResult>StackId"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// CreateStack creates a stack as specified in the template. After the call completes successfully,
+// the stack creation starts.
+//
+// Required params: StackName
+//
+// See http://goo.gl/yDZYuV for more details
+func (c *CloudFormation) CreateStack(options *CreateStackParams) (
+ resp *CreateStackResponse, err error) {
+ params := makeParams("CreateStack")
+
+ params["StackName"] = options.StackName
+
+ if options.DisableRollback {
+ params["DisableRollback"] = strconv.FormatBool(options.DisableRollback)
+ }
+ if options.OnFailure != "" {
+ params["OnFailure"] = options.OnFailure
+ }
+ if options.StackPolicyBody != "" {
+ params["StackPolicyBody"] = options.StackPolicyBody
+ }
+ if options.StackPolicyURL != "" {
+ params["StackPolicyURL"] = options.StackPolicyURL
+ }
+ if options.TemplateBody != "" {
+ params["TemplateBody"] = options.TemplateBody
+ }
+ if options.TemplateURL != "" {
+ params["TemplateURL"] = options.TemplateURL
+ }
+ if options.TimeoutInMinutes != 0 {
+ params["TimeoutInMinutes"] = strconv.Itoa(options.TimeoutInMinutes)
+ }
+ if len(options.Capabilities) > 0 {
+ addParamsList(params, "Capabilities.member", options.Capabilities)
+ }
+ if len(options.NotificationARNs) > 0 {
+ addParamsList(params, "NotificationARNs.member", options.NotificationARNs)
+ }
+ // Add any parameters
+ for i, t := range options.Parameters {
+ key := "Parameters.member.%d.%s"
+ index := i + 1
+ params[fmt.Sprintf(key, index, "ParameterKey")] = t.ParameterKey
+ params[fmt.Sprintf(key, index, "ParameterValue")] = t.ParameterValue
+ params[fmt.Sprintf(key, index, "UsePreviousValue")] = strconv.FormatBool(t.UsePreviousValue)
+ }
+ // Add any tags
+ for i, t := range options.Tags {
+ key := "Tags.member.%d.%s"
+ index := i + 1
+ params[fmt.Sprintf(key, index, "Key")] = t.Key
+ params[fmt.Sprintf(key, index, "Value")] = t.Value
+ }
+
+ resp = new(CreateStackResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// DeleteStack deletes a specified stack.
+// Once the call completes successfully, stack deletion starts.
+//
+// See http://goo.gl/CVMpxC for more details
+func (c *CloudFormation) DeleteStack(stackName string) (resp *SimpleResp, err error) {
+ params := makeParams("DeleteStack")
+
+ params["StackName"] = stackName
+
+ resp = new(SimpleResp)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// StackEvent encapsulates the StackEvent data type
+//
+// See http://goo.gl/EHwiMf for more details
+type StackEvent struct {
+ EventId string `xml:"EventId"`
+ LogicalResourceId string `xml:"LogicalResourceId"`
+ PhysicalResourceId string `xml:"PhysicalResourceId"`
+ ResourceProperties string `xml:"ResourceProperties"`
+ ResourceStatus string `xml:"ResourceStatus"`
+ ResourceStatusReason string `xml:"ResourceStatusReason"`
+ ResourceType string `xml:"ResourceType"`
+ StackId string `xml:"StackId"`
+ StackName string `xml:"StackName"`
+ Timestamp time.Time `xml:"Timestamp"`
+}
+
+// DescribeStackEventsResponse wraps a response returned by DescribeStackEvents request
+//
+// See http://goo.gl/zqj4Bz for more details
+type DescribeStackEventsResponse struct {
+ NextToken string `xml:"DescribeStackEventsResult>NextToken"`
+ StackEvents []StackEvent `xml:"DescribeStackEventsResult>StackEvents>member"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// DescribeStackEvents returns all stack related events for a specified stack.
+//
+// See http://goo.gl/zqj4Bz for more details
+func (c *CloudFormation) DescribeStackEvents(stackName string, nextToken string) (
+ resp *DescribeStackEventsResponse, err error) {
+ params := makeParams("DescribeStackEvents")
+
+ if stackName != "" {
+ params["StackName"] = stackName
+ }
+ if nextToken != "" {
+ params["NextToken"] = nextToken
+ }
+
+ resp = new(DescribeStackEventsResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// StackResourceDetail encapsulates the StackResourceDetail data type
+//
+// See http://goo.gl/flce6I for more details
+type StackResourceDetail struct {
+ Description string `xml:"Description"`
+ LastUpdatedTimestamp time.Time `xml:"LastUpdatedTimestamp"`
+ LogicalResourceId string `xml:"LogicalResourceId"`
+ Metadata string `xml:"Metadata"`
+ PhysicalResourceId string `xml:"PhysicalResourceId"`
+ ResourceStatus string `xml:"ResourceStatus"`
+ ResourceStatusReason string `xml:"ResourceStatusReason"`
+ ResourceType string `xml:"ResourceType"`
+ StackId string `xml:"StackId"`
+ StackName string `xml:"StackName"`
+}
+
+// DescribeStackResourceResponse wraps a response returned by DescribeStackResource request
+//
+// See http://goo.gl/6pfPFs for more details
+type DescribeStackResourceResponse struct {
+ StackResourceDetail StackResourceDetail `xml:"DescribeStackResourceResult>StackResourceDetail"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// DescribeStackResource returns a description of the specified resource in the specified stack.
+// For deleted stacks, DescribeStackResource returns resource information
+// for up to 90 days after the stack has been deleted.
+//
+// Required params: stackName, logicalResourceId
+//
+// See http://goo.gl/6pfPFs for more details
+func (c *CloudFormation) DescribeStackResource(stackName string, logicalResourceId string) (
+ resp *DescribeStackResourceResponse, err error) {
+ params := makeParams("DescribeStackResource")
+
+ params["StackName"] = stackName
+ params["LogicalResourceId"] = logicalResourceId
+
+ resp = new(DescribeStackResourceResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// StackResource encapsulates the StackResource data type
+//
+// See http://goo.gl/j4eli5 for more details
+type StackResource struct {
+ Description string `xml:"Description"`
+ LogicalResourceId string `xml:"LogicalResourceId"`
+ PhysicalResourceId string `xml:"PhysicalResourceId"`
+ ResourceStatus string `xml:"ResourceStatus"`
+ ResourceStatusReason string `xml:"ResourceStatusReason"`
+ ResourceType string `xml:"ResourceType"`
+ StackId string `xml:"StackId"`
+ StackName string `xml:"StackName"`
+ Timestamp time.Time `xml:"Timestamp"`
+}
+
+// DescribeStackResourcesResponse wraps a response returned by DescribeStackResources request
+//
+// See http://goo.gl/YnY5rs for more details
+type DescribeStackResourcesResponse struct {
+ StackResources []StackResource `xml:"DescribeStackResourcesResult>StackResources>member"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// DescribeStackResources returns AWS resource descriptions for running and deleted stacks.
+// If stackName is specified, all the associated resources that are part of the stack are returned.
+// If physicalResourceId is specified, the associated resources of the stack that the resource
+// belongs to are returned.
+//
+// Only the first 100 resources will be returned. If your stack has more resources than this,
+// you should use ListStackResources instead.
+//
+// See http://goo.gl/YnY5rs for more details
+func (c *CloudFormation) DescribeStackResources(stackName, physicalResourceId, logicalResourceId string) (
+ resp *DescribeStackResourcesResponse, err error) {
+ params := makeParams("DescribeStackResources")
+
+ if stackName != "" {
+ params["StackName"] = stackName
+ }
+ if physicalResourceId != "" {
+ params["PhysicalResourceId"] = physicalResourceId
+ }
+ if logicalResourceId != "" {
+ params["LogicalResourceId"] = logicalResourceId
+ }
+
+ resp = new(DescribeStackResourcesResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// Output encapsulates the Output AWS data type
+//
+// See http://goo.gl/UOn7q6 for more information
+type Output struct {
+ Description string `xml:"Description"`
+ OutputKey string `xml:"OutputKey"`
+ OutputValue string `xml:"OutputValue"`
+}
+
+// Stack encapsulates the Stack AWS data type
+//
+// See http://goo.gl/yDZYuV for more information
+type Stack struct {
+ Capabilities []string `xml:"Capabilities>member"`
+ CreationTime time.Time `xml:"CreationTime"`
+ Description string `xml:"Description"`
+ DisableRollback bool `xml:"DisableRollback"`
+ LastUpdatedTime time.Time `xml:"LastUpdatedTime"`
+ NotificationARNs []string `xml:"NotificationARNs>member"`
+ Outputs []Output `xml:"Outputs>member"`
+ Parameters []Parameter `xml:"Parameters>member"`
+ StackId string `xml:"StackId"`
+ StackName string `xml:"StackName"`
+ StackStatus string `xml:"StackStatus"`
+ StackStatusReason string `xml:"StackStatusReason"`
+ Tags []Tag `xml:"Tags>member"`
+ TimeoutInMinutes int `xml:"TimeoutInMinutes"`
+}
+
+// DescribeStacksResponse wraps a response returned by DescribeStacks request
+//
+// See http://goo.gl/UOLsXD for more information
+type DescribeStacksResponse struct {
+ NextToken string `xml:"DescribeStacksResult>NextToken"`
+ Stacks []Stack `xml:"DescribeStacksResult>Stacks>member"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// DescribeStacks returns the description for the specified stack;
+// If no stack name was specified, then it returns the description for all the stacks created.
+//
+// See http://goo.gl/UOLsXD for more information
+func (c *CloudFormation) DescribeStacks(stackName string, nextToken string) (
+ resp *DescribeStacksResponse, err error) {
+ params := makeParams("DescribeStacks")
+
+ if stackName != "" {
+ params["StackName"] = stackName
+ }
+ if nextToken != "" {
+ params["NextToken"] = nextToken
+ }
+
+ resp = new(DescribeStacksResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// EstimateTemplateCostResponse wraps a response returned by EstimateTemplateCost request
+//
+// See http://goo.gl/PD9hle for more information
+type EstimateTemplateCostResponse struct {
+ Url string `xml:"EstimateTemplateCostResult>Url"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// EstimateTemplateCost returns the estimated monthly cost of a template.
+// The return value is an AWS Simple Monthly Calculator URL with a query string that describes
+// the resources required to run the template.
+//
+// See http://goo.gl/PD9hle for more information
+func (c *CloudFormation) EstimateTemplateCost(parameters []Parameter, templateBody, templateUrl string) (
+ resp *EstimateTemplateCostResponse, err error) {
+ params := makeParams("EstimateTemplateCost")
+
+ if templateBody != "" {
+ params["TemplateBody"] = templateBody
+ }
+ if templateUrl != "" {
+ params["TemplateURL"] = templateUrl
+ }
+ // Add any parameters
+ for i, t := range parameters {
+ key := "Parameters.member.%d.%s"
+ index := i + 1
+ params[fmt.Sprintf(key, index, "ParameterKey")] = t.ParameterKey
+ params[fmt.Sprintf(key, index, "ParameterValue")] = t.ParameterValue
+ params[fmt.Sprintf(key, index, "UsePreviousValue")] = strconv.FormatBool(t.UsePreviousValue)
+ }
+
+ resp = new(EstimateTemplateCostResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// GetStackPolicyResponse wraps a response returned by GetStackPolicy request
+//
+// See http://goo.gl/iZFSgy for more information
+type GetStackPolicyResponse struct {
+ StackPolicyBody string `xml:"GetStackPolicyResult>StackPolicyBody"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// GetStackPolicy returns the stack policy for a specified stack. If a stack doesn't have a policy,
+// a null value is returned.
+//
+// See http://goo.gl/iZFSgy for more information
+func (c *CloudFormation) GetStackPolicy(stackName string) (
+ resp *GetStackPolicyResponse, err error) {
+ params := makeParams("GetStackPolicy")
+
+ params["StackName"] = stackName
+
+ resp = new(GetStackPolicyResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// GetTemplateResponse wraps a response returned by GetTemplate request
+//
+// See http://goo.gl/GU59CB for more information
+type GetTemplateResponse struct {
+ TemplateBody string `xml:"GetTemplateResult>TemplateBody"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// GetTemplate returns the template body for a specified stack.
+// You can get the template for running or deleted stacks
+//
+// Required Params: StackName - The name or the unique identifier associated with the stack,
+// which are not always interchangeable:
+// Running stacks: You can specify either the stack's name or its unique stack ID.
+// Deleted stacks: You must specify the unique stack ID.
+//
+// See http://goo.gl/GU59CB for more information
+func (c *CloudFormation) GetTemplate(stackName string) (
+ resp *GetTemplateResponse, err error) {
+ params := makeParams("GetTemplate")
+
+ params["StackName"] = stackName
+
+ resp = new(GetTemplateResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// StackResourceSummary encapsulates the StackResourceSummary data type
+//
+// See http://goo.gl/Af0vcm for more details
+type StackResourceSummary struct {
+ LastUpdatedTimestamp time.Time `xml:"LastUpdatedTimestamp"`
+ LogicalResourceId string `xml:"LogicalResourceId"`
+ PhysicalResourceId string `xml:"PhysicalResourceId"`
+ ResourceStatus string `xml:"ResourceStatus"`
+ ResourceStatusReason string `xml:"ResourceStatusReason"`
+ ResourceType string `xml:"ResourceType"`
+}
+
+// ListStackResourcesResponse wraps a response returned by ListStackResources request
+//
+// See http://goo.gl/JUCgLf for more details
+type ListStackResourcesResponse struct {
+ NextToken string `xml:"ListStackResourcesResult>NextToken"`
+ StackResourceSummaries []StackResourceSummary `xml:"ListStackResourcesResult>StackResourceSummaries>member"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// ListStackResources returns descriptions of all resources of the specified stack.
+// For deleted stacks, ListStackResources returns resource information for up to 90 days
+// after the stack has been deleted.
+//
+// Required Params: stackName - the name or the unique identifier associated with the stack,
+// which are not always interchangeable:
+// Running stacks: You can specify either the stack's name or its unique stack ID.
+// Deleted stacks: You must specify the unique stack ID.
+//
+// See http://goo.gl/JUCgLf for more details
+func (c *CloudFormation) ListStackResources(stackName, nextToken string) (
+ resp *ListStackResourcesResponse, err error) {
+ params := makeParams("ListStackResources")
+
+ params["StackName"] = stackName
+
+ if nextToken != "" {
+ params["NextToken"] = nextToken
+ }
+
+ resp = new(ListStackResourcesResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// StackSummary encapsulates the StackSummary data type
+//
+// See http://goo.gl/35j3wf for more details
+type StackSummary struct {
+ CreationTime time.Time `xml:"CreationTime"`
+ DeletionTime time.Time `xml:"DeletionTime"`
+ LastUpdatedTime time.Time `xml:"LastUpdatedTime"`
+ StackId string `xml:"StackId"`
+ StackName string `xml:"StackName"`
+ StackStatus string `xml:"StackStatus"`
+ StackStatusReason string `xml:"StackStatusReason"`
+ TemplateDescription string `xml:"TemplateDescription"`
+}
+
+// ListStacksResponse wraps a response returned by ListStacks request
+//
+// See http://goo.gl/UWi6nm for more details
+type ListStacksResponse struct {
+ NextToken string `xml:"ListStacksResult>NextToken"`
+ StackSummaries []StackSummary `xml:"ListStacksResult>StackSummaries>member"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// ListStacks Returns the summary information for stacks whose status matches the specified StackStatusFilter.
+// Summary information for stacks that have been deleted is kept for 90 days after the stack is deleted.
+// If no StackStatusFilter is specified, summary information for all stacks is returned
+// (including existing stacks and stacks that have been deleted).
+//
+// See http://goo.gl/UWi6nm for more details
+func (c *CloudFormation) ListStacks(stackStatusFilters []string, nextToken string) (
+ resp *ListStacksResponse, err error) {
+ params := makeParams("ListStacks")
+
+ if nextToken != "" {
+ params["NextToken"] = nextToken
+ }
+
+ if len(stackStatusFilters) > 0 {
+ addParamsList(params, "StackStatusFilter.member", stackStatusFilters)
+ }
+
+ resp = new(ListStacksResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// SetStackPolicy sets a stack policy for a specified stack.
+//
+// Required Params: stackName
+//
+// See http://goo.gl/iY9ohu for more information
+func (c *CloudFormation) SetStackPolicy(stackName, stackPolicyBody, stackPolicyUrl string) (
+ resp *SimpleResp, err error) {
+ params := makeParams("SetStackPolicy")
+
+ params["StackName"] = stackName
+
+ if stackPolicyBody != "" {
+ params["StackPolicyBody"] = stackPolicyBody
+ }
+ if stackPolicyUrl != "" {
+ params["StackPolicyURL"] = stackPolicyUrl
+ }
+
+ resp = new(SimpleResp)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// UpdateStackParams wraps UpdateStack request options
+//
+// See http://goo.gl/LvkhZq for more information
+type UpdateStackParams struct {
+ Capabilities []string
+ NotificationARNs []string
+ Parameters []Parameter
+ StackName string
+ StackPolicyBody string
+ StackPolicyDuringUpdateBody string
+ StackPolicyDuringUpdateURL string
+ StackPolicyURL string
+ TemplateBody string
+ TemplateURL string
+ UsePreviousTemplate bool
+}
+
+// UpdateStackResponse wraps the UpdateStack call response
+//
+// See http://goo.gl/LvkhZq for more information
+type UpdateStackResponse struct {
+ StackId string `xml:"UpdateStackResult>StackId"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// UpdateStack updates a stack as specified in the template.
+// After the call completes successfully, the stack update starts.
+// You can check the status of the stack via the DescribeStacks action.
+//
+// Required Params: options.StackName
+//
+// See http://goo.gl/LvkhZq for more information
+func (c *CloudFormation) UpdateStack(options *UpdateStackParams) (
+ resp *UpdateStackResponse, err error) {
+ params := makeParams("UpdateStack")
+
+ params["StackName"] = options.StackName
+
+ if options.StackPolicyBody != "" {
+ params["StackPolicyBody"] = options.StackPolicyBody
+ }
+ if options.StackPolicyDuringUpdateBody != "" {
+ params["StackPolicyDuringUpdateBody"] = options.StackPolicyDuringUpdateBody
+ }
+ if options.StackPolicyDuringUpdateURL != "" {
+ params["StackPolicyDuringUpdateURL"] = options.StackPolicyDuringUpdateURL
+ }
+ if options.StackPolicyURL != "" {
+ params["StackPolicyURL"] = options.StackPolicyURL
+ }
+ if options.TemplateBody != "" {
+ params["TemplateBody"] = options.TemplateBody
+ }
+ if options.TemplateURL != "" {
+ params["TemplateURL"] = options.TemplateURL
+ }
+ if options.UsePreviousTemplate {
+ params["UsePreviousTemplate"] = strconv.FormatBool(options.UsePreviousTemplate)
+ }
+
+ if len(options.Capabilities) > 0 {
+ addParamsList(params, "Capabilities.member", options.Capabilities)
+ }
+ if len(options.NotificationARNs) > 0 {
+ addParamsList(params, "NotificationARNs.member", options.NotificationARNs)
+ }
+ // Add any parameters
+ for i, t := range options.Parameters {
+ key := "Parameters.member.%d.%s"
+ index := i + 1
+ params[fmt.Sprintf(key, index, "ParameterKey")] = t.ParameterKey
+ params[fmt.Sprintf(key, index, "ParameterValue")] = t.ParameterValue
+ params[fmt.Sprintf(key, index, "UsePreviousValue")] = strconv.FormatBool(t.UsePreviousValue)
+ }
+
+ resp = new(UpdateStackResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// TemplateParameter encapsulates the AWS TemplateParameter data type
+//
+// See http://goo.gl/OBhNzk for more information
+type TemplateParameter struct {
+ DefaultValue string `xml:"DefaultValue"`
+ Description string `xml:Description"`
+ NoEcho bool `xml:NoEcho"`
+ ParameterKey string `xml:ParameterKey"`
+}
+
+// ValidateTemplateResponse wraps the ValidateTemplate call response
+//
+// See http://goo.gl/OBhNzk for more information
+type ValidateTemplateResponse struct {
+ Capabilities []string `xml:"ValidateTemplateResult>Capabilities>member"`
+ CapabilitiesReason string `xml:"ValidateTemplateResult>CapabilitiesReason"`
+ Description string `xml:"ValidateTemplateResult>Description"`
+ Parameters []TemplateParameter `xml:"ValidateTemplateResult>Parameters>member"`
+ RequestId string `xml:"ResponseMetadata>RequestId"`
+}
+
+// ValidateTemplate validates a specified template.
+//
+// See http://goo.gl/OBhNzk for more information
+func (c *CloudFormation) ValidateTemplate(templateBody, templateUrl string) (
+ resp *ValidateTemplateResponse, err error) {
+ params := makeParams("ValidateTemplate")
+
+ if templateBody != "" {
+ params["TemplateBody"] = templateBody
+ }
+ if templateUrl != "" {
+ params["TemplateURL"] = templateUrl
+ }
+
+ resp = new(ValidateTemplateResponse)
+ if err := c.query(params, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}