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