template: parse provisioners
This commit is contained in:
parent
95890003b7
commit
4583ed6108
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
|
@ -12,6 +13,9 @@ func TestParse(t *testing.T) {
|
|||
Result *Template
|
||||
Err bool
|
||||
}{
|
||||
/*
|
||||
* Builders
|
||||
*/
|
||||
{
|
||||
"parse-basic.json",
|
||||
&Template{
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"provisioners": [
|
||||
{"type": "something"}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "something",
|
||||
"except": ["foo"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"provisioners": [
|
||||
{"foo": "something"}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "something",
|
||||
"only": ["foo"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "something",
|
||||
"override": {
|
||||
"foo": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "something",
|
||||
"pause_before": "1s"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue