github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/ignition/provider.go (about) 1 package ignition 2 3 import ( 4 "bytes" 5 "crypto/sha256" 6 "encoding/hex" 7 "encoding/json" 8 "fmt" 9 "net/url" 10 "sync" 11 12 "github.com/coreos/go-systemd/unit" 13 "github.com/coreos/ignition/config/types" 14 "github.com/hashicorp/terraform/helper/schema" 15 "github.com/hashicorp/terraform/terraform" 16 ) 17 18 // globalCache keeps the instances of the internal types of ignition generated 19 // by the different data resources with the goal to be reused by the 20 // ignition_config data resource. The key of the maps are a hash of the types 21 // calculated on the type serialized to JSON. 22 var globalCache = &cache{ 23 disks: make(map[string]*types.Disk, 0), 24 arrays: make(map[string]*types.Raid, 0), 25 filesystems: make(map[string]*types.Filesystem, 0), 26 files: make(map[string]*types.File, 0), 27 systemdUnits: make(map[string]*types.SystemdUnit, 0), 28 networkdUnits: make(map[string]*types.NetworkdUnit, 0), 29 users: make(map[string]*types.User, 0), 30 groups: make(map[string]*types.Group, 0), 31 } 32 33 func Provider() terraform.ResourceProvider { 34 return &schema.Provider{ 35 DataSourcesMap: map[string]*schema.Resource{ 36 "ignition_config": resourceConfig(), 37 "ignition_disk": resourceDisk(), 38 "ignition_raid": resourceRaid(), 39 "ignition_filesystem": resourceFilesystem(), 40 "ignition_file": resourceFile(), 41 "ignition_systemd_unit": resourceSystemdUnit(), 42 "ignition_networkd_unit": resourceNetworkdUnit(), 43 "ignition_user": resourceUser(), 44 "ignition_group": resourceGroup(), 45 }, 46 ResourcesMap: map[string]*schema.Resource{ 47 "ignition_config": schema.DataSourceResourceShim( 48 "ignition_config", 49 resourceConfig(), 50 ), 51 "ignition_disk": schema.DataSourceResourceShim( 52 "ignition_disk", 53 resourceDisk(), 54 ), 55 "ignition_raid": schema.DataSourceResourceShim( 56 "ignition_raid", 57 resourceRaid(), 58 ), 59 "ignition_filesystem": schema.DataSourceResourceShim( 60 "ignition_filesystem", 61 resourceFilesystem(), 62 ), 63 "ignition_file": schema.DataSourceResourceShim( 64 "ignition_file", 65 resourceFile(), 66 ), 67 "ignition_systemd_unit": schema.DataSourceResourceShim( 68 "ignition_systemd_unit", 69 resourceSystemdUnit(), 70 ), 71 "ignition_networkd_unit": schema.DataSourceResourceShim( 72 "ignition_networkd_unit", 73 resourceNetworkdUnit(), 74 ), 75 "ignition_user": schema.DataSourceResourceShim( 76 "ignition_user", 77 resourceUser(), 78 ), 79 "ignition_group": schema.DataSourceResourceShim( 80 "ignition_group", 81 resourceGroup(), 82 ), 83 }, 84 } 85 } 86 87 type cache struct { 88 disks map[string]*types.Disk 89 arrays map[string]*types.Raid 90 filesystems map[string]*types.Filesystem 91 files map[string]*types.File 92 systemdUnits map[string]*types.SystemdUnit 93 networkdUnits map[string]*types.NetworkdUnit 94 users map[string]*types.User 95 groups map[string]*types.Group 96 97 sync.Mutex 98 } 99 100 func (c *cache) addDisk(g *types.Disk) string { 101 c.Lock() 102 defer c.Unlock() 103 104 id := id(g) 105 c.disks[id] = g 106 107 return id 108 } 109 110 func (c *cache) addRaid(r *types.Raid) string { 111 c.Lock() 112 defer c.Unlock() 113 114 id := id(r) 115 c.arrays[id] = r 116 117 return id 118 } 119 120 func (c *cache) addFilesystem(f *types.Filesystem) string { 121 c.Lock() 122 defer c.Unlock() 123 124 id := id(f) 125 c.filesystems[id] = f 126 127 return id 128 } 129 130 func (c *cache) addFile(f *types.File) string { 131 c.Lock() 132 defer c.Unlock() 133 134 id := id(f) 135 c.files[id] = f 136 137 return id 138 } 139 140 func (c *cache) addSystemdUnit(u *types.SystemdUnit) string { 141 c.Lock() 142 defer c.Unlock() 143 144 id := id(u) 145 c.systemdUnits[id] = u 146 147 return id 148 } 149 150 func (c *cache) addNetworkdUnit(u *types.NetworkdUnit) string { 151 c.Lock() 152 defer c.Unlock() 153 154 id := id(u) 155 c.networkdUnits[id] = u 156 157 return id 158 } 159 160 func (c *cache) addUser(u *types.User) string { 161 c.Lock() 162 defer c.Unlock() 163 164 id := id(u) 165 c.users[id] = u 166 167 return id 168 } 169 170 func (c *cache) addGroup(g *types.Group) string { 171 c.Lock() 172 defer c.Unlock() 173 174 id := id(g) 175 c.groups[id] = g 176 177 return id 178 } 179 180 func id(input interface{}) string { 181 b, _ := json.Marshal(input) 182 return hash(string(b)) 183 } 184 185 func hash(s string) string { 186 sha := sha256.Sum256([]byte(s)) 187 return hex.EncodeToString(sha[:]) 188 } 189 190 func castSliceInterface(i []interface{}) []string { 191 var o []string 192 for _, value := range i { 193 o = append(o, value.(string)) 194 } 195 196 return o 197 } 198 199 func getUInt(d *schema.ResourceData, key string) *uint { 200 var uid *uint 201 if value, ok := d.GetOk(key); ok { 202 u := uint(value.(int)) 203 uid = &u 204 } 205 206 return uid 207 } 208 209 var errEmptyUnit = fmt.Errorf("invalid or empty unit content") 210 211 func validateUnitContent(content string) error { 212 c := bytes.NewBufferString(content) 213 unit, err := unit.Deserialize(c) 214 if err != nil { 215 return fmt.Errorf("invalid unit content: %s", err) 216 } 217 218 if len(unit) == 0 { 219 return errEmptyUnit 220 } 221 222 return nil 223 } 224 225 func buildURL(raw string) (types.Url, error) { 226 u, err := url.Parse(raw) 227 if err != nil { 228 return types.Url{}, err 229 } 230 231 return types.Url(*u), nil 232 } 233 234 func buildHash(raw string) (types.Hash, error) { 235 h := types.Hash{} 236 err := h.UnmarshalJSON([]byte(fmt.Sprintf("%q", raw))) 237 238 return h, err 239 }