add execution policy type and use it to default the powershell cmd
This commit is contained in:
parent
2da36b7374
commit
e96409954a
|
@ -23,6 +23,14 @@ type DecodeOpts struct {
|
||||||
Interpolate bool
|
Interpolate bool
|
||||||
InterpolateContext *interpolate.Context
|
InterpolateContext *interpolate.Context
|
||||||
InterpolateFilter *interpolate.RenderFilter
|
InterpolateFilter *interpolate.RenderFilter
|
||||||
|
|
||||||
|
DecodeHooks []mapstructure.DecodeHookFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
var DefaultDecodeHookFuncs = []mapstructure.DecodeHookFunc{
|
||||||
|
uint8ToStringHook,
|
||||||
|
mapstructure.StringToSliceHookFunc(","),
|
||||||
|
mapstructure.StringToTimeDurationHookFunc(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes the configuration into the target and optionally
|
// Decode decodes the configuration into the target and optionally
|
||||||
|
@ -60,17 +68,18 @@ func Decode(target interface{}, config *DecodeOpts, raws ...interface{}) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decodeHookFuncs := DefaultDecodeHookFuncs
|
||||||
|
if len(config.DecodeHooks) != 0 {
|
||||||
|
decodeHookFuncs = config.DecodeHooks
|
||||||
|
}
|
||||||
|
|
||||||
// Build our decoder
|
// Build our decoder
|
||||||
var md mapstructure.Metadata
|
var md mapstructure.Metadata
|
||||||
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||||
Result: target,
|
Result: target,
|
||||||
Metadata: &md,
|
Metadata: &md,
|
||||||
WeaklyTypedInput: true,
|
WeaklyTypedInput: true,
|
||||||
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
DecodeHook: mapstructure.ComposeDecodeHookFunc(decodeHookFuncs...),
|
||||||
uint8ToStringHook,
|
|
||||||
mapstructure.StringToSliceHookFunc(","),
|
|
||||||
mapstructure.StringToTimeDurationHookFunc(),
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package powershell
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExecutionPolicy setting to run the command(s).
|
||||||
|
// For the powershell provider the default has historically been to bypass.
|
||||||
|
type ExecutionPolicy int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Bypass ExecutionPolicy = 0
|
||||||
|
AllSigned ExecutionPolicy = 1
|
||||||
|
Default ExecutionPolicy = 2
|
||||||
|
RemoteSigned ExecutionPolicy = 3
|
||||||
|
Restricted ExecutionPolicy = 4
|
||||||
|
Undefined ExecutionPolicy = 5
|
||||||
|
Unrestricted ExecutionPolicy = 6
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ep *ExecutionPolicy) Decode(v interface{}) (err error) {
|
||||||
|
str, ok := v.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("%#v is not a string", v)
|
||||||
|
}
|
||||||
|
*ep, err = ExecutionPolicyString(str)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringToExecutionPolicyHook(f reflect.Kind, t reflect.Kind, data interface{}) (interface{}, error) {
|
||||||
|
if f != reflect.String || t != reflect.Int {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
raw := data.(string)
|
||||||
|
return ExecutionPolicyString(raw)
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package powershell
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExecutionPolicy_Decode(t *testing.T) {
|
||||||
|
config := map[string]interface{}{
|
||||||
|
"inline": []interface{}{"foo", "bar"},
|
||||||
|
"execution_policy": "AllSigned",
|
||||||
|
}
|
||||||
|
p := new(Provisioner)
|
||||||
|
err := p.Prepare(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.config.ExecutionPolicy != AllSigned {
|
||||||
|
t.Fatalf("Expected AllSigned execution policy; got: %s", p.config.ExecutionPolicy)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
// Code generated by "enumer -type ExecutionPolicy provisioner/powershell/execution_policy.go"; DO NOT EDIT.
|
||||||
|
|
||||||
|
//
|
||||||
|
package powershell
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const _ExecutionPolicyName = "BypassAllSignedDefaultRemoteSignedRestrictedUndefinedUnrestricted"
|
||||||
|
|
||||||
|
var _ExecutionPolicyIndex = [...]uint8{0, 6, 15, 22, 34, 44, 53, 65}
|
||||||
|
|
||||||
|
func (i ExecutionPolicy) String() string {
|
||||||
|
if i < 0 || i >= ExecutionPolicy(len(_ExecutionPolicyIndex)-1) {
|
||||||
|
return fmt.Sprintf("ExecutionPolicy(%d)", i)
|
||||||
|
}
|
||||||
|
return _ExecutionPolicyName[_ExecutionPolicyIndex[i]:_ExecutionPolicyIndex[i+1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ExecutionPolicyValues = []ExecutionPolicy{0, 1, 2, 3, 4, 5, 6}
|
||||||
|
|
||||||
|
var _ExecutionPolicyNameToValueMap = map[string]ExecutionPolicy{
|
||||||
|
_ExecutionPolicyName[0:6]: 0,
|
||||||
|
_ExecutionPolicyName[6:15]: 1,
|
||||||
|
_ExecutionPolicyName[15:22]: 2,
|
||||||
|
_ExecutionPolicyName[22:34]: 3,
|
||||||
|
_ExecutionPolicyName[34:44]: 4,
|
||||||
|
_ExecutionPolicyName[44:53]: 5,
|
||||||
|
_ExecutionPolicyName[53:65]: 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecutionPolicyString retrieves an enum value from the enum constants string name.
|
||||||
|
// Throws an error if the param is not part of the enum.
|
||||||
|
func ExecutionPolicyString(s string) (ExecutionPolicy, error) {
|
||||||
|
if val, ok := _ExecutionPolicyNameToValueMap[s]; ok {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("%s does not belong to ExecutionPolicy values", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecutionPolicyValues returns all values of the enum
|
||||||
|
func ExecutionPolicyValues() []ExecutionPolicy {
|
||||||
|
return _ExecutionPolicyValues
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAExecutionPolicy returns "true" if the value is listed in the enum definition. "false" otherwise
|
||||||
|
func (i ExecutionPolicy) IsAExecutionPolicy() bool {
|
||||||
|
for _, v := range _ExecutionPolicyValues {
|
||||||
|
if i == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
|
@ -66,6 +66,8 @@ type Config struct {
|
||||||
ElevatedUser string `mapstructure:"elevated_user"`
|
ElevatedUser string `mapstructure:"elevated_user"`
|
||||||
ElevatedPassword string `mapstructure:"elevated_password"`
|
ElevatedPassword string `mapstructure:"elevated_password"`
|
||||||
|
|
||||||
|
ExecutionPolicy ExecutionPolicy `mapstructure:"execution_policy"`
|
||||||
|
|
||||||
ctx interpolate.Context
|
ctx interpolate.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +86,13 @@ type EnvVarsTemplate struct {
|
||||||
WinRMPassword string
|
WinRMPassword string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provisioner) defaultExecuteCommand() string {
|
||||||
|
return `powershell -executionpolicy ` + p.config.ExecutionPolicy.String() +
|
||||||
|
` "& { if (Test-Path variable:global:ProgressPreference)` +
|
||||||
|
`{set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};` +
|
||||||
|
`. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"`
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provisioner) Prepare(raws ...interface{}) error {
|
func (p *Provisioner) Prepare(raws ...interface{}) error {
|
||||||
// Create passthrough for winrm password so we can fill it in once we know
|
// Create passthrough for winrm password so we can fill it in once we know
|
||||||
// it
|
// it
|
||||||
|
@ -100,6 +109,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
||||||
"elevated_execute_command",
|
"elevated_execute_command",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
DecodeHooks: append(config.DefaultDecodeHookFuncs, StringToExecutionPolicyHook),
|
||||||
}, raws...)
|
}, raws...)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -115,11 +125,11 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.config.ExecuteCommand == "" {
|
if p.config.ExecuteCommand == "" {
|
||||||
p.config.ExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"`
|
p.config.ExecuteCommand = p.defaultExecuteCommand()
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.config.ElevatedExecuteCommand == "" {
|
if p.config.ElevatedExecuteCommand == "" {
|
||||||
p.config.ElevatedExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"`
|
p.config.ElevatedExecuteCommand = p.defaultExecuteCommand()
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.config.Inline != nil && len(p.config.Inline) == 0 {
|
if p.config.Inline != nil && len(p.config.Inline) == 0 {
|
||||||
|
@ -272,6 +282,8 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
|
||||||
// Close the original file since we copied it
|
// Close the original file since we copied it
|
||||||
f.Close()
|
f.Close()
|
||||||
|
|
||||||
|
log.Printf("%s returned with exit code %d", p.config.RemotePath, cmd.ExitStatus())
|
||||||
|
|
||||||
if err := p.config.ValidExitCode(cmd.ExitStatus()); err != nil {
|
if err := p.config.ValidExitCode(cmd.ExitStatus()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue