forked from crewjam/go-cloudformation
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtemplate.go
171 lines (156 loc) · 6.54 KB
/
template.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package cloudformation
import (
"encoding/json"
"fmt"
)
// NewTemplate returns a new empty Template initialized with some
// default values.
func NewTemplate() *Template {
return &Template{
AWSTemplateFormatVersion: "2010-09-09",
Transform: []string{},
Mappings: map[string]*Mapping{},
Parameters: map[string]*Parameter{},
Resources: map[string]*Resource{},
Outputs: map[string]*Output{},
Conditions: map[string]interface{}{},
Metadata: map[string]interface{}{},
}
}
// Template represents a cloudformation template.
type Template struct {
AWSTemplateFormatVersion string `json:",omitempty"`
Description string `json:",omitempty"`
Metadata map[string]interface{} `json:",omitempty"`
Mappings map[string]*Mapping `json:",omitempty"`
Parameters map[string]*Parameter `json:",omitempty"`
Transform []string `json:",omitempty"`
Resources map[string]*Resource `json:",omitempty"`
Outputs map[string]*Output `json:",omitempty"`
Conditions map[string]interface{} `json:",omitempty"`
}
// AddResource adds the resource to the template as name, displacing
// any resource with the same name that already exists.
func (t *Template) AddResource(name string, resource ResourceProperties) *Resource {
templateResource := &Resource{Properties: resource}
t.Resources[name] = templateResource
return templateResource
}
// Mapping matches a key to a corresponding set of named values. For example,
// if you want to set values based on a region, you can create a mapping that
// uses the region name as a key and contains the values you want to specify
// for each specific region. You use the Fn::FindInMap intrinsic function to
// retrieve values in a map.
//
// See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html
type Mapping map[string]map[string]string
// Parameter represents a parameter to the template.
//
// You can use the optional Parameters section to pass values into your
// template when you create a stack. With parameters, you can create templates
// that are customized each time you create a stack. Each parameter must
// contain a value when you create a stack. You can specify a default value to
// make the parameter optional.
//
// See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html
type Parameter struct {
Type string `json:",omitempty"`
Default string `json:",omitempty"`
NoEcho *BoolExpr `json:",omitempty"`
AllowedValues []string `json:",omitempty"`
AllowedPattern string `json:",omitempty"`
MinLength *IntegerExpr `json:",omitempty"`
MaxLength *IntegerExpr `json:",omitempty"`
MinValue *IntegerExpr `json:",omitempty"`
MaxValue *IntegerExpr `json:",omitempty"`
Description string `json:",omitempty"`
ConstraintDescription string `json:",omitempty"`
}
// OutputExport represents the name of the resource output that should
// be used for cross stack references.
//
// See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/walkthrough-crossstackref.html
type OutputExport struct {
Name Stringable `json:",omitempty"`
}
// Output represents a template output
//
// The optional Outputs section declares output values that you want to view from the
// AWS CloudFormation console or that you want to return in response to describe stack calls.
// For example, you can output the Amazon S3 bucket name for a stack so that you can easily find it.
//
// See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html
type Output struct {
Description string `json:",omitempty"`
Value interface{} `json:",omitempty"`
Export *OutputExport `json:",omitempty"`
}
// ResourceProperties is an interface that is implemented by resource objects.
type ResourceProperties interface {
CfnResourceType() string
CfnResourceAttributes() []string
}
// FnTransform represents the Fn::Transform intrinsic function. See:
// https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-transform.html
// for more information.
type FnTransform struct {
Name *StringExpr `json:",omitempty"`
Parameters map[string]interface{}
}
// Resource represents a resource in a cloudformation template. It contains resource
// metadata and, in Properties, a struct that implements ResourceProperties which
// contains the properties of the resource.
type Resource struct {
CreationPolicy *CreationPolicy
DeletionPolicy string
DependsOn []string
Metadata map[string]interface{}
UpdatePolicy *UpdatePolicy
Condition string
Properties ResourceProperties
Transform *FnTransform
}
// MarshalJSON returns a JSON representation of the object
func (r Resource) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type string
CreationPolicy *CreationPolicy `json:",omitempty"`
DeletionPolicy string `json:",omitempty"`
DependsOn []string `json:",omitempty"`
Metadata map[string]interface{} `json:",omitempty"`
UpdatePolicy *UpdatePolicy `json:",omitempty"`
Condition string `json:",omitempty"`
Transform *FnTransform `json:",omitempty"`
Properties ResourceProperties
}{
Type: r.Properties.CfnResourceType(),
CreationPolicy: r.CreationPolicy,
DeletionPolicy: r.DeletionPolicy,
DependsOn: r.DependsOn,
Metadata: r.Metadata,
UpdatePolicy: r.UpdatePolicy,
Condition: r.Condition,
Transform: r.Transform,
Properties: r.Properties,
})
}
// UnmarshalJSON sets the object from the provided JSON representation
func (r *Resource) UnmarshalJSON(buf []byte) error {
m := map[string]interface{}{}
if err := json.Unmarshal(buf, &m); err != nil {
return err
}
typeName := m["Type"].(string)
r.DependsOn, _ = m["DependsOn"].([]string)
r.Metadata, _ = m["Metadata"].(map[string]interface{})
r.DeletionPolicy, _ = m["DeletionPolicy"].(string)
r.Properties = NewResourceByType(typeName)
if r.Properties == nil {
return fmt.Errorf("unknown resource type: %s", typeName)
}
propertiesBuf, err := json.Marshal(m["Properties"])
if err != nil {
return err
}
return json.Unmarshal(propertiesBuf, r.Properties)
}