2013-08-27 00:57:23 -04:00
|
|
|
package openstack
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
2020-09-25 08:59:00 -04:00
|
|
|
"regexp"
|
2013-08-27 00:57:23 -04:00
|
|
|
"testing"
|
2015-06-13 18:34:37 -04:00
|
|
|
|
2018-08-22 07:37:43 -04:00
|
|
|
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
|
2020-12-01 18:30:31 -05:00
|
|
|
"github.com/hashicorp/packer/packer-plugin-sdk/communicator"
|
2018-08-22 18:23:12 -04:00
|
|
|
"github.com/mitchellh/mapstructure"
|
2013-08-27 00:57:23 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
// Clear out the openstack env vars so they don't
|
|
|
|
// affect our tests.
|
|
|
|
os.Setenv("SDK_USERNAME", "")
|
|
|
|
os.Setenv("SDK_PASSWORD", "")
|
|
|
|
os.Setenv("SDK_PROVIDER", "")
|
|
|
|
}
|
|
|
|
|
|
|
|
func testRunConfig() *RunConfig {
|
|
|
|
return &RunConfig{
|
|
|
|
SourceImage: "abcd",
|
|
|
|
Flavor: "m1.small",
|
2015-06-13 18:34:37 -04:00
|
|
|
|
|
|
|
Comm: communicator.Config{
|
2019-06-06 10:44:48 -04:00
|
|
|
SSH: communicator.SSH{
|
|
|
|
SSHUsername: "foo",
|
|
|
|
},
|
2015-06-13 18:34:37 -04:00
|
|
|
},
|
2013-08-27 00:57:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRunConfigPrepare(t *testing.T) {
|
|
|
|
c := testRunConfig()
|
|
|
|
err := c.Prepare(nil)
|
|
|
|
if len(err) > 0 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRunConfigPrepare_InstanceType(t *testing.T) {
|
|
|
|
c := testRunConfig()
|
|
|
|
c.Flavor = ""
|
|
|
|
if err := c.Prepare(nil); len(err) != 1 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRunConfigPrepare_SourceImage(t *testing.T) {
|
|
|
|
c := testRunConfig()
|
|
|
|
c.SourceImage = ""
|
|
|
|
if err := c.Prepare(nil); len(err) != 1 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRunConfigPrepare_SSHPort(t *testing.T) {
|
|
|
|
c := testRunConfig()
|
2015-06-13 18:34:37 -04:00
|
|
|
c.Comm.SSHPort = 0
|
2013-08-27 00:57:23 -04:00
|
|
|
if err := c.Prepare(nil); len(err) != 0 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
2015-06-13 18:34:37 -04:00
|
|
|
if c.Comm.SSHPort != 22 {
|
|
|
|
t.Fatalf("invalid value: %d", c.Comm.SSHPort)
|
2013-08-27 00:57:23 -04:00
|
|
|
}
|
|
|
|
|
2015-06-13 18:34:37 -04:00
|
|
|
c.Comm.SSHPort = 44
|
2013-08-27 00:57:23 -04:00
|
|
|
if err := c.Prepare(nil); len(err) != 0 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
2015-06-13 18:34:37 -04:00
|
|
|
if c.Comm.SSHPort != 44 {
|
|
|
|
t.Fatalf("invalid value: %d", c.Comm.SSHPort)
|
2013-08-27 00:57:23 -04:00
|
|
|
}
|
|
|
|
}
|
2018-05-24 06:20:22 -04:00
|
|
|
|
|
|
|
func TestRunConfigPrepare_BlockStorage(t *testing.T) {
|
|
|
|
c := testRunConfig()
|
|
|
|
c.UseBlockStorageVolume = true
|
|
|
|
c.VolumeType = "fast"
|
|
|
|
if err := c.Prepare(nil); len(err) != 0 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if c.VolumeType != "fast" {
|
|
|
|
t.Fatalf("invalid value: %s", c.VolumeType)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.AvailabilityZone = "RegionTwo"
|
|
|
|
if err := c.Prepare(nil); len(err) != 0 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.VolumeAvailabilityZone != "RegionTwo" {
|
|
|
|
t.Fatalf("invalid value: %s", c.VolumeAvailabilityZone)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.VolumeAvailabilityZone = "RegionOne"
|
|
|
|
if err := c.Prepare(nil); len(err) != 0 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.VolumeAvailabilityZone != "RegionOne" {
|
|
|
|
t.Fatalf("invalid value: %s", c.VolumeAvailabilityZone)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.VolumeName = "PackerVolume"
|
2018-06-12 07:08:17 -04:00
|
|
|
if c.VolumeName != "PackerVolume" {
|
|
|
|
t.Fatalf("invalid value: %s", c.VolumeName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRunConfigPrepare_FloatingIPPoolCompat(t *testing.T) {
|
|
|
|
c := testRunConfig()
|
2018-08-16 17:15:18 -04:00
|
|
|
c.FloatingIPPool = "uuid1"
|
2018-05-24 06:20:22 -04:00
|
|
|
if err := c.Prepare(nil); len(err) != 0 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
2018-08-16 17:15:18 -04:00
|
|
|
if c.FloatingIPNetwork != "uuid1" {
|
|
|
|
t.Fatalf("invalid value: %s", c.FloatingIPNetwork)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.FloatingIPNetwork = "uuid2"
|
|
|
|
c.FloatingIPPool = "uuid3"
|
|
|
|
if err := c.Prepare(nil); len(err) != 0 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.FloatingIPNetwork != "uuid2" {
|
2018-06-12 07:08:17 -04:00
|
|
|
t.Fatalf("invalid value: %s", c.FloatingIPNetwork)
|
2018-05-24 06:20:22 -04:00
|
|
|
}
|
|
|
|
}
|
2018-08-22 07:37:43 -04:00
|
|
|
|
2020-09-25 08:59:00 -04:00
|
|
|
func TestRunConfigPrepare_ExternalSourceImageURL(t *testing.T) {
|
|
|
|
c := testRunConfig()
|
|
|
|
// test setting both ExternalSourceImageURL and SourceImage causes an error
|
|
|
|
c.ExternalSourceImageURL = "http://example.com/image.qcow2"
|
|
|
|
if err := c.Prepare(nil); len(err) != 1 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
2020-10-08 04:54:41 -04:00
|
|
|
c = testRunConfig()
|
2020-09-25 08:59:00 -04:00
|
|
|
// test setting both ExternalSourceImageURL and SourceImageName causes an error
|
|
|
|
c.SourceImage = ""
|
|
|
|
c.SourceImageName = "abcd"
|
|
|
|
c.ExternalSourceImageURL = "http://example.com/image.qcow2"
|
|
|
|
if err := c.Prepare(nil); len(err) != 1 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
2020-10-08 04:54:41 -04:00
|
|
|
c = testRunConfig()
|
2020-09-25 08:59:00 -04:00
|
|
|
// test neither setting SourceImage, SourceImageName or ExternalSourceImageURL causes an error
|
|
|
|
c.SourceImage = ""
|
|
|
|
c.SourceImageName = ""
|
|
|
|
c.ExternalSourceImageURL = ""
|
|
|
|
if err := c.Prepare(nil); len(err) != 1 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
2020-10-08 04:54:41 -04:00
|
|
|
c = testRunConfig()
|
2020-09-25 08:59:00 -04:00
|
|
|
// test setting only ExternalSourceImageURL passes
|
|
|
|
c.SourceImage = ""
|
|
|
|
c.SourceImageName = ""
|
|
|
|
c.ExternalSourceImageURL = "http://example.com/image.qcow2"
|
|
|
|
if err := c.Prepare(nil); len(err) != 0 {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// test default values
|
|
|
|
if c.ExternalSourceImageFormat != "qcow2" {
|
|
|
|
t.Fatalf("ExternalSourceImageFormat should have been set to default: qcow2")
|
|
|
|
}
|
|
|
|
|
|
|
|
p := `packer_[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}`
|
|
|
|
if matches, _ := regexp.MatchString(p, c.SourceImageName); !matches {
|
|
|
|
t.Fatalf("invalid format for SourceImageName: %s", c.SourceImageName)
|
|
|
|
}
|
2020-10-08 04:54:41 -04:00
|
|
|
|
|
|
|
c = testRunConfig()
|
|
|
|
// test setting a filter passes
|
|
|
|
c.SourceImage = ""
|
|
|
|
c.SourceImageName = ""
|
|
|
|
c.ExternalSourceImageURL = ""
|
|
|
|
c.SourceImageFilters = ImageFilter{
|
|
|
|
Filters: ImageFilterOptions{
|
|
|
|
Name: "Ubuntu 16.04",
|
|
|
|
Visibility: "public",
|
|
|
|
Owner: "1234567890",
|
|
|
|
Tags: []string{"prod", "ready"},
|
|
|
|
Properties: map[string]string{"os_distro": "ubuntu", "os_version": "16.04"},
|
|
|
|
},
|
|
|
|
MostRecent: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := c.Prepare(nil); len(err) != 0 {
|
|
|
|
t.Fatalf("Should not error if everything but filter is empty: %s", err)
|
|
|
|
}
|
|
|
|
|
2020-09-25 08:59:00 -04:00
|
|
|
}
|
|
|
|
|
2018-08-22 07:37:43 -04:00
|
|
|
// This test case confirms that only allowed fields will be set to values
|
|
|
|
// The checked values are non-nil for their target type
|
|
|
|
func TestBuildImageFilter(t *testing.T) {
|
|
|
|
|
|
|
|
filters := ImageFilterOptions{
|
|
|
|
Name: "Ubuntu 16.04",
|
|
|
|
Visibility: "public",
|
|
|
|
Owner: "1234567890",
|
|
|
|
Tags: []string{"prod", "ready"},
|
2019-04-30 10:34:40 -04:00
|
|
|
Properties: map[string]string{"os_distro": "ubuntu", "os_version": "16.04"},
|
2018-08-22 07:37:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
listOpts, err := filters.Build()
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Building filter failed with: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if listOpts.Name != "Ubuntu 16.04" {
|
|
|
|
t.Errorf("Name did not build correctly: %s", listOpts.Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
if listOpts.Visibility != images.ImageVisibilityPublic {
|
|
|
|
t.Errorf("Visibility did not build correctly: %s", listOpts.Visibility)
|
|
|
|
}
|
|
|
|
|
|
|
|
if listOpts.Owner != "1234567890" {
|
|
|
|
t.Errorf("Owner did not build correctly: %s", listOpts.Owner)
|
|
|
|
}
|
|
|
|
}
|
2018-08-22 18:23:12 -04:00
|
|
|
|
|
|
|
func TestBuildBadImageFilter(t *testing.T) {
|
|
|
|
filterMap := map[string]interface{}{
|
|
|
|
"limit": "3",
|
|
|
|
"size_min": "25",
|
|
|
|
}
|
|
|
|
|
|
|
|
filters := ImageFilterOptions{}
|
|
|
|
mapstructure.Decode(filterMap, &filters)
|
|
|
|
listOpts, err := filters.Build()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Error returned processing image filter: %s", err.Error())
|
|
|
|
return // we cannot trust listOpts to not cause unexpected behaviour
|
|
|
|
}
|
|
|
|
|
|
|
|
if listOpts.Limit == filterMap["limit"] {
|
|
|
|
t.Errorf("Limit was parsed into ListOpts: %d", listOpts.Limit)
|
|
|
|
}
|
|
|
|
|
|
|
|
if listOpts.SizeMin != 0 {
|
|
|
|
t.Errorf("SizeMin was parsed into ListOpts: %d", listOpts.SizeMin)
|
|
|
|
}
|
|
|
|
|
|
|
|
if listOpts.Sort != "created_at:desc" {
|
|
|
|
t.Errorf("Sort was not applied: %s", listOpts.Sort)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !filters.Empty() {
|
|
|
|
t.Errorf("The filters should be empty due to lack of input")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tests that the Empty method on ImageFilterOptions works as expected
|
|
|
|
func TestImageFiltersEmpty(t *testing.T) {
|
|
|
|
filledFilters := ImageFilterOptions{
|
|
|
|
Name: "Ubuntu 16.04",
|
|
|
|
Visibility: "public",
|
|
|
|
Owner: "1234567890",
|
|
|
|
Tags: []string{"prod", "ready"},
|
2019-04-30 10:34:40 -04:00
|
|
|
Properties: map[string]string{"os_distro": "ubuntu", "os_version": "16.04"},
|
2018-08-22 18:23:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if filledFilters.Empty() {
|
|
|
|
t.Errorf("Expected filled filters to be non-empty: %v", filledFilters)
|
|
|
|
}
|
|
|
|
|
|
|
|
emptyFilters := ImageFilterOptions{}
|
|
|
|
|
|
|
|
if !emptyFilters.Empty() {
|
|
|
|
t.Errorf("Expected default filter to be empty: %v", emptyFilters)
|
|
|
|
}
|
|
|
|
}
|