provisioner/powershell: Add basic Powershell provisioner acceptance tests

* Modifies the amazon-ebs builder with a windows build configuration

```
⇶  ACC_TEST_BUILDERS=amazon-ebs ACC_TEST_PROVISIONERS=powershell go test -v ./provisioner/powershell/... -run=TestPowershellProvisioner_Inline
--- PASS: TestPowershellProvisioner_Inline (256.50s)
--- PASS: TestPowershellProvisioner_Inline/testing_amazon-ebs_builder_against_powershell_provisioner (256.50s)
PASS
ok      github.com/hashicorp/packer/provisioner/powershell 256.525s
```
This commit is contained in:
Wilken Rivera 2020-04-03 14:53:32 -04:00
parent e26df90a66
commit b183c5498f
7 changed files with 195 additions and 9 deletions

View File

@ -18,18 +18,31 @@ import (
type AmazonEBSAccTest struct{} type AmazonEBSAccTest struct{}
func (s *AmazonEBSAccTest) GetConfigs() (map[string]string, error) { func (s *AmazonEBSAccTest) GetConfigs() (map[string]string, error) {
filePath := filepath.Join("../../builder/amazon/ebs/acceptance/test-fixtures/", "amazon-ebs.txt") fixtures := map[string]string{
config, err := os.Open(filePath) "linux": "amazon-ebs.txt",
if err != nil { "windows": "amazon-ebs_windows.txt",
return nil, fmt.Errorf("Expected to find %s", filePath)
} }
defer config.Close()
file, err := ioutil.ReadAll(config) configs := make(map[string]string)
if err != nil {
return nil, fmt.Errorf("Uneble to read %s", filePath) for distro, fixture := range fixtures {
fileName := fixture
filePath := filepath.Join("../../builder/amazon/ebs/acceptance/test-fixtures/", fileName)
config, err := os.Open(filePath)
if err != nil {
return nil, fmt.Errorf("Expected to find %s", filePath)
}
defer config.Close()
file, err := ioutil.ReadAll(config)
if err != nil {
return nil, fmt.Errorf("Unable to read %s", filePath)
}
configs[distro] = string(file)
} }
return map[string]string{"linux": string(file)}, nil return configs, nil
} }
func (s *AmazonEBSAccTest) CleanUp() error { func (s *AmazonEBSAccTest) CleanUp() error {

View File

@ -0,0 +1,23 @@
{
"type": "amazon-ebs",
"region": "us-east-1",
"instance_type": "t2.micro",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "*Windows_Server-2012-R2*English-64Bit-Base*",
"root-device-type": "ebs"
},
"most_recent": true,
"owners": "amazon"
},
"ami_name": "packer-acc-test",
"user_data_file": "../../builder/amazon/ebs/acceptance/test-fixtures/scripts/bootstrap_win.txt",
"communicator": "winrm",
"winrm_username": "Administrator",
"winrm_password": "SuperS3cr3t!!!!",
"force_deregister" : true,
"tags": {
"packer-test": "true"
}
}

View File

@ -0,0 +1,40 @@
<powershell>
# Set administrator password
net user Administrator SuperS3cr3t!!!!
wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE
# First, make sure WinRM can't be connected to
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block
# Delete any existing WinRM listeners
winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null
winrm delete winrm/config/listener?Address=*+Transport=HTTPS 2>$Null
# Disable group policies which block basic authentication and unencrypted login
Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Client -Name AllowBasic -Value 1
Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Client -Name AllowUnencryptedTraffic -Value 1
Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Service -Name AllowBasic -Value 1
Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Service -Name AllowUnencryptedTraffic -Value 1
# Create a new WinRM listener and configure
winrm create winrm/config/listener?Address=*+Transport=HTTP
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}'
winrm set winrm/config '@{MaxTimeoutms="7200000"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/client/auth '@{Basic="true"}'
# Configure UAC to allow privilege elevation in remote shells
$Key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
$Setting = 'LocalAccountTokenFilterPolicy'
Set-ItemProperty -Path $Key -Name $Setting -Value 1 -Force
# Configure and restart the WinRM Service; Enable the required firewall exception
Stop-Service -Name WinRM
Set-Service -Name WinRM -StartupType Automatic
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new action=allow localip=any remoteip=any
Start-Service -Name WinRM
</powershell>

