]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package resource |
2 | ||
3 | import ( | |
4 | "fmt" | |
5 | "sort" | |
6 | ||
7 | "github.com/hashicorp/terraform/terraform" | |
8 | ) | |
9 | ||
10 | // Map is a map of resources that are supported, and provides helpers for | |
11 | // more easily implementing a ResourceProvider. | |
12 | type Map struct { | |
13 | Mapping map[string]Resource | |
14 | } | |
15 | ||
16 | func (m *Map) Validate( | |
17 | t string, c *terraform.ResourceConfig) ([]string, []error) { | |
18 | r, ok := m.Mapping[t] | |
19 | if !ok { | |
20 | return nil, []error{fmt.Errorf("Unknown resource type: %s", t)} | |
21 | } | |
22 | ||
23 | // If there is no validator set, then it is valid | |
24 | if r.ConfigValidator == nil { | |
25 | return nil, nil | |
26 | } | |
27 | ||
28 | return r.ConfigValidator.Validate(c) | |
29 | } | |
30 | ||
31 | // Apply performs a create or update depending on the diff, and calls | |
32 | // the proper function on the matching Resource. | |
33 | func (m *Map) Apply( | |
34 | info *terraform.InstanceInfo, | |
35 | s *terraform.InstanceState, | |
36 | d *terraform.InstanceDiff, | |
37 | meta interface{}) (*terraform.InstanceState, error) { | |
38 | r, ok := m.Mapping[info.Type] | |
39 | if !ok { | |
40 | return nil, fmt.Errorf("Unknown resource type: %s", info.Type) | |
41 | } | |
42 | ||
43 | if d.Destroy || d.RequiresNew() { | |
44 | if s.ID != "" { | |
45 | // Destroy the resource if it is created | |
46 | err := r.Destroy(s, meta) | |
47 | if err != nil { | |
48 | return s, err | |
49 | } | |
50 | ||
51 | s.ID = "" | |
52 | } | |
53 | ||
54 | // If we're only destroying, and not creating, then return now. | |
55 | // Otherwise, we continue so that we can create a new resource. | |
56 | if !d.RequiresNew() { | |
57 | return nil, nil | |
58 | } | |
59 | } | |
60 | ||
61 | var result *terraform.InstanceState | |
62 | var err error | |
63 | if s.ID == "" { | |
64 | result, err = r.Create(s, d, meta) | |
65 | } else { | |
66 | if r.Update == nil { | |
67 | return s, fmt.Errorf( | |
68 | "Resource type '%s' doesn't support update", | |
69 | info.Type) | |
70 | } | |
71 | ||
72 | result, err = r.Update(s, d, meta) | |
73 | } | |
74 | if result != nil { | |
75 | if result.Attributes == nil { | |
76 | result.Attributes = make(map[string]string) | |
77 | } | |
78 | ||
79 | result.Attributes["id"] = result.ID | |
80 | } | |
81 | ||
82 | return result, err | |
83 | } | |
84 | ||
85 | // Diff performs a diff on the proper resource type. | |
86 | func (m *Map) Diff( | |
87 | info *terraform.InstanceInfo, | |
88 | s *terraform.InstanceState, | |
89 | c *terraform.ResourceConfig, | |
90 | meta interface{}) (*terraform.InstanceDiff, error) { | |
91 | r, ok := m.Mapping[info.Type] | |
92 | if !ok { | |
93 | return nil, fmt.Errorf("Unknown resource type: %s", info.Type) | |
94 | } | |
95 | ||
96 | return r.Diff(s, c, meta) | |
97 | } | |
98 | ||
99 | // Refresh performs a Refresh on the proper resource type. | |
100 | // | |
101 | // Refresh on the Resource won't be called if the state represents a | |
102 | // non-created resource (ID is blank). | |
103 | // | |
104 | // An error is returned if the resource isn't registered. | |
105 | func (m *Map) Refresh( | |
106 | info *terraform.InstanceInfo, | |
107 | s *terraform.InstanceState, | |
108 | meta interface{}) (*terraform.InstanceState, error) { | |
109 | // If the resource isn't created, don't refresh. | |
110 | if s.ID == "" { | |
111 | return s, nil | |
112 | } | |
113 | ||
114 | r, ok := m.Mapping[info.Type] | |
115 | if !ok { | |
116 | return nil, fmt.Errorf("Unknown resource type: %s", info.Type) | |
117 | } | |
118 | ||
119 | return r.Refresh(s, meta) | |
120 | } | |
121 | ||
122 | // Resources returns all the resources that are supported by this | |
123 | // resource map and can be used to satisfy the Resources method of | |
124 | // a ResourceProvider. | |
125 | func (m *Map) Resources() []terraform.ResourceType { | |
126 | ks := make([]string, 0, len(m.Mapping)) | |
127 | for k, _ := range m.Mapping { | |
128 | ks = append(ks, k) | |
129 | } | |
130 | sort.Strings(ks) | |
131 | ||
132 | rs := make([]terraform.ResourceType, 0, len(m.Mapping)) | |
133 | for _, k := range ks { | |
134 | rs = append(rs, terraform.ResourceType{ | |
135 | Name: k, | |
136 | }) | |
137 | } | |
138 | ||
139 | return rs | |
140 | } |