Refactor the code a bit to make it more idiomatic
This commit is contained in:
parent
2f4067cf70
commit
a614056925
|
@ -106,7 +106,7 @@ type provisioner struct {
|
||||||
OSType string
|
OSType string
|
||||||
RecreateClient bool
|
RecreateClient bool
|
||||||
PreventSudo bool
|
PreventSudo bool
|
||||||
RetryOnExitCode []int
|
RetryOnExitCode map[int]bool
|
||||||
RunList []string
|
RunList []string
|
||||||
SecretKey string
|
SecretKey string
|
||||||
ServerURL string
|
ServerURL string
|
||||||
|
@ -117,7 +117,7 @@ type provisioner struct {
|
||||||
UserKey string
|
UserKey string
|
||||||
Vaults map[string][]string
|
Vaults map[string][]string
|
||||||
Version string
|
Version string
|
||||||
WaitForRetry int
|
WaitForRetry time.Duration
|
||||||
|
|
||||||
cleanupUserKeyCmd string
|
cleanupUserKeyCmd string
|
||||||
createConfigFiles provisionFn
|
createConfigFiles provisionFn
|
||||||
|
@ -334,10 +334,6 @@ func applyFn(ctx context.Context) error {
|
||||||
retryCtx, cancel := context.WithTimeout(ctx, comm.Timeout())
|
retryCtx, cancel := context.WithTimeout(ctx, comm.Timeout())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Graceful retry of RFC062 exit codes
|
|
||||||
var attempt int
|
|
||||||
retry:
|
|
||||||
|
|
||||||
// Wait and retry until we establish the connection
|
// Wait and retry until we establish the connection
|
||||||
err = communicator.Retry(retryCtx, func() error {
|
err = communicator.Retry(retryCtx, func() error {
|
||||||
return comm.Connect(o)
|
return comm.Connect(o)
|
||||||
|
@ -357,55 +353,65 @@ retry:
|
||||||
}
|
}
|
||||||
defer once.Do(cleanupUserKey)
|
defer once.Do(cleanupUserKey)
|
||||||
|
|
||||||
if attempt == 0 {
|
if !p.SkipInstall {
|
||||||
if !p.SkipInstall {
|
if err := p.installChefClient(o, comm); err != nil {
|
||||||
if err := p.installChefClient(o, comm); err != nil {
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
o.Output("Creating configuration files...")
|
||||||
|
if err := p.createConfigFiles(o, comm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !p.SkipRegister {
|
||||||
|
if p.FetchChefCertificates {
|
||||||
|
o.Output("Fetch Chef certificates...")
|
||||||
|
if err := p.fetchChefCertificates(o, comm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
o.Output("Creating configuration files...")
|
o.Output("Generate the private key...")
|
||||||
if err := p.createConfigFiles(o, comm); err != nil {
|
if err := p.generateClientKey(o, comm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Vaults != nil {
|
||||||
|
o.Output("Configure Chef vaults...")
|
||||||
|
if err := p.configureVaults(o, comm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup the user key before we run Chef-Client to prevent issues
|
||||||
|
// with rights caused by changing settings during the run.
|
||||||
|
once.Do(cleanupUserKey)
|
||||||
|
|
||||||
|
o.Output("Starting initial Chef-Client run...")
|
||||||
|
|
||||||
|
for attempt := 0; attempt < p.MaxRetries; attempt++ {
|
||||||
|
// Make sure to (re)connect before trying to run Chef-Client.
|
||||||
|
if err := communicator.Retry(retryCtx, func() error {
|
||||||
|
return comm.Connect(o)
|
||||||
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !p.SkipRegister {
|
err = p.runChefClient(o, comm)
|
||||||
if p.FetchChefCertificates {
|
if err == nil {
|
||||||
o.Output("Fetch Chef certificates...")
|
return nil
|
||||||
if err := p.fetchChefCertificates(o, comm); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
o.Output("Generate the private key...")
|
|
||||||
if err := p.generateClientKey(o, comm); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Vaults != nil {
|
// Allow RFC062 Exit Codes:
|
||||||
o.Output("Configure Chef vaults...")
|
|
||||||
if err := p.configureVaults(o, comm); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup the user key before we run Chef-Client to prevent issues
|
|
||||||
// with rights caused by changing settings during the run.
|
|
||||||
once.Do(cleanupUserKey)
|
|
||||||
|
|
||||||
o.Output("Starting initial Chef-Client run...")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := p.runChefClient(o, comm); err != nil {
|
|
||||||
// Allow RFC062 Exit Codes
|
|
||||||
// https://github.com/chef/chef-rfc/blob/master/rfc062-exit-status.md
|
// https://github.com/chef/chef-rfc/blob/master/rfc062-exit-status.md
|
||||||
exitError, ok := err.(*remote.ExitError)
|
exitError, ok := err.(*remote.ExitError)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Expected remote.ExitError but got: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
exitStatus := exitError.ExitStatus
|
|
||||||
switch exitStatus {
|
switch exitError.ExitStatus {
|
||||||
case 35:
|
case 35:
|
||||||
o.Output("Reboot has been scheduled in the run state")
|
o.Output("Reboot has been scheduled in the run state")
|
||||||
err = nil
|
err = nil
|
||||||
|
@ -417,23 +423,13 @@ retry:
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(p.RetryOnExitCode) == 0 || attempt == p.MaxRetries {
|
if p.RetryOnExitCode[exitError.ExitStatus] {
|
||||||
return err
|
o.Output(fmt.Sprintf("Waiting %s before retrying Chef-Client run...", p.WaitForRetry))
|
||||||
|
time.Sleep(p.WaitForRetry)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, code := range p.RetryOnExitCode {
|
|
||||||
if code == exitStatus {
|
|
||||||
o.Output(fmt.Sprintf("Waiting %v seconds before reconnecting & re-running Chef...", p.WaitForRetry))
|
|
||||||
time.Sleep(time.Duration(p.WaitForRetry) * time.Second)
|
|
||||||
attempt++
|
|
||||||
goto retry
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateFn(c *terraform.ResourceConfig) (ws []string, es []error) {
|
func validateFn(c *terraform.ResourceConfig) (ws []string, es []error) {
|
||||||
|
@ -795,7 +791,7 @@ func decodeConfig(d *schema.ResourceData) (*provisioner, error) {
|
||||||
OSType: d.Get("os_type").(string),
|
OSType: d.Get("os_type").(string),
|
||||||
RecreateClient: d.Get("recreate_client").(bool),
|
RecreateClient: d.Get("recreate_client").(bool),
|
||||||
PreventSudo: d.Get("prevent_sudo").(bool),
|
PreventSudo: d.Get("prevent_sudo").(bool),
|
||||||
RetryOnExitCode: getIntList(d.Get("retry_on_exit_code")),
|
RetryOnExitCode: getIntListAsMap(d.Get("retry_on_exit_code")),
|
||||||
RunList: getStringList(d.Get("run_list")),
|
RunList: getStringList(d.Get("run_list")),
|
||||||
SecretKey: d.Get("secret_key").(string),
|
SecretKey: d.Get("secret_key").(string),
|
||||||
ServerURL: d.Get("server_url").(string),
|
ServerURL: d.Get("server_url").(string),
|
||||||
|
@ -805,7 +801,7 @@ func decodeConfig(d *schema.ResourceData) (*provisioner, error) {
|
||||||
UserName: d.Get("user_name").(string),
|
UserName: d.Get("user_name").(string),
|
||||||
UserKey: d.Get("user_key").(string),
|
UserKey: d.Get("user_key").(string),
|
||||||
Version: d.Get("version").(string),
|
Version: d.Get("version").(string),
|
||||||
WaitForRetry: d.Get("wait_for_retry").(int),
|
WaitForRetry: time.Duration(d.Get("wait_for_retry").(int)) * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the supplied URL has a trailing slash
|
// Make sure the supplied URL has a trailing slash
|
||||||
|
@ -855,8 +851,8 @@ func decodeConfig(d *schema.ResourceData) (*provisioner, error) {
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getIntList(v interface{}) []int {
|
func getIntListAsMap(v interface{}) map[int]bool {
|
||||||
var result []int
|
result := make(map[int]bool)
|
||||||
|
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
|
@ -864,7 +860,7 @@ func getIntList(v interface{}) []int {
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
for _, vv := range v {
|
for _, vv := range v {
|
||||||
if vv, ok := vv.(int); ok {
|
if vv, ok := vv.(int); ok {
|
||||||
result = append(result, vv)
|
result[vv] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -58,7 +58,7 @@ func (c *Communicator) Connect(o terraform.UIOutput) error {
|
||||||
|
|
||||||
params := winrm.DefaultParameters
|
params := winrm.DefaultParameters
|
||||||
params.Timeout = formatDuration(c.Timeout())
|
params.Timeout = formatDuration(c.Timeout())
|
||||||
if c.connInfo.NTLM == true {
|
if c.connInfo.NTLM {
|
||||||
params.TransportDecorator = func() winrm.Transporter { return &winrm.ClientNTLM{} }
|
params.TransportDecorator = func() winrm.Transporter { return &winrm.ClientNTLM{} }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ func (c *Communicator) newCopyClient() (*winrmcp.Winrmcp, error) {
|
||||||
MaxOperationsPerShell: 15, // lowest common denominator
|
MaxOperationsPerShell: 15, // lowest common denominator
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.connInfo.NTLM == true {
|
if c.connInfo.NTLM {
|
||||||
config.TransportDecorator = func() winrm.Transporter { return &winrm.ClientNTLM{} }
|
config.TransportDecorator = func() winrm.Transporter { return &winrm.ClientNTLM{} }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,8 @@ The following arguments are supported:
|
||||||
|
|
||||||
* `https_proxy (string)` - (Optional) The proxy server for Chef Client HTTPS connections.
|
* `https_proxy (string)` - (Optional) The proxy server for Chef Client HTTPS connections.
|
||||||
|
|
||||||
* `max_retries (integer)` - (Optional) The number of times to retry the provisioning process after receiving an exit code in the `retry_on_error` list. Defaults to `1`
|
* `max_retries (integer)` - (Optional) The number of times to retry the provisioning process
|
||||||
|
after receiving an exit code in the `retry_on_error` list. Defaults to `1`
|
||||||
|
|
||||||
* `named_run_list (string)` - (Optional) The name of an alternate run-list to invoke during the
|
* `named_run_list (string)` - (Optional) The name of an alternate run-list to invoke during the
|
||||||
initial Chef Client run. The run-list must already exist in the Policyfile that defines
|
initial Chef Client run. The run-list must already exist in the Policyfile that defines
|
||||||
|
@ -135,7 +136,9 @@ The following arguments are supported:
|
||||||
* `recreate_client (boolean)` - (Optional) If `true`, first delete any existing Chef Node and
|
* `recreate_client (boolean)` - (Optional) If `true`, first delete any existing Chef Node and
|
||||||
Client before registering the new Chef Client.
|
Client before registering the new Chef Client.
|
||||||
|
|
||||||
* `retry_on_error (list of integers)` - (Optional) The error codes upon which Terraform should gracefully retry the provisioning process. Intended for use with [Chef RFC062 codes.](https://github.com/chef-boneyard/chef-rfc/blob/69a19f632cceffe965bafaad6765e3376068fd5b/rfc062-exit-status.md)
|
* `retry_on_error (list of integers)` - (Optional) The error codes upon which Terraform should
|
||||||
|
gracefully retry the provisioning process. Intended for use with
|
||||||
|
[Chef RFC062 codes](https://github.com/chef-boneyard/chef-rfc/blob/master/rfc062-exit-status.md).
|
||||||
|
|
||||||
* `run_list (array)` - (Optional) A list with recipes that will be invoked during the initial
|
* `run_list (array)` - (Optional) A list with recipes that will be invoked during the initial
|
||||||
Chef Client run. The run-list will also be saved to the Chef Server after a successful
|
Chef Client run. The run-list will also be saved to the Chef Server after a successful
|
||||||
|
@ -176,4 +179,6 @@ The following arguments are supported:
|
||||||
* `version (string)` - (Optional) The Chef Client version to install on the remote machine.
|
* `version (string)` - (Optional) The Chef Client version to install on the remote machine.
|
||||||
If not set, the latest available version will be installed.
|
If not set, the latest available version will be installed.
|
||||||
|
|
||||||
* `wait_for_retry (integer)` - (Optional) - Amount of time in seconds to wait before retrying the provisionining process after receiving an exit code in the `retry_on_error` list. Defaults to `30`.
|
* `wait_for_retry (integer)` - (Optional) - Amount of time in seconds to wait before
|
||||||
|
retrying the provisionining process after receiving an exit code in the `retry_on_error`
|
||||||
|
list. Defaults to `30`.
|
||||||
|
|
Loading…
Reference in New Issue