View File

@ -0,0 +1,86 @@
package powershell_test
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/packer/command"
"github.com/hashicorp/packer/helper/tests/acc"
"github.com/hashicorp/packer/packer"
)
func TestPowershellProvisioner_Inline(t *testing.T) {
p := os.Getenv("ACC_TEST_PROVISIONERS")
if p != "all" && !strings.Contains(p, "powershell") {
t.Skip()
}
testProvisioner := PowershellProvisionerAccTest{"powershell-inline-provisioner.txt"}
acc.TestProvisionersAgainstBuilders(&testProvisioner, t)
}
func TestPowershellProvisioner_Script(t *testing.T) {
p := os.Getenv("ACC_TEST_PROVISIONERS")
if p != "all" && !strings.Contains(p, "powershell") {
t.Skip()
}
testProvisioner := PowershellProvisionerAccTest{"powershell-script-provisioner.txt"}
acc.TestProvisionersAgainstBuilders(&testProvisioner, t)
}
type PowershellProvisionerAccTest struct {
ConfigName string
}
func (s *PowershellProvisionerAccTest) GetName() string {
return "powershell"
}
func (s *PowershellProvisionerAccTest) GetConfig() (string, error) {
filePath := filepath.Join("./test-fixtures", s.ConfigName)
config, err := os.Open(filePath)
if err != nil {
return "", fmt.Errorf("Expected to find %s", filePath)
}
defer config.Close()
file, err := ioutil.ReadAll(config)
return string(file), nil
}
func (s *PowershellProvisionerAccTest) GetProvisionerStore() packer.MapOfProvisioner {
return packer.MapOfProvisioner{
"powershell": func() (packer.Provisioner, error) { return command.Provisioners["powershell"], nil },
}
}
func (s *PowershellProvisionerAccTest) IsCompatible(builder string, vmOS string) bool {
return vmOS == "windows"
}
func (s *PowershellProvisionerAccTest) RunTest(c *command.BuildCommand, args []string) error {
UUID := os.Getenv("PACKER_RUN_UUID")
if UUID == "" {
UUID, _ = uuid.GenerateUUID()
os.Setenv("PACKER_RUN_UUID", UUID)
}
if code := c.Run(args); code != 0 {
ui := c.Meta.Ui.(*packer.BasicUi)
out := ui.Writer.(*bytes.Buffer)
err := ui.ErrorWriter.(*bytes.Buffer)
return fmt.Errorf(
"Bad exit code.\n\nStdout:\n\n%s\n\nStderr:\n\n%s",
out.String(),
err.String())
}
return nil
}

View File

@ -0,0 +1,8 @@
{
"type": "powershell",
"environment_vars": "PackerRunUUID={{build `PackerRunUUID`}},ID={{build `ID`}}",
"inline": [
"Write-Host \"$env:ID for provisioner.$env:PackerRunUUID\""
]
}

View File

@ -0,0 +1,11 @@
{
"type": "powershell",
"script": "../../provisioner/powershell/test-fixtures/scripts/sample_script.ps1",
"environment_vars": [
"VAR1=A$Dollar",
"VAR2=A`Backtick",
"VAR3=A'SingleQuote",
"VAR4=A\"DoubleQuote"
]
}

View File

@ -0,0 +1,5 @@
write-output("packer_build_name is automatically set for you, or you can set it in your builder variables; the default for this builder is: " + $env:packer_build_name )
write-output("remember that escaping variables in powershell requires backticks; for example var1 from our config is " + $env:var1 )
write-output("likewise, var2 is " + $env:var2 )
write-output("and var3 is " + $env:var3 )