-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add DependOn, DeletionPolicy and others to CustomResource #350
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,103 @@ | ||
package cloudformation | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/awslabs/goformation/v4/cloudformation/policies" | ||
) | ||
|
||
// See: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html | ||
// CustomResource AWS CloudFormation Resource (AWS::CloudFormation::CustomResource) | ||
// See: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html | ||
type CustomResource struct { | ||
Type string `json:"Type,omitempty"` | ||
Properties map[string]interface{} `json:"Properties,omitempty"` | ||
|
||
// _deletionPolicy represents a CloudFormation DeletionPolicy | ||
_deletionPolicy policies.DeletionPolicy | ||
// AWSCloudFormationDeletionPolicy represents a CloudFormation DeletionPolicy | ||
AWSCloudFormationDeletionPolicy policies.DeletionPolicy `json:"-"` | ||
|
||
// _dependsOn stores the logical ID of the resources to be created before this resource | ||
_dependsOn []string | ||
// AWSCloudFormationUpdateReplacePolicy represents a CloudFormation UpdateReplacePolicy | ||
AWSCloudFormationUpdateReplacePolicy policies.UpdateReplacePolicy `json:"-"` | ||
|
||
// _metadata stores structured data associated with this resource | ||
_metadata map[string]interface{} | ||
// AWSCloudFormationDependsOn stores the logical ID of the resources to be created before this resource | ||
AWSCloudFormationDependsOn []string `json:"-"` | ||
|
||
// AWSCloudFormationMetadata stores structured data associated with this resource | ||
AWSCloudFormationMetadata map[string]interface{} `json:"-"` | ||
|
||
// AWSCloudFormationCondition stores the logical ID of the condition that must be satisfied for this resource to be created | ||
AWSCloudFormationCondition string `json:"-"` | ||
} | ||
|
||
// AWSCloudFormationType returns the AWS CloudFormation resource type | ||
func (r *CustomResource) AWSCloudFormationType() string { | ||
return r.Type | ||
} | ||
|
||
// DependsOn returns a slice of logical ID names this resource depends on. | ||
// see: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html | ||
func (r *CustomResource) DependsOn() []string { | ||
return r._dependsOn | ||
// MarshalJSON is a custom JSON marshalling hook that embeds this object into | ||
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'. | ||
func (r CustomResource) MarshalJSON() ([]byte, error) { | ||
return json.Marshal(&struct { | ||
Type string | ||
Properties interface{} | ||
DependsOn []string `json:"DependsOn,omitempty"` | ||
Metadata map[string]interface{} `json:"Metadata,omitempty"` | ||
DeletionPolicy policies.DeletionPolicy `json:"DeletionPolicy,omitempty"` | ||
UpdateReplacePolicy policies.UpdateReplacePolicy `json:"UpdateReplacePolicy,omitempty"` | ||
Condition string `json:"Condition,omitempty"` | ||
}{ | ||
Type: r.AWSCloudFormationType(), | ||
Properties: (map[string]interface{})(r.Properties), | ||
DependsOn: r.AWSCloudFormationDependsOn, | ||
Metadata: r.AWSCloudFormationMetadata, | ||
DeletionPolicy: r.AWSCloudFormationDeletionPolicy, | ||
UpdateReplacePolicy: r.AWSCloudFormationUpdateReplacePolicy, | ||
Condition: r.AWSCloudFormationCondition, | ||
}) | ||
} | ||
|
||
// SetDependsOn specify that the creation of this resource follows another. | ||
// see: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html | ||
func (r *CustomResource) SetDependsOn(dependencies []string) { | ||
r._dependsOn = dependencies | ||
} | ||
// UnmarshalJSON is a custom JSON unmarshalling hook that strips the outer | ||
// AWS CloudFormation resource object, and just keeps the 'Properties' field. | ||
func (r *CustomResource) UnmarshalJSON(b []byte) error { | ||
res := &struct { | ||
Type string | ||
Properties map[string]interface{} | ||
DependsOn []string | ||
Metadata map[string]interface{} | ||
DeletionPolicy string | ||
UpdateReplacePolicy string | ||
Condition string | ||
}{} | ||
|
||
// Metadata returns the metadata associated with this resource. | ||
// see: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-metadata.html | ||
func (r *CustomResource) Metadata() map[string]interface{} { | ||
return r._metadata | ||
} | ||
dec := json.NewDecoder(bytes.NewReader(b)) | ||
dec.DisallowUnknownFields() // Force error if unknown field is found | ||
|
||
// SetMetadata enables you to associate structured data with this resource. | ||
// see: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-metadata.html | ||
func (r *CustomResource) SetMetadata(metadata map[string]interface{}) { | ||
r._metadata = metadata | ||
} | ||
if err := dec.Decode(&res); err != nil { | ||
fmt.Printf("ERROR: %s\n", err) | ||
return err | ||
} | ||
|
||
// DeletionPolicy returns the AWS CloudFormation DeletionPolicy to this resource | ||
// see: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html | ||
func (r *CustomResource) DeletionPolicy() policies.DeletionPolicy { | ||
return r._deletionPolicy | ||
} | ||
r.Type = res.Type | ||
|
||
// SetDeletionPolicy applies an AWS CloudFormation DeletionPolicy to this resource | ||
// see: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html | ||
func (r *CustomResource) SetDeletionPolicy(policy policies.DeletionPolicy) { | ||
r._deletionPolicy = policy | ||
} | ||
|
||
// GetAllCustomResourceResources retrieves all CustomResource items from an AWS CloudFormation template | ||
func (t *Template) GetAllCustomResources() map[string]*CustomResource { | ||
results := map[string]*CustomResource{} | ||
for name, untyped := range t.Resources { | ||
switch resource := untyped.(type) { | ||
case *CustomResource: | ||
results[name] = resource | ||
} | ||
// If the resource has no Properties set, it could be nil | ||
if res.Properties != nil { | ||
r.Properties = res.Properties | ||
} | ||
return results | ||
} | ||
|
||
// GetCustomResourceWithName retrieves all CustomResource items from an AWS CloudFormation template | ||
// whose logical ID matches the provided name. Returns an error if not found. | ||
func (t *Template) GetCustomResourceWithName(name string) (*CustomResource, error) { | ||
if untyped, ok := t.Resources[name]; ok { | ||
switch resource := untyped.(type) { | ||
case *CustomResource: | ||
return resource, nil | ||
} | ||
if res.DependsOn != nil { | ||
r.AWSCloudFormationDependsOn = res.DependsOn | ||
} | ||
if res.Metadata != nil { | ||
r.AWSCloudFormationMetadata = res.Metadata | ||
} | ||
if res.DeletionPolicy != "" { | ||
r.AWSCloudFormationDeletionPolicy = policies.DeletionPolicy(res.DeletionPolicy) | ||
} | ||
if res.UpdateReplacePolicy != "" { | ||
r.AWSCloudFormationUpdateReplacePolicy = policies.UpdateReplacePolicy(res.UpdateReplacePolicy) | ||
} | ||
if res.Condition != "" { | ||
r.AWSCloudFormationCondition = res.Condition | ||
} | ||
return nil, fmt.Errorf("resource %q of type CustomResource not found", name) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reason for removing this test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 reasons
GetAllCustomResources()
function seems that it do not make bigger sense to have it - then implementation of a resource is not necessarily different that othersresources, ok := result["Resources"].(map[string]interface{})
Expect(ok).To(BeTrue())
Expect(resources).To(HaveLen(1))
Expect(resources).To(HaveKey("MyCustomResource"))
Which is in my opinion almost the same test but without - template.GetAllCustomResources() - this is why I think we can remove that part of the test
I think the rest of the test is fair enough for CoustomResource check