Fix and refactor the Chef provisioner

The tests did pass, but that was because they only tested part of the changes. By using the `schema.TestResourceDataRaw` function the schema and config are better tested and so they pointed out a problem with the schema of the Chef provisioner.

The `Elem` fields did not have a `*schema.Schema` but a `schema.Schema` and in an `Elem` schema only the `Type` field may (and must) be set. Any other fields like `Optional` are not allowed here.

Next to fixing that problem I also did a little refactoring and cleaning up. Mainly making the `ProvisionerS` private (`provisioner`) and removing the deprecated fields.
This commit is contained in:
Sander van Harmelen 2017-05-19 20:42:14 +02:00
parent df4342bc3d
commit 0e422737ba
13 changed files with 310 additions and 411 deletions

View File

@ -14,10 +14,7 @@ const (
installURL = "https://www.chef.io/chef/install.sh"
)
func (p *ProvisionerS) linuxInstallChefClient(
o terraform.UIOutput,
comm communicator.Communicator) error {
func (p *provisioner) linuxInstallChefClient(o terraform.UIOutput, comm communicator.Communicator) error {
// Build up the command prefix
prefix := ""
if p.HTTPProxy != "" {
@ -26,7 +23,7 @@ func (p *ProvisionerS) linuxInstallChefClient(
if p.HTTPSProxy != "" {
prefix += fmt.Sprintf("https_proxy='%s' ", p.HTTPSProxy)
}
if p.NOProxy != nil && len(p.NOProxy) > 0 {
if len(p.NOProxy) > 0 {
prefix += fmt.Sprintf("no_proxy='%s' ", strings.Join(p.NOProxy, ","))
}
@ -46,9 +43,7 @@ func (p *ProvisionerS) linuxInstallChefClient(
return p.runCommand(o, comm, fmt.Sprintf("%srm -f install.sh", prefix))
}
func (p *ProvisionerS) linuxCreateConfigFiles(
o terraform.UIOutput,
comm communicator.Communicator) error {
func (p *provisioner) linuxCreateConfigFiles(o terraform.UIOutput, comm communicator.Communicator) error {
// Make sure the config directory exists
if err := p.runCommand(o, comm, "mkdir -p "+linuxConfDir); err != nil {
return err

View File

@ -6,22 +6,23 @@ import (
"testing"
"github.com/hashicorp/terraform/communicator"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)
func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
cases := map[string]struct {
Config *terraform.ResourceConfig
Config map[string]interface{}
Commands map[string]bool
}{
"Sudo": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"run_list": []interface{}{"cookbook::recipe"},
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"sudo curl -LO https://www.chef.io/chef/install.sh": true,
@ -31,7 +32,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
},
"NoSudo": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"prevent_sudo": true,
"run_list": []interface{}{"cookbook::recipe"},
@ -39,7 +40,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"curl -LO https://www.chef.io/chef/install.sh": true,
@ -49,7 +50,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
},
"HTTPProxy": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"http_proxy": "http://proxy.local",
"node_name": "nodename1",
"prevent_sudo": true,
@ -57,7 +58,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"http_proxy='http://proxy.local' curl -LO https://www.chef.io/chef/install.sh": true,
@ -67,7 +68,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
},
"HTTPSProxy": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"https_proxy": "https://proxy.local",
"node_name": "nodename1",
"prevent_sudo": true,
@ -75,7 +76,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"https_proxy='https://proxy.local' curl -LO https://www.chef.io/chef/install.sh": true,
@ -85,7 +86,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
},
"NoProxy": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"http_proxy": "http://proxy.local",
"no_proxy": []interface{}{"http://local.local", "http://local.org"},
"node_name": "nodename1",
@ -94,7 +95,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"http_proxy='http://proxy.local' no_proxy='http://local.local,http://local.org' " +
@ -107,7 +108,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
},
"Version": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"prevent_sudo": true,
"run_list": []interface{}{"cookbook::recipe"},
@ -115,7 +116,7 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
"user_name": "bob",
"user_key": "USER-KEY",
"version": "11.18.6",
}),
},
Commands: map[string]bool{
"curl -LO https://www.chef.io/chef/install.sh": true,
@ -131,7 +132,9 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
for k, tc := range cases {
c.Commands = tc.Commands
p, err := decodeConfig(getTestResourceData(tc.Config))
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}
@ -147,12 +150,12 @@ func TestResourceProvider_linuxInstallChefClient(t *testing.T) {
func TestResourceProvider_linuxCreateConfigFiles(t *testing.T) {
cases := map[string]struct {
Config *terraform.ResourceConfig
Config map[string]interface{}
Commands map[string]bool
Uploads map[string]string
}{
"Sudo": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"ohai_hints": []interface{}{"test-fixtures/ohaihint.json"},
"node_name": "nodename1",
"run_list": []interface{}{"cookbook::recipe"},
@ -160,7 +163,7 @@ func TestResourceProvider_linuxCreateConfigFiles(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"sudo mkdir -p " + linuxConfDir: true,
@ -187,7 +190,7 @@ func TestResourceProvider_linuxCreateConfigFiles(t *testing.T) {
},
"NoSudo": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"prevent_sudo": true,
"run_list": []interface{}{"cookbook::recipe"},
@ -195,7 +198,7 @@ func TestResourceProvider_linuxCreateConfigFiles(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"mkdir -p " + linuxConfDir: true,
@ -210,7 +213,7 @@ func TestResourceProvider_linuxCreateConfigFiles(t *testing.T) {
},
"Proxy": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"http_proxy": "http://proxy.local",
"https_proxy": "https://proxy.local",
"no_proxy": []interface{}{"http://local.local", "https://local.local"},
@ -222,7 +225,7 @@ func TestResourceProvider_linuxCreateConfigFiles(t *testing.T) {
"ssl_verify_mode": "verify_none",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"mkdir -p " + linuxConfDir: true,
@ -237,7 +240,7 @@ func TestResourceProvider_linuxCreateConfigFiles(t *testing.T) {
},
"Attributes JSON": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"attributes_json": `{"key1":{"subkey1":{"subkey2a":["val1","val2","val3"],` +
`"subkey2b":{"subkey3":"value3"}}},"key2":"value2"}`,
"node_name": "nodename1",
@ -247,7 +250,7 @@ func TestResourceProvider_linuxCreateConfigFiles(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"mkdir -p " + linuxConfDir: true,
@ -270,7 +273,9 @@ func TestResourceProvider_linuxCreateConfigFiles(t *testing.T) {
c.Commands = tc.Commands
c.Uploads = tc.Uploads
p, err := decodeConfig(getTestResourceData(tc.Config))
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}

View File

@ -2,6 +2,7 @@ package chef
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
@ -15,7 +16,6 @@ import (
"text/template"
"time"
"context"
"github.com/hashicorp/terraform/communicator"
"github.com/hashicorp/terraform/communicator/remote"
"github.com/hashicorp/terraform/helper/schema"
@ -82,9 +82,10 @@ enable_reporting false
{{ end }}
`
// ProvisionerS represents a Chef provisioner
type ProvisionerS struct {
AttributesJSON string
type provisionFn func(terraform.UIOutput, communicator.Communicator) error
type provisioner struct {
Attributes map[string]interface{}
ClientOptions []string
DisableReporting bool
Environment string
@ -110,180 +111,153 @@ type ProvisionerS struct {
SSLVerifyMode string
UserName string
UserKey string
VaultJSON string
Vaults map[string][]string
Version string
attributes map[string]interface{}
vaults map[string][]string
cleanupUserKeyCmd string
createConfigFiles func(terraform.UIOutput, communicator.Communicator) error
installChefClient func(terraform.UIOutput, communicator.Communicator) error
fetchChefCertificates func(terraform.UIOutput, communicator.Communicator) error
generateClientKey func(terraform.UIOutput, communicator.Communicator) error
configureVaults func(terraform.UIOutput, communicator.Communicator) error
runChefClient func(terraform.UIOutput, communicator.Communicator) error
createConfigFiles provisionFn
installChefClient provisionFn
fetchChefCertificates provisionFn
generateClientKey provisionFn
configureVaults provisionFn
runChefClient provisionFn
useSudo bool
// Deprecated Fields
ValidationClientName string
ValidationKey string
}
// Provisioner returns a Chef provisioner
func Provisioner() terraform.ResourceProvisioner {
return &schema.Provisioner{
Schema: map[string]*schema.Schema{
"attributes_json": {
Type: schema.TypeString,
Optional: true,
},
"client_options": {
Type: schema.TypeList,
Elem: schema.Schema{
Type: schema.TypeString,
},
Optional: true,
},
"disable_reporting": {
Type: schema.TypeBool,
Optional: true,
},
"environment": {
Type: schema.TypeString,
Optional: true,
},
"fetch_chef_certificates": {
Type: schema.TypeBool,
Optional: true,
},
"log_to_file": {
Type: schema.TypeBool,
Optional: true,
},
"use_policyfile": {
Type: schema.TypeBool,
Optional: true,
},
"policy_group": {
Type: schema.TypeString,
Optional: true,
},
"policy_name": {
Type: schema.TypeString,
Optional: true,
},
"http_proxy": {
Type: schema.TypeString,
Optional: true,
},
"https_proxy": {
Type: schema.TypeString,
Optional: true,
},
"no_proxy": {
Type: schema.TypeList,
Elem: schema.Schema{
Type: schema.TypeString,
Optional: true,
},
Optional: true,
},
"named_run_list": {
Type: schema.TypeString,
Optional: true,
},
"node_name": {
"node_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"ohai_hints": {
Type: schema.TypeList,
Elem: schema.Schema{
Type: schema.TypeString,
Optional: true,
},
Optional: true,
},
"os_type": {
Type: schema.TypeString,
Optional: true,
},
"recreate_client": {
Type: schema.TypeBool,
Optional: true,
},
"prevent_sudo": {
Type: schema.TypeBool,
Optional: true,
},
"run_list": {
Type: schema.TypeList,
Elem: schema.Schema{
Type: schema.TypeString,
Optional: true,
},
Optional: true,
},
"secret_key": {
Type: schema.TypeString,
Optional: true,
},
"server_url": {
"server_url": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"skip_install": {
"user_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"user_key": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"attributes_json": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"client_options": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
"disable_reporting": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"skip_register": {
"environment": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: defaultEnv,
},
"fetch_chef_certificates": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"ssl_verify_mode": {
"log_to_file": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"use_policyfile": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"policy_group": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"user_name": {
"policy_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"user_key": {
"http_proxy": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"vault_json": {
"https_proxy": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"version": {
"no_proxy": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
"named_run_list": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
// Deprecated
"validation_client_name": {
Type: schema.TypeString,
Deprecated: "Please use user_name instead",
Optional: true,
"ohai_hints": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
"validation_key": {
Type: schema.TypeString,
Deprecated: "Please use user_key instead",
Optional: true,
"os_type": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"recreate_client": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"prevent_sudo": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"run_list": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
"secret_key": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"skip_install": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"skip_register": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"ssl_verify_mode": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"vault_json": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"version": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
},
ApplyFunc: Apply,
ValidateFunc: Validate,
ApplyFunc: applyFn,
ValidateFunc: validateFn,
}
}
// TODO: Support context cancelling (Provisioner Stop)
// Apply executes the file provisioner
func Apply(ctx context.Context) error {
func applyFn(ctx context.Context) error {
o := ctx.Value(schema.ProvOutputKey).(terraform.UIOutput)
d := ctx.Value(schema.ProvConfigDataKey).(*schema.ResourceData)
// Decode the raw config for this provisioner
p, err := decodeConfig(d)
if err != nil {
@ -291,8 +265,7 @@ func Apply(ctx context.Context) error {
}
if p.OSType == "" {
t := d.State().Ephemeral.ConnInfo["type"]
switch t {
switch t := d.State().Ephemeral.ConnInfo["type"]; t {
case "ssh", "": // The default connection type is ssh, so if the type is empty assume ssh
p.OSType = "linux"
case "winrm":
@ -334,8 +307,7 @@ func Apply(ctx context.Context) error {
// Wait and retry until we establish the connection
err = retryFunc(comm.Timeout(), func() error {
err := comm.Connect(o)
return err
return comm.Connect(o)
})
if err != nil {
return err
@ -377,7 +349,7 @@ func Apply(ctx context.Context) error {
}
}
if p.VaultJSON != "" {
if p.Vaults != nil {
o.Output("Configure Chef vaults...")
if err := p.configureVaults(o, comm); err != nil {
return err
@ -396,8 +368,7 @@ func Apply(ctx context.Context) error {
return nil
}
// Validate checks if the required arguments are configured
func Validate(d *schema.ResourceData) (ws []string, es []error) {
func validateFn(d *schema.ResourceData) (ws []string, es []error) {
p, err := decodeConfig(d)
if err != nil {
es = append(es, err)
@ -413,94 +384,11 @@ func Validate(d *schema.ResourceData) (ws []string, es []error) {
if p.UsePolicyfile && p.PolicyGroup == "" {
es = append(es, errors.New("Policyfile enabled but key not found: policy_group"))
}
if p.UserName == "" && p.ValidationClientName == "" {
es = append(es, errors.New(
"One of user_name or the deprecated validation_client_name must be provided"))
}
if p.UserKey == "" && p.ValidationKey == "" {
es = append(es, errors.New(
"One of user_key or the deprecated validation_key must be provided"))
}
if p.ValidationKey != "" {
if p.RecreateClient {
es = append(es, errors.New(
"Cannot use recreate_client=true with the deprecated validation_key, please provide a user_key"))
}
if p.VaultJSON != "" {
es = append(es, errors.New(
"Cannot configure chef vaults using the deprecated validation_key, please provide a user_key"))
}
}
return ws, es
}
func decodeConfig(d *schema.ResourceData) (*ProvisionerS, error) {
p := decodeDataToProvisioner(d)
// Make sure the supplied URL has a trailing slash
p.ServerURL = strings.TrimSuffix(p.ServerURL, "/") + "/"
if p.Environment == "" {
p.Environment = defaultEnv
}
for i, hint := range p.OhaiHints {
hintPath, err := homedir.Expand(hint)
if err != nil {
return nil, fmt.Errorf("Error expanding the path %s: %v", hint, err)
}
p.OhaiHints[i] = hintPath
}
if p.UserName == "" && p.ValidationClientName != "" {
p.UserName = p.ValidationClientName
}
if p.UserKey == "" && p.ValidationKey != "" {
p.UserKey = p.ValidationKey
}
if attrs, ok := d.GetOk("attributes_json"); ok {
var m map[string]interface{}
if err := json.Unmarshal([]byte(attrs.(string)), &m); err != nil {
return nil, fmt.Errorf("Error parsing attributes_json: %v", err)
}
p.attributes = m
}
if vaults, ok := d.GetOk("vault_json"); ok {
var m map[string]interface{}
if err := json.Unmarshal([]byte(vaults.(string)), &m); err != nil {
return nil, fmt.Errorf("Error parsing vault_json: %v", err)
}
v := make(map[string][]string)
for vault, items := range m {
switch items := items.(type) {
case []interface{}:
for _, item := range items {
if item, ok := item.(string); ok {
v[vault] = append(v[vault], item)
}
}
case interface{}:
if item, ok := items.(string); ok {
v[vault] = append(v[vault], item)
}
}
}
p.vaults = v
}
return p, nil
}
func (p *ProvisionerS) deployConfigFiles(
o terraform.UIOutput,
comm communicator.Communicator,
confDir string) error {
func (p *provisioner) deployConfigFiles(o terraform.UIOutput, comm communicator.Communicator, confDir string) error {
// Copy the user key to the new instance
pk := strings.NewReader(p.UserKey)
if err := comm.Upload(path.Join(confDir, p.UserName+".pem"), pk); err != nil {
@ -535,14 +423,14 @@ func (p *ProvisionerS) deployConfigFiles(
}
// Copy the client config to the new instance
if err := comm.Upload(path.Join(confDir, clienrb), &buf); err != nil {
if err = comm.Upload(path.Join(confDir, clienrb), &buf); err != nil {
return fmt.Errorf("Uploading %s failed: %v", clienrb, err)
}
// Create a map with first boot settings
fb := make(map[string]interface{})
if p.attributes != nil {
fb = p.attributes
if p.Attributes != nil {
fb = p.Attributes
}
// Check if the run_list was also in the attributes and if so log a warning
@ -571,10 +459,7 @@ func (p *ProvisionerS) deployConfigFiles(
return nil
}
func (p *ProvisionerS) deployOhaiHints(
o terraform.UIOutput,
comm communicator.Communicator,
hintDir string) error {
func (p *provisioner) deployOhaiHints(o terraform.UIOutput, comm communicator.Communicator, hintDir string) error {
for _, hint := range p.OhaiHints {
// Open the hint file
f, err := os.Open(hint)
@ -592,7 +477,7 @@ func (p *ProvisionerS) deployOhaiHints(
return nil
}
func (p *ProvisionerS) fetchChefCertificatesFunc(
func (p *provisioner) fetchChefCertificatesFunc(
knifeCmd string,
confDir string) func(terraform.UIOutput, communicator.Communicator) error {
return func(o terraform.UIOutput, comm communicator.Communicator) error {
@ -603,10 +488,7 @@ func (p *ProvisionerS) fetchChefCertificatesFunc(
}
}
func (p *ProvisionerS) generateClientKeyFunc(
knifeCmd string,
confDir string,
noOutput string) func(terraform.UIOutput, communicator.Communicator) error {
func (p *provisioner) generateClientKeyFunc(knifeCmd string, confDir string, noOutput string) provisionFn {
return func(o terraform.UIOutput, comm communicator.Communicator) error {
options := fmt.Sprintf("-c %s -u %s --key %s",
path.Join(confDir, clienrb),
@ -664,10 +546,7 @@ func (p *ProvisionerS) generateClientKeyFunc(
}
}
func (p *ProvisionerS) configureVaultsFunc(
gemCmd string,
knifeCmd string,
confDir string) func(terraform.UIOutput, communicator.Communicator) error {
func (p *provisioner) configureVaultsFunc(gemCmd string, knifeCmd string, confDir string) provisionFn {
return func(o terraform.UIOutput, comm communicator.Communicator) error {
if err := p.runCommand(o, comm, fmt.Sprintf("%s install chef-vault", gemCmd)); err != nil {
return err
@ -679,7 +558,7 @@ func (p *ProvisionerS) configureVaultsFunc(
path.Join(confDir, p.UserName+".pem"),
)
for vault, items := range p.vaults {
for vault, items := range p.Vaults {
for _, item := range items {
updateCmd := fmt.Sprintf("%s vault update %s %s -C %s -M client %s",
knifeCmd,
@ -698,9 +577,7 @@ func (p *ProvisionerS) configureVaultsFunc(
}
}
func (p *ProvisionerS) runChefClientFunc(
chefCmd string,
confDir string) func(terraform.UIOutput, communicator.Communicator) error {
func (p *provisioner) runChefClientFunc(chefCmd string, confDir string) provisionFn {
return func(o terraform.UIOutput, comm communicator.Communicator) error {
fb := path.Join(confDir, firstBoot)
var cmd string
@ -736,7 +613,7 @@ func (p *ProvisionerS) runChefClientFunc(
}
// Output implementation of terraform.UIOutput interface
func (p *ProvisionerS) Output(output string) {
func (p *provisioner) Output(output string) {
logFile := path.Join(logfileDir, p.NodeName)
f, err := os.OpenFile(logFile, os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
@ -762,10 +639,7 @@ func (p *ProvisionerS) Output(output string) {
}
// runCommand is used to run already prepared commands
func (p *ProvisionerS) runCommand(
o terraform.UIOutput,
comm communicator.Communicator,
command string) error {
func (p *provisioner) runCommand(o terraform.UIOutput, comm communicator.Communicator, command string) error {
// Unless prevented, prefix the command with sudo
if p.useSudo {
command = "sudo " + command
@ -804,7 +678,7 @@ func (p *ProvisionerS) runCommand(
return err
}
func (p *ProvisionerS) copyOutput(o terraform.UIOutput, r io.Reader, doneCh chan<- struct{}) {
func (p *provisioner) copyOutput(o terraform.UIOutput, r io.Reader, doneCh chan<- struct{}) {
defer close(doneCh)
lr := linereader.New(r)
for line := range lr.Ch {
@ -830,9 +704,8 @@ func retryFunc(timeout time.Duration, f func() error) error {
}
}
func decodeDataToProvisioner(d *schema.ResourceData) *ProvisionerS {
return &ProvisionerS{
AttributesJSON: d.Get("attributes_json").(string),
func decodeConfig(d *schema.ResourceData) (*provisioner, error) {
p := &provisioner{
ClientOptions: getStringList(d.Get("client_options")),
DisableReporting: d.Get("disable_reporting").(bool),
Environment: d.Get("environment").(string),
@ -858,13 +731,54 @@ func decodeDataToProvisioner(d *schema.ResourceData) *ProvisionerS {
SSLVerifyMode: d.Get("ssl_verify_mode").(string),
UserName: d.Get("user_name").(string),
UserKey: d.Get("user_key").(string),
VaultJSON: d.Get("vault_json").(string),
Version: d.Get("version").(string),
// Deprecated
ValidationClientName: d.Get("validation_client_name").(string),
ValidationKey: d.Get("validation_key").(string),
}
// Make sure the supplied URL has a trailing slash
p.ServerURL = strings.TrimSuffix(p.ServerURL, "/") + "/"
for i, hint := range p.OhaiHints {
hintPath, err := homedir.Expand(hint)
if err != nil {
return nil, fmt.Errorf("Error expanding the path %s: %v", hint, err)
}
p.OhaiHints[i] = hintPath
}
if attrs, ok := d.GetOk("attributes_json"); ok {
var m map[string]interface{}
if err := json.Unmarshal([]byte(attrs.(string)), &m); err != nil {
return nil, fmt.Errorf("Error parsing attributes_json: %v", err)
}
p.Attributes = m
}
if vaults, ok := d.GetOk("vault_json"); ok {
var m map[string]interface{}
if err := json.Unmarshal([]byte(vaults.(string)), &m); err != nil {
return nil, fmt.Errorf("Error parsing vault_json: %v", err)
}
v := make(map[string][]string)
for vault, items := range m {
switch items := items.(type) {
case []interface{}:
for _, item := range items {
if item, ok := item.(string); ok {
v[vault] = append(v[vault], item)
}
}
case interface{}:
if item, ok := items.(string); ok {
v[vault] = append(v[vault], item)
}
}
}
p.Vaults = v
}
return p, nil
}
func getStringList(v interface{}) []string {

View File

@ -30,8 +30,8 @@ func TestResourceProvider_Validate_good(t *testing.T) {
"user_name": "bob",
"user_key": "USER-KEY",
})
r := Provisioner()
warn, errs := r.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -44,8 +44,8 @@ func TestResourceProvider_Validate_bad(t *testing.T) {
c := testConfig(t, map[string]interface{}{
"invalid": "nope",
})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -66,8 +66,8 @@ func TestResourceProvider_Validate_computedValues(t *testing.T) {
"user_key": "USER-KEY",
"attributes_json": config.UnknownVariableValue,
})
r := Provisioner()
warn, errs := r.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -76,30 +76,21 @@ func TestResourceProvider_Validate_computedValues(t *testing.T) {
}
}
func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig {
r, err := config.NewRawConfig(c)
if err != nil {
t.Fatalf("bad: %s", err)
}
return terraform.NewResourceConfig(r)
}
func TestResourceProvider_runChefClient(t *testing.T) {
cases := map[string]struct {
Config *terraform.ResourceConfig
Config map[string]interface{}
ChefCmd string
ConfDir string
Commands map[string]bool
}{
"Sudo": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"run_list": []interface{}{"cookbook::recipe"},
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
ChefCmd: linuxChefCmd,
@ -113,14 +104,14 @@ func TestResourceProvider_runChefClient(t *testing.T) {
},
"NoSudo": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"prevent_sudo": true,
"run_list": []interface{}{"cookbook::recipe"},
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
ChefCmd: linuxChefCmd,
@ -134,7 +125,7 @@ func TestResourceProvider_runChefClient(t *testing.T) {
},
"Environment": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"environment": "production",
"node_name": "nodename1",
"prevent_sudo": true,
@ -142,7 +133,7 @@ func TestResourceProvider_runChefClient(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
ChefCmd: windowsChefCmd,
@ -162,7 +153,9 @@ func TestResourceProvider_runChefClient(t *testing.T) {
for k, tc := range cases {
c.Commands = tc.Commands
p, err := decodeConfig(getTestResourceData(tc.Config))
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}
@ -179,20 +172,20 @@ func TestResourceProvider_runChefClient(t *testing.T) {
func TestResourceProvider_fetchChefCertificates(t *testing.T) {
cases := map[string]struct {
Config *terraform.ResourceConfig
Config map[string]interface{}
KnifeCmd string
ConfDir string
Commands map[string]bool
}{
"Sudo": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"fetch_chef_certificates": true,
"node_name": "nodename1",
"run_list": []interface{}{"cookbook::recipe"},
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
KnifeCmd: linuxKnifeCmd,
@ -206,7 +199,7 @@ func TestResourceProvider_fetchChefCertificates(t *testing.T) {
},
"NoSudo": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"fetch_chef_certificates": true,
"node_name": "nodename1",
"prevent_sudo": true,
@ -214,7 +207,7 @@ func TestResourceProvider_fetchChefCertificates(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
KnifeCmd: windowsKnifeCmd,
@ -234,7 +227,9 @@ func TestResourceProvider_fetchChefCertificates(t *testing.T) {
for k, tc := range cases {
c.Commands = tc.Commands
p, err := decodeConfig(getTestResourceData(tc.Config))
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}
@ -251,14 +246,14 @@ func TestResourceProvider_fetchChefCertificates(t *testing.T) {
func TestResourceProvider_configureVaults(t *testing.T) {
cases := map[string]struct {
Config *terraform.ResourceConfig
Config map[string]interface{}
GemCmd string
KnifeCmd string
ConfDir string
Commands map[string]bool
}{
"Linux Vault string": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"prevent_sudo": true,
"run_list": []interface{}{"cookbook::recipe"},
@ -266,7 +261,7 @@ func TestResourceProvider_configureVaults(t *testing.T) {
"user_name": "bob",
"user_key": "USER-KEY",
"vault_json": `{"vault1": "item1"}`,
}),
},
GemCmd: linuxGemCmd,
KnifeCmd: linuxKnifeCmd,
@ -280,7 +275,7 @@ func TestResourceProvider_configureVaults(t *testing.T) {
},
"Linux Vault []string": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"fetch_chef_certificates": true,
"node_name": "nodename1",
"prevent_sudo": true,
@ -289,7 +284,7 @@ func TestResourceProvider_configureVaults(t *testing.T) {
"user_name": "bob",
"user_key": "USER-KEY",
"vault_json": `{"vault1": ["item1", "item2"]}`,
}),
},
GemCmd: linuxGemCmd,
KnifeCmd: linuxKnifeCmd,
@ -305,7 +300,7 @@ func TestResourceProvider_configureVaults(t *testing.T) {
},
"Windows Vault string": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"prevent_sudo": true,
"run_list": []interface{}{"cookbook::recipe"},
@ -313,7 +308,7 @@ func TestResourceProvider_configureVaults(t *testing.T) {
"user_name": "bob",
"user_key": "USER-KEY",
"vault_json": `{"vault1": "item1"}`,
}),
},
GemCmd: windowsGemCmd,
KnifeCmd: windowsKnifeCmd,
@ -327,7 +322,7 @@ func TestResourceProvider_configureVaults(t *testing.T) {
},
"Windows Vault []string": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"fetch_chef_certificates": true,
"node_name": "nodename1",
"prevent_sudo": true,
@ -336,7 +331,7 @@ func TestResourceProvider_configureVaults(t *testing.T) {
"user_name": "bob",
"user_key": "USER-KEY",
"vault_json": `{"vault1": ["item1", "item2"]}`,
}),
},
GemCmd: windowsGemCmd,
KnifeCmd: windowsKnifeCmd,
@ -358,7 +353,9 @@ func TestResourceProvider_configureVaults(t *testing.T) {
for k, tc := range cases {
c.Commands = tc.Commands
p, err := decodeConfig(getTestResourceData(tc.Config))
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}
@ -373,6 +370,11 @@ func TestResourceProvider_configureVaults(t *testing.T) {
}
}
func getTestResourceData(c *terraform.ResourceConfig) *schema.ResourceData {
return schema.TestResourceDataConfig(Provisioner().(*schema.Provisioner).Schema, c)
func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig {
r, err := config.NewRawConfig(c)
if err != nil {
t.Fatalf("bad: %s", err)
}
return terraform.NewResourceConfig(r)
}

View File

@ -46,9 +46,7 @@ Write-Host 'Installing Chef Client...'
Start-Process -FilePath msiexec -ArgumentList /qn, /i, $dest -Wait
`
func (p *ProvisionerS) windowsInstallChefClient(
o terraform.UIOutput,
comm communicator.Communicator) error {
func (p *provisioner) windowsInstallChefClient(o terraform.UIOutput, comm communicator.Communicator) error {
script := path.Join(path.Dir(comm.ScriptPath()), "ChefClient.ps1")
content := fmt.Sprintf(installScript, p.Version, p.HTTPProxy, strings.Join(p.NOProxy, ","))
@ -62,9 +60,7 @@ func (p *ProvisionerS) windowsInstallChefClient(
return p.runCommand(o, comm, installCmd)
}
func (p *ProvisionerS) windowsCreateConfigFiles(
o terraform.UIOutput,
comm communicator.Communicator) error {
func (p *provisioner) windowsCreateConfigFiles(o terraform.UIOutput, comm communicator.Communicator) error {
// Make sure the config directory exists
cmd := fmt.Sprintf("cmd /c if not exist %q mkdir %q", windowsConfDir, windowsConfDir)
if err := p.runCommand(o, comm, cmd); err != nil {

View File

@ -6,23 +6,24 @@ import (
"testing"
"github.com/hashicorp/terraform/communicator"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)
func TestResourceProvider_windowsInstallChefClient(t *testing.T) {
cases := map[string]struct {
Config *terraform.ResourceConfig
Config map[string]interface{}
Commands map[string]bool
UploadScripts map[string]string
}{
"Default": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"run_list": []interface{}{"cookbook::recipe"},
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"powershell -NoProfile -ExecutionPolicy Bypass -File ChefClient.ps1": true,
@ -34,7 +35,7 @@ func TestResourceProvider_windowsInstallChefClient(t *testing.T) {
},
"Proxy": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"http_proxy": "http://proxy.local",
"no_proxy": []interface{}{"http://local.local", "http://local.org"},
"node_name": "nodename1",
@ -42,7 +43,7 @@ func TestResourceProvider_windowsInstallChefClient(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
"powershell -NoProfile -ExecutionPolicy Bypass -File ChefClient.ps1": true,
@ -54,14 +55,14 @@ func TestResourceProvider_windowsInstallChefClient(t *testing.T) {
},
"Version": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"node_name": "nodename1",
"run_list": []interface{}{"cookbook::recipe"},
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
"version": "11.18.6",
}),
},
Commands: map[string]bool{
"powershell -NoProfile -ExecutionPolicy Bypass -File ChefClient.ps1": true,
@ -80,7 +81,9 @@ func TestResourceProvider_windowsInstallChefClient(t *testing.T) {
c.Commands = tc.Commands
c.UploadScripts = tc.UploadScripts
p, err := decodeConfig(getTestResourceData(tc.Config))
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}
@ -96,12 +99,12 @@ func TestResourceProvider_windowsInstallChefClient(t *testing.T) {
func TestResourceProvider_windowsCreateConfigFiles(t *testing.T) {
cases := map[string]struct {
Config *terraform.ResourceConfig
Config map[string]interface{}
Commands map[string]bool
Uploads map[string]string
}{
"Default": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"ohai_hints": []interface{}{"test-fixtures/ohaihint.json"},
"node_name": "nodename1",
"run_list": []interface{}{"cookbook::recipe"},
@ -109,7 +112,7 @@ func TestResourceProvider_windowsCreateConfigFiles(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
fmt.Sprintf("cmd /c if not exist %q mkdir %q", windowsConfDir, windowsConfDir): true,
@ -128,7 +131,7 @@ func TestResourceProvider_windowsCreateConfigFiles(t *testing.T) {
},
"Proxy": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"http_proxy": "http://proxy.local",
"https_proxy": "https://proxy.local",
"no_proxy": []interface{}{"http://local.local", "https://local.local"},
@ -139,7 +142,7 @@ func TestResourceProvider_windowsCreateConfigFiles(t *testing.T) {
"ssl_verify_mode": "verify_none",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
fmt.Sprintf("cmd /c if not exist %q mkdir %q", windowsConfDir, windowsConfDir): true,
@ -154,7 +157,7 @@ func TestResourceProvider_windowsCreateConfigFiles(t *testing.T) {
},
"Attributes JSON": {
Config: testConfig(t, map[string]interface{}{
Config: map[string]interface{}{
"attributes_json": `{"key1":{"subkey1":{"subkey2a":["val1","val2","val3"],` +
`"subkey2b":{"subkey3":"value3"}}},"key2":"value2"}`,
"node_name": "nodename1",
@ -163,7 +166,7 @@ func TestResourceProvider_windowsCreateConfigFiles(t *testing.T) {
"server_url": "https://chef.local",
"user_name": "bob",
"user_key": "USER-KEY",
}),
},
Commands: map[string]bool{
fmt.Sprintf("cmd /c if not exist %q mkdir %q", windowsConfDir, windowsConfDir): true,
@ -186,7 +189,9 @@ func TestResourceProvider_windowsCreateConfigFiles(t *testing.T) {
c.Commands = tc.Commands
c.Uploads = tc.Uploads
p, err := decodeConfig(getTestResourceData(tc.Config))
p, err := decodeConfig(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
)
if err != nil {
t.Fatalf("Error: %v", err)
}

View File

@ -36,7 +36,7 @@ func Provisioner() terraform.ResourceProvisioner {
},
ApplyFunc: applyFn,
ValidateFunc: Validate,
ValidateFunc: validateFn,
}
}
@ -78,8 +78,7 @@ func applyFn(ctx context.Context) error {
}
}
// Validate checks if the required arguments are configured
func Validate(d *schema.ResourceData) (ws []string, es []error) {
func validateFn(d *schema.ResourceData) (ws []string, es []error) {
numSrc := 0
if _, ok := d.GetOk("source"); ok == true {
numSrc++

View File

@ -23,8 +23,8 @@ func TestResourceProvider_Validate_good_source(t *testing.T) {
"source": "/tmp/foo",
"destination": "/tmp/bar",
})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -38,8 +38,8 @@ func TestResourceProvider_Validate_good_content(t *testing.T) {
"content": "value to copy",
"destination": "/tmp/bar",
})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -52,8 +52,8 @@ func TestResourceProvider_Validate_bad_not_destination(t *testing.T) {
c := testConfig(t, map[string]interface{}{
"source": "nope",
})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -66,8 +66,8 @@ func TestResourceProvider_Validate_bad_no_source(t *testing.T) {
c := testConfig(t, map[string]interface{}{
"destination": "/tmp/bar",
})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -82,8 +82,8 @@ func TestResourceProvider_Validate_bad_to_many_src(t *testing.T) {
"content": "value to copy",
"destination": "/tmp/bar",
})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -92,12 +92,11 @@ func TestResourceProvider_Validate_bad_to_many_src(t *testing.T) {
}
}
func testConfig(
t *testing.T,
c map[string]interface{}) *terraform.ResourceConfig {
func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig {
r, err := config.NewRawConfig(c)
if err != nil {
t.Fatalf("bad: %s", err)
}
return terraform.NewResourceConfig(r)
}

View File

@ -30,6 +30,7 @@ func TestResourceProvider_Apply(t *testing.T) {
output := new(terraform.MockUIOutput)
p := Provisioner()
if err := p.Apply(output, nil, c); err != nil {
t.Fatalf("err: %v", err)
}
@ -84,8 +85,8 @@ func TestResourceProvider_Validate_good(t *testing.T) {
c := testConfig(t, map[string]interface{}{
"command": "echo foo",
})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -96,8 +97,8 @@ func TestResourceProvider_Validate_good(t *testing.T) {
func TestResourceProvider_Validate_missing(t *testing.T) {
c := testConfig(t, map[string]interface{}{})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -106,9 +107,7 @@ func TestResourceProvider_Validate_missing(t *testing.T) {
}
}
func testConfig(
t *testing.T,
c map[string]interface{}) *terraform.ResourceConfig {
func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig {
r, err := config.NewRawConfig(c)
if err != nil {
t.Fatalf("bad: %s", err)

View File

@ -30,8 +30,8 @@ func TestResourceProvider_Validate_good(t *testing.T) {
c := testConfig(t, map[string]interface{}{
"inline": "echo foo",
})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -44,8 +44,8 @@ func TestResourceProvider_Validate_bad(t *testing.T) {
c := testConfig(t, map[string]interface{}{
"invalid": "nope",
})
p := Provisioner()
warn, errs := p.Validate(c)
warn, errs := Provisioner().Validate(c)
if len(warn) > 0 {
t.Fatalf("Warnings: %v", warn)
}
@ -60,7 +60,6 @@ exit 0
`
func TestResourceProvider_generateScript(t *testing.T) {
p := Provisioner().(*schema.Provisioner)
conf := map[string]interface{}{
"inline": []interface{}{
"cd /tmp",
@ -68,8 +67,10 @@ func TestResourceProvider_generateScript(t *testing.T) {
"exit 0",
},
}
out, err := generateScripts(schema.TestResourceDataRaw(
t, p.Schema, conf))
out, err := generateScripts(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, conf),
)
if err != nil {
t.Fatalf("err: %v", err)
}
@ -101,7 +102,6 @@ func TestResourceProvider_generateScriptEmptyInline(t *testing.T) {
}
func TestResourceProvider_CollectScripts_inline(t *testing.T) {
p := Provisioner().(*schema.Provisioner)
conf := map[string]interface{}{
"inline": []interface{}{
"cd /tmp",
@ -110,8 +110,9 @@ func TestResourceProvider_CollectScripts_inline(t *testing.T) {
},
}
scripts, err := collectScripts(schema.TestResourceDataRaw(
t, p.Schema, conf))
scripts, err := collectScripts(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, conf),
)
if err != nil {
t.Fatalf("err: %v", err)
}
@ -132,13 +133,13 @@ func TestResourceProvider_CollectScripts_inline(t *testing.T) {
}
func TestResourceProvider_CollectScripts_script(t *testing.T) {
p := Provisioner().(*schema.Provisioner)
conf := map[string]interface{}{
"script": "test-fixtures/script1.sh",
}
scripts, err := collectScripts(schema.TestResourceDataRaw(
t, p.Schema, conf))
scripts, err := collectScripts(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, conf),
)
if err != nil {
t.Fatalf("err: %v", err)
}
@ -159,7 +160,6 @@ func TestResourceProvider_CollectScripts_script(t *testing.T) {
}
func TestResourceProvider_CollectScripts_scripts(t *testing.T) {
p := Provisioner().(*schema.Provisioner)
conf := map[string]interface{}{
"scripts": []interface{}{
"test-fixtures/script1.sh",
@ -168,8 +168,9 @@ func TestResourceProvider_CollectScripts_scripts(t *testing.T) {
},
}
scripts, err := collectScripts(schema.TestResourceDataRaw(
t, p.Schema, conf))
scripts, err := collectScripts(
schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, conf),
)
if err != nil {
t.Fatalf("err: %v", err)
}
@ -234,9 +235,7 @@ func TestRetryFunc(t *testing.T) {
}
}
func testConfig(
t *testing.T,
c map[string]interface{}) *terraform.ResourceConfig {
func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig {
r, err := config.NewRawConfig(c)
if err != nil {
t.Fatalf("bad: %s", err)

View File

@ -41,9 +41,8 @@ type Provisioner struct {
// information.
ApplyFunc func(ctx context.Context) error
// ValidateFunc is the function for extended validation. This is optional.
// It is given a resource data.
// Should be provided when Scheme is not enough.
// ValidateFunc is a function for extended validation. This is optional
// and should be used when individual field validation is not enough.
ValidateFunc func(*ResourceData) ([]string, []error)
stopCtx context.Context

View File

@ -28,10 +28,3 @@ func TestResourceDataRaw(
return result
}
func TestResourceDataConfig(schema map[string]*Schema, config *terraform.ResourceConfig) *ResourceData {
return &ResourceData{
schema: schema,
config: config,
}
}

View File

@ -157,9 +157,3 @@ The following arguments are supported:
* `version (string)` - (Optional) The Chef Client version to install on the remote machine.
If not set, the latest available version will be installed.
These options are supported for backwards compatibility and may be removed in a
future version:
* `validation_client_name (string)` - __Deprecated: please use `user_name` instead__.
* `validation_key (string)` - __Deprecated: please use `user_key` instead__.