github.com/ezbercih/terraform@v0.1.1-0.20140729011846-3c33865e0839/helper/resource/map.go (about) 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 s *terraform.ResourceState, 35 d *terraform.ResourceDiff, 36 meta interface{}) (*terraform.ResourceState, error) { 37 r, ok := m.Mapping[s.Type] 38 if !ok { 39 return nil, fmt.Errorf("Unknown resource type: %s", s.Type) 40 } 41 42 if d.Destroy || d.RequiresNew() { 43 if s.ID != "" { 44 // Destroy the resource if it is created 45 err := r.Destroy(s, meta) 46 if err != nil { 47 return s, err 48 } 49 50 s.ID = "" 51 } 52 53 // If we're only destroying, and not creating, then return now. 54 // Otherwise, we continue so that we can create a new resource. 55 if !d.RequiresNew() { 56 return nil, nil 57 } 58 } 59 60 var result *terraform.ResourceState 61 var err error 62 if s.ID == "" { 63 result, err = r.Create(s, d, meta) 64 } else { 65 if r.Update == nil { 66 return s, fmt.Errorf( 67 "Resource type '%s' doesn't support update", 68 s.Type) 69 } 70 71 result, err = r.Update(s, d, meta) 72 } 73 if result != nil { 74 if result.Attributes == nil { 75 result.Attributes = make(map[string]string) 76 } 77 78 result.Attributes["id"] = result.ID 79 } 80 81 return result, err 82 } 83 84 // Diff peforms a diff on the proper resource type. 85 func (m *Map) Diff( 86 s *terraform.ResourceState, 87 c *terraform.ResourceConfig, 88 meta interface{}) (*terraform.ResourceDiff, error) { 89 r, ok := m.Mapping[s.Type] 90 if !ok { 91 return nil, fmt.Errorf("Unknown resource type: %s", s.Type) 92 } 93 94 return r.Diff(s, c, meta) 95 } 96 97 // Refresh performs a Refresh on the proper resource type. 98 // 99 // Refresh on the Resource won't be called if the state represents a 100 // non-created resource (ID is blank). 101 // 102 // An error is returned if the resource isn't registered. 103 func (m *Map) Refresh( 104 s *terraform.ResourceState, 105 meta interface{}) (*terraform.ResourceState, error) { 106 // If the resource isn't created, don't refresh. 107 if s.ID == "" { 108 return s, nil 109 } 110 111 r, ok := m.Mapping[s.Type] 112 if !ok { 113 return nil, fmt.Errorf("Unknown resource type: %s", s.Type) 114 } 115 116 return r.Refresh(s, meta) 117 } 118 119 // Resources returns all the resources that are supported by this 120 // resource map and can be used to satisfy the Resources method of 121 // a ResourceProvider. 122 func (m *Map) Resources() []terraform.ResourceType { 123 ks := make([]string, 0, len(m.Mapping)) 124 for k, _ := range m.Mapping { 125 ks = append(ks, k) 126 } 127 sort.Strings(ks) 128 129 rs := make([]terraform.ResourceType, 0, len(m.Mapping)) 130 for _, k := range ks { 131 rs = append(rs, terraform.ResourceType{ 132 Name: k, 133 }) 134 } 135 136 return rs 137 }