Skip to content

Commit

Permalink
template: parse provisioners
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed May 21, 2015
1 parent 9589000 commit 4583ed6
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 4 deletions.
54 changes: 53 additions & 1 deletion template/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ func (r *rawTemplate) Template() (*Template, error) {
var errs error

// Let's start by gathering all the builders
result.Builders = make(map[string]*Builder)
if len(r.Builders) > 0 {
result.Builders = make(map[string]*Builder, len(r.Builders))
}
for i, rawB := range r.Builders {
var b Builder
if err := mapstructure.WeakDecode(rawB, &b); err != nil {
Expand Down Expand Up @@ -72,6 +74,39 @@ func (r *rawTemplate) Template() (*Template, error) {
result.Builders[b.Name] = &b
}

// Gather all the provisioners
if len(r.Provisioners) > 0 {
result.Provisioners = make([]*Provisioner, 0, len(r.Provisioners))
}
for i, v := range r.Provisioners {
var p Provisioner
if err := r.decoder(&p, nil).Decode(v); err != nil {
errs = multierror.Append(errs, fmt.Errorf(
"provisioner %d: %s", i+1, err))
continue
}

// Type is required before any richer validation
if p.Type == "" {
errs = multierror.Append(errs, fmt.Errorf(
"provisioner %d: missing 'type'", i+1))
continue
}

// Copy the configuration
delete(v, "except")
delete(v, "only")
delete(v, "override")
delete(v, "pause_before")
delete(v, "type")
if len(v) > 0 {
p.Config = v
}

// TODO: stuff
result.Provisioners = append(result.Provisioners, &p)
}

// If we have errors, return those with a nil result
if errs != nil {
return nil, errs
Expand All @@ -80,6 +115,23 @@ func (r *rawTemplate) Template() (*Template, error) {
return &result, nil
}

func (r *rawTemplate) decoder(
result interface{},
md *mapstructure.Metadata) *mapstructure.Decoder {
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
Metadata: md,
Result: result,
})
if err != nil {
// This really shouldn't happen since we have firm control over
// all the arguments and they're all unit tested. So we use a
// panic here to note this would definitely be a bug.
panic(err)
}
return d
}

// Parse takes the given io.Reader and parses a Template object out of it.
func Parse(r io.Reader) (*Template, error) {
// First, decode the object into an interface{}. We do this instead of
Expand Down
85 changes: 84 additions & 1 deletion template/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os"
"reflect"
"testing"
"time"
)

func TestParse(t *testing.T) {
Expand All @@ -12,6 +13,9 @@ func TestParse(t *testing.T) {
Result *Template
Err bool
}{
/*
* Builders
*/
{
"parse-basic.json",
&Template{
Expand All @@ -34,6 +38,85 @@ func TestParse(t *testing.T) {
nil,
true,
},

/*
* Provisioners
*/
{
"parse-provisioner-basic.json",
&Template{
Provisioners: []*Provisioner{
&Provisioner{
Type: "something",
},
},
},
false,
},

{
"parse-provisioner-pause-before.json",
&Template{
Provisioners: []*Provisioner{
&Provisioner{
Type: "something",
PauseBefore: 1 * time.Second,
},
},
},
false,
},

{
"parse-provisioner-only.json",
&Template{
Provisioners: []*Provisioner{
&Provisioner{
Type: "something",
OnlyExcept: OnlyExcept{
Only: []string{"foo"},
},
},
},
},
false,
},

{
"parse-provisioner-except.json",
&Template{
Provisioners: []*Provisioner{
&Provisioner{
Type: "something",
OnlyExcept: OnlyExcept{
Except: []string{"foo"},
},
},
},
},
false,
},

{
"parse-provisioner-override.json",
&Template{
Provisioners: []*Provisioner{
&Provisioner{
Type: "something",
Override: map[string]interface{}{
"foo": map[string]interface{}{},
},
},
},
},
false,
},

{
"parse-provisioner-no-type.json",
nil,
true,
},
}

for _, tc := range cases {
Expand All @@ -49,7 +132,7 @@ func TestParse(t *testing.T) {
}

if !reflect.DeepEqual(tpl, tc.Result) {
t.Fatalf("bad: %#v", tpl)
t.Fatalf("bad: %s\n\n%#v\n\n%#v", tc.File, tpl, tc.Result)
}
}
}
8 changes: 6 additions & 2 deletions template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ type PostProcessor struct {

// Provisioner represents a provisioner within the template.
type Provisioner struct {
OnlyExcept
OnlyExcept `mapstructure:",squash"`

Type string
Config map[string]interface{}
Override map[string]interface{}
PauseBefore time.Duration
PauseBefore time.Duration `mapstructure:"pause_before"`
}

// Push represents the configuration for pushing the template to Atlas.
Expand Down Expand Up @@ -75,3 +75,7 @@ type OnlyExcept struct {
func (b *Builder) GoString() string {
return fmt.Sprintf("*%#v", *b)
}

func (p *Provisioner) GoString() string {
return fmt.Sprintf("*%#v", *p)
}
5 changes: 5 additions & 0 deletions template/test-fixtures/parse-provisioner-basic.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"provisioners": [
{"type": "something"}
]
}
8 changes: 8 additions & 0 deletions template/test-fixtures/parse-provisioner-except.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"provisioners": [
{
"type": "something",
"except": ["foo"]
}
]
}
5 changes: 5 additions & 0 deletions template/test-fixtures/parse-provisioner-no-type.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"provisioners": [
{"foo": "something"}
]
}
8 changes: 8 additions & 0 deletions template/test-fixtures/parse-provisioner-only.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"provisioners": [
{
"type": "something",
"only": ["foo"]
}
]
}
10 changes: 10 additions & 0 deletions template/test-fixtures/parse-provisioner-override.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"provisioners": [
{
"type": "something",
"override": {
"foo": {}
}
}
]
}
8 changes: 8 additions & 0 deletions template/test-fixtures/parse-provisioner-pause-before.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"provisioners": [
{
"type": "something",
"pause_before": "1s"
}
]
}

0 comments on commit 4583ed6

Please sign in to comment.