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  }