provisioner/remote-exec: Fix panic from remote_exec provisioner

Fixes panic on `nil` values of `inline` and `scripts` from improper interface casts.

Fixes: #13970
This commit is contained in:
Jake Champlin 2017-05-01 16:48:42 -04:00
parent 08e778c883
commit 7e5eeb2268
No known key found for this signature in database
GPG Key ID: DC31F41958EF4AC2
2 changed files with 55 additions and 6 deletions

View File

@ -22,7 +22,7 @@ import (
func Provisioner() terraform.ResourceProvisioner {
return &schema.Provisioner{
Schema: map[string]*schema.Schema{
"inline": &schema.Schema{
"inline": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
PromoteSingle: true,
@ -30,13 +30,13 @@ func Provisioner() terraform.ResourceProvisioner {
ConflictsWith: []string{"script", "scripts"},
},
"script": &schema.Schema{
"script": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"inline", "scripts"},
},
"scripts": &schema.Schema{
"scripts": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
@ -81,7 +81,11 @@ func applyFn(ctx context.Context) error {
func generateScripts(d *schema.ResourceData) ([]string, error) {
var lines []string
for _, l := range d.Get("inline").([]interface{}) {
lines = append(lines, l.(string))
line, ok := l.(string)
if !ok {
return nil, fmt.Errorf("Error parsing %v as a string", l)
}
lines = append(lines, line)
}
lines = append(lines, "")
@ -109,12 +113,20 @@ func collectScripts(d *schema.ResourceData) ([]io.ReadCloser, error) {
// Collect scripts
var scripts []string
if script, ok := d.GetOk("script"); ok {
scripts = append(scripts, script.(string))
scr, ok := script.(string)
if !ok {
return nil, fmt.Errorf("Error parsing script %v as string", script)
}
scripts = append(scripts, scr)
}
if scriptList, ok := d.GetOk("scripts"); ok {
for _, script := range scriptList.([]interface{}) {
scripts = append(scripts, script.(string))
scr, ok := script.(string)
if !ok {
return nil, fmt.Errorf("Error parsing script %v as string", script)
}
scripts = append(scripts, scr)
}
}

View File

@ -9,6 +9,8 @@ import (
"testing"
"time"
"strings"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
@ -71,6 +73,23 @@ func TestResourceProvider_generateScript(t *testing.T) {
}
}
func TestResourceProvider_generateScriptEmptyInline(t *testing.T) {
p := Provisioner().(*schema.Provisioner)
conf := map[string]interface{}{
"inline": []interface{}{""},
}
_, err := generateScripts(schema.TestResourceDataRaw(
t, p.Schema, conf))
if err == nil {
t.Fatal("expected error, got none")
}
if !strings.Contains(err.Error(), "Error parsing") {
t.Fatalf("expected parsing error, got: %s", err)
}
}
func TestResourceProvider_CollectScripts_inline(t *testing.T) {
p := Provisioner().(*schema.Provisioner)
conf := map[string]interface{}{
@ -162,6 +181,24 @@ func TestResourceProvider_CollectScripts_scripts(t *testing.T) {
}
}
func TestResourceProvider_CollectScripts_scriptsEmpty(t *testing.T) {
p := Provisioner().(*schema.Provisioner)
conf := map[string]interface{}{
"scripts": []interface{}{""},
}
_, err := collectScripts(schema.TestResourceDataRaw(
t, p.Schema, conf))
if err == nil {
t.Fatal("expected error")
}
if !strings.Contains(err.Error(), "Error parsing") {
t.Fatalf("Expected parsing error, got: %s", err)
}
}
func TestRetryFunc(t *testing.T) {
// succeed on the third try
errs := []error{io.EOF, &net.OpError{Err: errors.New("ERROR")}, nil}