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  }