Skip to content

Commit

Permalink
Ignition provider (#6189)
Browse files Browse the repository at this point in the history
* providers: ignition, basic config, version and config

* providers: ignition, user and passwd example, general cache implementation

* vendor: Capture new dependency upstream-pkg

* providers: ignition ignition_user

* providers: ignition ignition_disk, ignition_group and ignition_raid

* providers: ignition_file and ignition_filesystem

* providers: ignition_systemd_unit and ignition_networkd_unit

* providers: ignition_config improvements

* vendor: Capture new dependency upstream-pkg

* providers: ignition main

* documentation: ignition provider

* providers: ignition minor changes

* providers: ignition, fix test

* fixing tests and latest versions
  • Loading branch information
mcuadros authored and stack72 committed Jan 3, 2017
1 parent 3203023 commit 85f0fba
Show file tree
Hide file tree
Showing 79 changed files with 6,552 additions and 4 deletions.
12 changes: 12 additions & 0 deletions builtin/bins/provider-ignition/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

import (
"github.com/hashicorp/terraform/builtin/providers/ignition"
"github.com/hashicorp/terraform/plugin"
)

func main() {
plugin.Serve(&plugin.ServeOpts{
ProviderFunc: ignition.Provider,
})
}
202 changes: 202 additions & 0 deletions builtin/providers/ignition/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package ignition

import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/url"
"sync"

"github.com/coreos/go-systemd/unit"
"github.com/coreos/ignition/config/types"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)

func Provider() terraform.ResourceProvider {
return &schema.Provider{
ResourcesMap: map[string]*schema.Resource{
"ignition_config": resourceConfig(),
"ignition_disk": resourceDisk(),
"ignition_raid": resourceRaid(),
"ignition_filesystem": resourceFilesystem(),
"ignition_file": resourceFile(),
"ignition_systemd_unit": resourceSystemdUnit(),
"ignition_networkd_unit": resourceNetworkdUnit(),
"ignition_user": resourceUser(),
"ignition_group": resourceGroup(),
},
ConfigureFunc: func(*schema.ResourceData) (interface{}, error) {
return &cache{
disks: make(map[string]*types.Disk, 0),
arrays: make(map[string]*types.Raid, 0),
filesystems: make(map[string]*types.Filesystem, 0),
files: make(map[string]*types.File, 0),
systemdUnits: make(map[string]*types.SystemdUnit, 0),
networkdUnits: make(map[string]*types.NetworkdUnit, 0),
users: make(map[string]*types.User, 0),
groups: make(map[string]*types.Group, 0),
}, nil
},
}
}

type cache struct {
disks map[string]*types.Disk
arrays map[string]*types.Raid
filesystems map[string]*types.Filesystem
files map[string]*types.File
systemdUnits map[string]*types.SystemdUnit
networkdUnits map[string]*types.NetworkdUnit
users map[string]*types.User
groups map[string]*types.Group

sync.Mutex
}

func (c *cache) addDisk(g *types.Disk) string {
c.Lock()
defer c.Unlock()

id := id(g)
c.disks[id] = g

return id
}

func (c *cache) addRaid(r *types.Raid) string {
c.Lock()
defer c.Unlock()

id := id(r)
c.arrays[id] = r

return id
}

func (c *cache) addFilesystem(f *types.Filesystem) string {
c.Lock()
defer c.Unlock()

id := id(f)
c.filesystems[id] = f

return id
}

func (c *cache) addFile(f *types.File) string {
c.Lock()
defer c.Unlock()

id := id(f)
c.files[id] = f

return id
}

func (c *cache) addSystemdUnit(u *types.SystemdUnit) string {
c.Lock()
defer c.Unlock()

id := id(u)
c.systemdUnits[id] = u

return id
}

func (c *cache) addNetworkdUnit(u *types.NetworkdUnit) string {
c.Lock()
defer c.Unlock()

id := id(u)
c.networkdUnits[id] = u

return id
}

func (c *cache) addUser(u *types.User) string {
c.Lock()
defer c.Unlock()

id := id(u)
c.users[id] = u

return id
}

func (c *cache) addGroup(g *types.Group) string {
c.Lock()
defer c.Unlock()

id := id(g)
c.groups[id] = g

return id
}

func id(input interface{}) string {
b, _ := json.Marshal(input)
return hash(string(b))
}

func hash(s string) string {
sha := sha256.Sum256([]byte(s))
return hex.EncodeToString(sha[:])
}

func castSliceInterface(i []interface{}) []string {
var o []string
for _, value := range i {
o = append(o, value.(string))
}

return o
}

func getUInt(d *schema.ResourceData, key string) *uint {
var uid *uint
if value, ok := d.GetOk(key); ok {
u := uint(value.(int))
uid = &u
}

return uid
}

func validateUnit(content string) error {
r := bytes.NewBuffer([]byte(content))

u, err := unit.Deserialize(r)
if len(u) == 0 {
return fmt.Errorf("invalid or empty unit content")
}

if err == nil {
return nil
}

if err == io.EOF {
return fmt.Errorf("unexpected EOF reading unit content")
}

return err
}

func buildURL(raw string) (types.Url, error) {
u, err := url.Parse(raw)
if err != nil {
return types.Url{}, err
}

return types.Url(*u), nil
}

func buildHash(raw string) (types.Hash, error) {
h := types.Hash{}
err := h.UnmarshalJSON([]byte(fmt.Sprintf("%q", raw)))

return h, err
}
32 changes: 32 additions & 0 deletions builtin/providers/ignition/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ignition

import (
"testing"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)

var testProviders = map[string]terraform.ResourceProvider{
"ignition": Provider(),
}

func TestProvider(t *testing.T) {
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
t.Fatalf("err: %s", err)
}
}

func TestValidateUnit(t *testing.T) {
if err := validateUnit(""); err == nil {
t.Fatalf("error not found, expected error")
}

if err := validateUnit("[foo]qux"); err == nil {
t.Fatalf("error not found, expected error")
}

if err := validateUnit("[foo]\nqux=foo\nfoo"); err == nil {
t.Fatalf("error not found, expected error")
}
}
Loading

0 comments on commit 85f0fba

Please sign in to comment.