Merge pull request #9011 from hashicorp/powershell-acceptance-test

provisioner/powershell: Add basic Powershell provisioner acceptance tests
This commit is contained in:
Wilken Rivera 2020-04-07 05:40:26 -04:00 committed by GitHub
commit 1eee0bca5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 227 additions and 22 deletions

View File

@ -9,7 +9,8 @@ import (
"os"
"path/filepath"
"github.com/hashicorp/packer/command"
amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs"
"github.com/hashicorp/packer/packer"
testshelper "github.com/hashicorp/packer/helper/tests"
@ -18,7 +19,16 @@ import (
type AmazonEBSAccTest struct{}
func (s *AmazonEBSAccTest) GetConfigs() (map[string]string, error) {
filePath := filepath.Join("../../builder/amazon/ebs/acceptance/test-fixtures/", "amazon-ebs.txt")
fixtures := map[string]string{
"linux": "amazon-ebs.txt",
"windows": "amazon-ebs_windows.txt",
}
configs := make(map[string]string)
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)
@ -27,9 +37,13 @@ func (s *AmazonEBSAccTest) GetConfigs() (map[string]string, error) {
file, err := ioutil.ReadAll(config)
if err != nil {
return nil, fmt.Errorf("Uneble to read %s", filePath)
return nil, fmt.Errorf("Unable to read %s", filePath)
}
return map[string]string{"linux": string(file)}, nil
configs[distro] = string(file)
}
return configs, nil
}
func (s *AmazonEBSAccTest) CleanUp() error {
@ -42,6 +56,6 @@ func (s *AmazonEBSAccTest) CleanUp() error {
func (s *AmazonEBSAccTest) GetBuilderStore() packer.MapOfBuilder {
return packer.MapOfBuilder{
"amazon-ebs": func() (packer.Builder, error) { return command.Builders["amazon-ebs"], nil },
"amazon-ebs": func() (packer.Builder, error) { return &amazonebsbuilder.Builder{}, nil },
}
}

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

@ -9,7 +9,8 @@ import (
"os"
"path/filepath"
"github.com/hashicorp/packer/command"
"github.com/hashicorp/packer/builder/virtualbox/iso"
"github.com/hashicorp/packer/packer"
testshelper "github.com/hashicorp/packer/helper/tests"
@ -40,6 +41,6 @@ func (v *VirtualBoxISOAccTest) CleanUp() error {
func (v *VirtualBoxISOAccTest) GetBuilderStore() packer.MapOfBuilder {
return packer.MapOfBuilder{
"virtualbox-iso": func() (packer.Builder, error) { return command.Builders["virtualbox-iso"], nil },
"virtualbox-iso": func() (packer.Builder, error) { return &iso.Builder{}, nil },
}
}

View File

@ -3,13 +3,14 @@ package acc
import (
"bytes"
"fmt"
"github.com/hashicorp/packer/helper/tests"
"log"
"os"
"path/filepath"
"strings"
"testing"
testshelper "github.com/hashicorp/packer/helper/tests"
amazonEBS "github.com/hashicorp/packer/builder/amazon/ebs/acceptance"
virtualboxISO "github.com/hashicorp/packer/builder/virtualbox/iso/acceptance"
"github.com/hashicorp/packer/command"
@ -68,6 +69,26 @@ func TestProvisionersAgainstBuilders(provisionerAcc ProvisionerAcceptance, t *te
}
}
// TestProvisionersPreCheck checks if the Provisioner with name is set in ACC_TEST_PROVISIONERS environment variable
func TestProvisionersPreCheck(name string, t *testing.T) {
p := os.Getenv("ACC_TEST_PROVISIONERS")
if p == "all" {
return
}
provisioners := strings.Split(p, ",")
for _, provisioner := range provisioners {
if provisioner == name {
return
}
}
msg := fmt.Sprintf("Provisioner %q not defined in ACC_TEST_PROVISIONERS", name)
t.Skip(msg)
}
func checkBuilders(t *testing.T) []string {
b := os.Getenv("ACC_TEST_BUILDERS")
// validate if we want to run provisioners acc tests

View File

@ -0,0 +1,83 @@
package powershell_test
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/hashicorp/packer/provisioner/powershell"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/packer/command"
"github.com/hashicorp/packer/helper/tests/acc"
"github.com/hashicorp/packer/packer"
)
const TestProvisionerName = "powershell"
func TestPowershellProvisioner_Inline(t *testing.T) {
acc.TestProvisionersPreCheck(TestProvisionerName, t)
testProvisioner := PowershellProvisionerAccTest{"powershell-inline-provisioner.txt"}
acc.TestProvisionersAgainstBuilders(&testProvisioner, t)
}
func TestPowershellProvisioner_Script(t *testing.T) {
acc.TestProvisionersPreCheck(TestProvisionerName, t)
testProvisioner := PowershellProvisionerAccTest{"powershell-script-provisioner.txt"}
acc.TestProvisionersAgainstBuilders(&testProvisioner, t)
}
type PowershellProvisionerAccTest struct {
ConfigName string
}
func (s *PowershellProvisionerAccTest) GetName() string {
return TestProvisionerName
}
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{
TestProvisionerName: func() (packer.Provisioner, error) { return &powershell.Provisioner{}, 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 )

View File

@ -3,13 +3,15 @@ package shell_test
import (
"bytes"
"fmt"
"github.com/hashicorp/packer/helper/tests/acc"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/hashicorp/packer/helper/tests/acc"
"github.com/hashicorp/packer/provisioner/file"
"github.com/hashicorp/packer/provisioner/shell"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/go-uuid"
@ -18,10 +20,7 @@ import (
)
func TestShellProvisioner(t *testing.T) {
p := os.Getenv("ACC_TEST_PROVISIONERS")
if p != "all" && !strings.Contains(p, "shell") {
t.Skip()
}
acc.TestProvisionersPreCheck("shell", t)
acc.TestProvisionersAgainstBuilders(new(ShellProvisionerAccTest), t)
}
@ -45,8 +44,8 @@ func (s *ShellProvisionerAccTest) GetConfig() (string, error) {
func (s *ShellProvisionerAccTest) GetProvisionerStore() packer.MapOfProvisioner {
return packer.MapOfProvisioner{
"shell": func() (packer.Provisioner, error) { return command.Provisioners["shell"], nil },
"file": func() (packer.Provisioner, error) { return command.Provisioners["file"], nil },
"shell": func() (packer.Provisioner, error) { return &shell.Provisioner{}, nil },
"file": func() (packer.Provisioner, error) { return &file.Provisioner{}, nil },
}
}