Merge pull request #10933 from hashicorp/extract_openstack

extract openstack into its own plugin
This commit is contained in:
Megan Marsh 2021-04-20 10:28:00 -07:00 committed by GitHub
commit 9bdb809edd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 427 additions and 927 deletions

View File

@ -1,62 +0,0 @@
package openstack
import (
"testing"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
func TestArtifact_Impl(t *testing.T) {
var _ packersdk.Artifact = new(Artifact)
}
func TestArtifactId(t *testing.T) {
expected := `b8cdf55b-c916-40bd-b190-389ec144c4ed`
a := &Artifact{
ImageId: "b8cdf55b-c916-40bd-b190-389ec144c4ed",
}
result := a.Id()
if result != expected {
t.Fatalf("bad: %s", result)
}
}
func TestArtifactString(t *testing.T) {
expected := "An image was created: b8cdf55b-c916-40bd-b190-389ec144c4ed"
a := &Artifact{
ImageId: "b8cdf55b-c916-40bd-b190-389ec144c4ed",
}
result := a.String()
if result != expected {
t.Fatalf("bad: %s", result)
}
}
func TestArtifactState_StateData(t *testing.T) {
expectedData := "this is the data"
artifact := &Artifact{
StateData: map[string]interface{}{"state_data": expectedData},
}
// Valid state
result := artifact.State("state_data")
if result != expectedData {
t.Fatalf("Bad: State data was %s instead of %s", result, expectedData)
}
// Invalid state
result = artifact.State("invalid_key")
if result != nil {
t.Fatalf("Bad: State should be nil for invalid state data name")
}
// Nil StateData should not fail and should return nil
artifact = &Artifact{}
result = artifact.State("key")
if result != nil {
t.Fatalf("Bad: State should be nil for nil StateData")
}
}

View File

@ -1,30 +0,0 @@
package openstack
import (
"testing"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
func TestBuilder_ImplementsBuilder(t *testing.T) {
var raw interface{}
raw = &Builder{}
if _, ok := raw.(packersdk.Builder); !ok {
t.Fatalf("Builder should be a builder")
}
}
func TestBuilder_Prepare_BadType(t *testing.T) {
b := &Builder{}
c := map[string]interface{}{
"password": []string{},
}
_, warns, err := b.Prepare(c)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err == nil {
t.Fatalf("prepare should fail")
}
}

View File

@ -1,23 +0,0 @@
package openstack
import (
"testing"
)
func testImageConfig() *ImageConfig {
return &ImageConfig{
ImageName: "foo",
}
}
func TestImageConfigPrepare_Region(t *testing.T) {
c := testImageConfig()
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
c.ImageName = ""
if err := c.Prepare(nil); err == nil {
t.Fatal("should have error")
}
}

View File

@ -1,54 +0,0 @@
package openstack
import (
"net"
"testing"
)
func testYes(t *testing.T, a, b string) {
var m, n *net.IPNet
_, m, _ = net.ParseCIDR(a)
_, n, _ = net.ParseCIDR(b)
if !containsNet(m, n) {
t.Errorf("%s expected to contain %s", m, n)
}
}
func testNot(t *testing.T, a, b string) {
var m, n *net.IPNet
_, m, _ = net.ParseCIDR(a)
_, n, _ = net.ParseCIDR(b)
if containsNet(m, n) {
t.Errorf("%s expected to not contain %s", m, n)
}
}
func TestNetworkDiscovery_SubnetContainsGood_IPv4(t *testing.T) {
testYes(t, "192.168.0.0/23", "192.168.0.0/24")
testYes(t, "192.168.0.0/24", "192.168.0.0/24")
testNot(t, "192.168.0.0/25", "192.168.0.0/24")
testYes(t, "192.168.101.202/16", "192.168.202.101/16")
testNot(t, "192.168.101.202/24", "192.168.202.101/24")
testNot(t, "192.168.202.101/24", "192.168.101.202/24")
testYes(t, "0.0.0.0/0", "192.168.0.0/24")
testYes(t, "0.0.0.0/0", "0.0.0.0/1")
testNot(t, "192.168.0.0/24", "0.0.0.0/0")
testNot(t, "0.0.0.0/1", "0.0.0.0/0")
}
func TestNetworkDiscovery_SubnetContainsGood_IPv6(t *testing.T) {
testYes(t, "2001:db8::/63", "2001:db8::/64")
testYes(t, "2001:db8::/64", "2001:db8::/64")
testNot(t, "2001:db8::/65", "2001:db8::/64")
testYes(t, "2001:db8:fefe:b00b::/32", "2001:db8:b00b:fefe::/32")
testNot(t, "2001:db8:fefe:b00b::/64", "2001:db8:b00b:fefe::/64")
testNot(t, "2001:db8:b00b:fefe::/64", "2001:db8:fefe:b00b::/64")
testYes(t, "::/0", "2001:db8::/64")
testYes(t, "::/0", "::/1")
testNot(t, "2001:db8::/64", "::/0")
testNot(t, "::/1", "::/0")
}

View File

@ -1,284 +0,0 @@
package openstack
import (
"os"
"regexp"
"testing"
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
"github.com/hashicorp/packer-plugin-sdk/communicator"
"github.com/mitchellh/mapstructure"
)
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",
Comm: communicator.Config{
SSH: communicator.SSH{
SSHUsername: "foo",
},
},
}
}
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()
c.Comm.SSHPort = 0
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.Comm.SSHPort != 22 {
t.Fatalf("invalid value: %d", c.Comm.SSHPort)
}
c.Comm.SSHPort = 44
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.Comm.SSHPort != 44 {
t.Fatalf("invalid value: %d", c.Comm.SSHPort)
}
}
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"
if c.VolumeName != "PackerVolume" {
t.Fatalf("invalid value: %s", c.VolumeName)
}
}
func TestRunConfigPrepare_FloatingIPPoolCompat(t *testing.T) {
c := testRunConfig()
c.FloatingIPPool = "uuid1"
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
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" {
t.Fatalf("invalid value: %s", c.FloatingIPNetwork)
}
}
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)
}
c = testRunConfig()
// 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)
}
c = testRunConfig()
// 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)
}
c = testRunConfig()
// 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)
}
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)
}
}
// 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"},
Properties: map[string]string{"os_distro": "ubuntu", "os_version": "16.04"},
}
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)
}
}
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"},
Properties: map[string]string{"os_distro": "ubuntu", "os_version": "16.04"},
}
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)
}
}

View File

@ -1,102 +0,0 @@
package openstack
import (
"bytes"
"os/exec"
"testing"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
"golang.org/x/crypto/ssh"
)
var ber_encoded_key = `
-----BEGIN RSA PRIVATE KEY-----
MIIEqQIBAAKCAQEAo1C/iQtu7iSUJROyQgKm5VtJbaPg5GEP7IC+7TTZ2kVnWa9V
MU37sXKWk0J7oRHcSZ/dhRyNDcsvscFAU6V3FRpZxiTEvCqIBgLyoV3g+wkan+gD
AqNmqm77ldUIwMXT7n3AeWipw0uOBzZNjANhAf8qHIT2PXoT6LfaCof4PlPucCTx
eC+oT5zA/MbQoGneNkHnR26ijMac2vRC90+1WpZ5KwCVE6qd2kERlb9gbAGsNLE/
WrqR7bx4d8esLtE3l5zwkBTB63KdojMCrX/ZBiHT15TBQVsFPQqhdBT3BXfssnut
MkCf6+X0PIQkQcW6RqKR5nOHMFdB1kEChaKYMwIDAQABAoIBAQCRBPv/opJvjzWp
stLAgQBYe/Y5EKN7yKDOPwjLM/obMzPx1JqOvJO6X2lL/GYxgd2d1wJq2A586CdC
7brETBLxP0PmifHUsOO2itmO5wEHiW8F/Yzmw9g/kWuAAfrSyxhFF49Zf9H3ZFkL
GHJF2R5EGqP3TS4nKwcQyGkqntCV7p+QmPvlB05jT3vsc2jLn2yXXVEbu1X5Zj82
cdFwH4ZSc2BDv8ixBHy+zOGLx0TMF0hxEHdNIeAjGTyYfiyDr5mgMP4w6igGvP8q
pB5fE60ZKCEPLGyxMw69nDbXJK6YAKyNCVAD79FEl1yLYJlWfYAtOI6UeE0RUPeD
i42vINyBAoIAgQC9zZzl4kJUTdzYLYrxQ7f51B+eOF621kleTYLprr8I4VZUExht
KtsHdHWzMkxVtd7Q7UcG9L+Pqa3DVnD3S2C1IuUkO3eCpa93jhiwCIRYQfR7EzuR
ntVrQHfYaCgr8ahmWdoeZUr8lSDDp0/h+MamEksNEjZA+XwFWg6ycLgGwQKCAIEA
3EYz5iHqaOdekBYXcFpkq8uk+Sn27Cmnd7pLfK/YWEAb3Pie9X0pftA1O8z0tW9p
vEBS+pA27S55a38avmZSkZAiXMJOZ3HV99VZi5WU0Pg9A9oIiQvW6td9b1uuVl5q
o9fCK/r17E7NCFimtqSNtrNR/X08g+l4Dp1Ourgm7/MCggCAIGMohbWhGd+bcqv6
zIaAqzm+F3KI/uv74wKY9yUhZfOFlp0XivFIJLKDrwtDKVD6b249s3sqAOq0QuPK
LPiIzP/iV9dp4jpBgcYWgltBsgm3HRVAEe4nfsCmcp/7UtxOnwBwDsW8EPOlfp1b
LTUVOJtggR99cILh3cvrPBmt3UECggCBALsRH7g8a1+lxmglashu6/n+G1/DZMER
avjCDKOajuf7oe4acpzXK6tX1S2xFM0VDj3iftXuLcdl5ZYGPsceDNc0CgqutXki
cu1jkgV6BgUmHGMuAnuow19znEI7ISaWTohQjsVc/wctsPB6oTKRMwzK40Gc3wzD
9MKsk5T9GYxDAoIAgAFW9agGS4th1RrVwngjKHCPenQR1QSvHDHv3E3EQta1d0K3
Cx7RCdBpDNeNIpHVq8uTaWjSZ+Em6YDja7CqIfPj0HcykizxS4L7Dh0gt7I5+kuy
yBgJhEgIw3mK7U47nm9MmR/67RI4IS978ekVXP2oGdYqVUhHvMuOix8a72xk
-----END RSA PRIVATE KEY-----
`
var der_encoded_key = `
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAmfhARpOHdm5i551GEtOO2NEH36Dm2NjJp6eHQpnrwDW0bqd6
qHJSmhocSb/3r2WwPOsfBKa135aCEOqXKcrc2gY+IsgGMF8bFG//UVcHA0KGG9A8
mWwYBIU4lpb7DY54IllDDO11BERrxOEsPqmNgGzE0yOYApC2t8OcXsUE15kznhLn
d4V53kN//jRGR44KrGMcL8nrKDIBudz90ae7tRGBHYiMWPB89yYdUt06dXPLqqbf
JIUhuOBwle3IOuwJPmPEwsXFXkxKCYzKDAyi+weCDKtqeUl3HNbCB0f7g/uxUDhQ
wRzZ1v4g35LHh5zQR26dizl4Uj2dNLL6K5xkPwIDAQABAoIBABdpTPSuSAG1BSrs
mhQQwP6swgK553//bqIkcgepedRPFjFhG+BzCaZO5BA+tT2hO6v3oE7Hvo3Rx9Mk
qHl9VBl+q4IEYhSG0YpJAUxv7CwNuHCQODan3fsJ+rHDIUdNa2zln7FehdVxReW4
y05334EwiLkGB34UXQQSJTuvv228rF5F7wCs0luZWJ9IpGNWpwI2K6pg3ME/bIb6
xFMf6jKWUUZht1m+40UG2bhsMPPknde2zAq4DjJTl7bJuuhceqp3ylm5h+oUDCl2
twyGhn8gpHrMXVCcEvxwno8aJfNJ18iZu+lIQTT1DVuRrFprGDc9dFW6zVFauv6W
ZG5AUXkCgYEAyoBUPVFaf3E6nDqq26J5x6+DBe6afS7tqNn5E/z2cI54KLiUDwjs
P9axjdVMqqUiNw0jJRi8nUe1psDLguSZo4tFSgsWbsdnZQutQz2fy87jIgZOzZpj
fqud64O/fMm8fpGBz5LQjo27FLRfQcr23KVjWeQgBSMfMk2oe8Mw8+sCgYEAwqWc
abQBpG5TqtgvR3M9W0tAK51SSZF5okKif8KMoDJ67pXX2iTgh4bnUugaYObcG3qV
5VH9xlOuN4td4RfBybzRcKJDN/oinwZhMjQKKjyhpjLInDqnF4ogLPevT6cCq8I+
rHfK6DhtqLUG4BYDD7QWOBZpCTwd3n+7Xk39v/0CgYEAoaM9mpRNgFyJRBswNpDC
VDosg5epiTLkUVtsDiBlNgMCtr5esIGW0n40y9nukGevn/HEk9/i7khHHwvVZm3C
lWCdtjSTe2l/hpCDhKCz5KMHeik+za7mrD2gmFVZi+obo4vR6jZuctt+8U/omUPB
OO5rF12YkYEvbZ+/VMrBUHECgYEArWGpvvpJ0Dc6Ld9d1e5PxCd2pKMBLmj4CNIE
P3uDmhr9J9KvsC/TFMXU/iOjg5eAjrWWGev7+pKFiBKLcDqiMtoPUZ4n9A/KkQ60
u2xhdZgGga2QxqD0P+KYoJWMQo5IschX3XbjdhD1lSaTVj4lQfKvLAzCSSiUjqIG
u40LL90CgYB9t3CISlVJ+l1zy7QPIvAul5VuhwjxBHaotdLuXzvXFJXZH2dQ9j/a
/p2GMUq+VZbKq45x4I5Z3ax462qMRDmpx9yjtrwNavDV47uf34pQrNpuWO7kQfsM
mKMH6Gf6COfSIbLuejdzSOUAmjkFpm+nwBkka1eHdAy4ALn9wNQz3w==
-----END RSA PRIVATE KEY-----
`
func TestBerToDer(t *testing.T) {
_, err := exec.LookPath("openssl")
if err != nil {
t.Skipf("OpenSSL not available skipping test.")
}
msg := new(bytes.Buffer)
ui := &packersdk.BasicUi{
Reader: new(bytes.Buffer),
Writer: msg,
}
// Test - a DER encoded key comes back unchanged.
newKey := string(berToDer([]byte(der_encoded_key), ui))
if newKey != der_encoded_key {
t.Errorf("Trying to convert a DER encoded key should return the same key.")
}
if string(msg.Bytes()) != "" {
t.Errorf("Doing nothing with a DER encoded key result in no messages to the UI .")
}
// Test - a BER encoded key should be converted to DER.
newKey = string(berToDer([]byte(ber_encoded_key), ui))
_, err = ssh.ParsePrivateKey([]byte(newKey))
if err != nil {
t.Errorf("Trying to convert a BER encoded key should return a DER encoded key parsable by Go.")
}
if string(msg.Bytes()) != "Successfully converted BER encoded SSH key to DER encoding.\n" {
t.Errorf("Trying to convert a BER encoded key should tell the UI about the success.")
}
}

View File

@ -1,13 +0,0 @@
package version
import (
"github.com/hashicorp/packer-plugin-sdk/version"
packerVersion "github.com/hashicorp/packer/version"
)
var OpenstackPluginVersion *version.PluginVersion
func init() {
OpenstackPluginVersion = version.InitializePluginVersion(
packerVersion.Version, packerVersion.VersionPrerelease)
}

View File

@ -28,6 +28,7 @@ import (
googlecomputeexportpostprocessor "github.com/hashicorp/packer-plugin-googlecompute/post-processor/googlecompute-export"
googlecomputeimportpostprocessor "github.com/hashicorp/packer-plugin-googlecompute/post-processor/googlecompute-import"
ncloudbuilder "github.com/hashicorp/packer-plugin-ncloud/builder/ncloud"
openstackbuilder "github.com/hashicorp/packer-plugin-openstack/builder/openstack"
oscbsubuilder "github.com/hashicorp/packer-plugin-outscale/builder/osc/bsu"
oscbsusurrogatebuilder "github.com/hashicorp/packer-plugin-outscale/builder/osc/bsusurrogate"
oscbsuvolumebuilder "github.com/hashicorp/packer-plugin-outscale/builder/osc/bsuvolume"
@ -68,6 +69,7 @@ var VendoredBuilders = map[string]packersdk.Builder{
"docker": new(dockerbuilder.Builder),
"googlecompute": new(googlecomputebuilder.Builder),
"ncloud": new(ncloudbuilder.Builder),
"openstack": new(openstackbuilder.Builder),
"proxmox": new(proxmoxiso.Builder),
"proxmox-iso": new(proxmoxiso.Builder),
"proxmox-clone": new(proxmoxclone.Builder),

1
go.mod
View File

@ -45,6 +45,7 @@ require (
github.com/hashicorp/packer-plugin-docker v0.0.7
github.com/hashicorp/packer-plugin-googlecompute v0.0.1
github.com/hashicorp/packer-plugin-ncloud v0.0.2
github.com/hashicorp/packer-plugin-openstack v0.0.1
github.com/hashicorp/packer-plugin-outscale v0.0.1
github.com/hashicorp/packer-plugin-parallels v0.0.1
github.com/hashicorp/packer-plugin-proxmox v0.0.2

5
go.sum
View File

@ -474,6 +474,8 @@ github.com/hashicorp/packer-plugin-googlecompute v0.0.1 h1:Shjio88MraB+ocj0VI5+M
github.com/hashicorp/packer-plugin-googlecompute v0.0.1/go.mod h1:MfV898IrEMpKH6wVnvOI5Tkhxm2snf3QxwVqV4k3bNI=
github.com/hashicorp/packer-plugin-ncloud v0.0.2 h1:MGvGkOVfzeosqOSs5dteghLwv9VRcRxTuLoLX1ssUag=
github.com/hashicorp/packer-plugin-ncloud v0.0.2/go.mod h1:Hud2R1pkky96TQy3TPTTrr9Kej4b/4dqC/v+uEE0VDY=
github.com/hashicorp/packer-plugin-openstack v0.0.1 h1:FUaNjKguAipPZZXQ4UiJK6c5+2nS89CRxJHjAsfVyIQ=
github.com/hashicorp/packer-plugin-openstack v0.0.1/go.mod h1:L1OTbN24H+izce3v5IyQLdjDdrUigxPWgAQOK920h9A=
github.com/hashicorp/packer-plugin-outscale v0.0.1 h1:BrL8hKypNYrvP3NR+d+xX03SZKB08yTgXPRnH9piUI8=
github.com/hashicorp/packer-plugin-outscale v0.0.1/go.mod h1:6jEWfJO7TgAbaL3e+St1bN5PoIC/MmDIsYqNUzAHF1w=
github.com/hashicorp/packer-plugin-parallels v0.0.1 h1:fcaaiGWdU1+X4IGadXdUhJ2si1ZA3apXS9tMNJXln2A=
@ -1192,8 +1194,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@ -11,6 +11,7 @@ go:
- "1.11.x"
- "1.12.x"
- "1.13.x"
- "1.14.x"
- "tip"
go_import_path: gopkg.in/yaml.v2

6
vendor/gopkg.in/yaml.v2/apic.go generated vendored
View File

@ -79,6 +79,8 @@ func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
parser.encoding = encoding
}
var disableLineWrapping = false
// Create a new emitter object.
func yaml_emitter_initialize(emitter *yaml_emitter_t) {
*emitter = yaml_emitter_t{
@ -86,7 +88,9 @@ func yaml_emitter_initialize(emitter *yaml_emitter_t) {
raw_buffer: make([]byte, 0, output_raw_buffer_size),
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
events: make([]yaml_event_t, 0, initial_queue_size),
best_width: -1,
}
if disableLineWrapping {
emitter.best_width = -1
}
}

8
vendor/gopkg.in/yaml.v2/go.mod generated vendored
View File

@ -1,5 +1,5 @@
module "gopkg.in/yaml.v2"
module gopkg.in/yaml.v2
require (
"gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
)
go 1.15
require gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405

14
vendor/gopkg.in/yaml.v2/yaml.go generated vendored
View File

@ -175,7 +175,7 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) {
// Zero valued structs will be omitted if all their public
// fields are zero, unless they implement an IsZero
// method (see the IsZeroer interface type), in which
// case the field will be included if that method returns true.
// case the field will be excluded if IsZero returns true.
//
// flow Marshal using a flow style (useful for structs,
// sequences and maps).
@ -464,3 +464,15 @@ func isZero(v reflect.Value) bool {
}
return false
}
// FutureLineWrap globally disables line wrapping when encoding long strings.
// This is a temporary and thus deprecated method introduced to faciliate
// migration towards v3, which offers more control of line lengths on
// individual encodings, and has a default matching the behavior introduced
// by this function.
//
// The default formatting of v2 was erroneously changed in v2.3.0 and reverted
// in v2.4.0, at which point this function was introduced to help migration.
func FutureLineWrap() {
disableLineWrapping = true
}

5
vendor/modules.txt vendored
View File

@ -525,6 +525,9 @@ github.com/hashicorp/packer-plugin-googlecompute/post-processor/googlecompute-im
# github.com/hashicorp/packer-plugin-ncloud v0.0.2
## explicit
github.com/hashicorp/packer-plugin-ncloud/builder/ncloud
# github.com/hashicorp/packer-plugin-openstack v0.0.1
## explicit
github.com/hashicorp/packer-plugin-openstack/builder/openstack
# github.com/hashicorp/packer-plugin-outscale v0.0.1
## explicit
github.com/hashicorp/packer-plugin-outscale/builder/osc/bsu
@ -1210,7 +1213,7 @@ gopkg.in/square/go-jose.v2
gopkg.in/square/go-jose.v2/cipher
gopkg.in/square/go-jose.v2/json
gopkg.in/square/go-jose.v2/jwt
# gopkg.in/yaml.v2 v2.3.0
# gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v2
# gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
gopkg.in/yaml.v3

View File

@ -1,334 +0,0 @@
---
description: >
The openstack Packer builder is able to create new images for use with
OpenStack. The builder takes a source image, runs any provisioning necessary
on
the image after launching it, then creates a new reusable image. This reusable
image can then be used as the foundation of new servers that are launched
within OpenStack.
page_title: OpenStack - Builders
---
# OpenStack Builder
Type: `openstack`
Artifact BuilderId: `mitchellh.openstack`
The `openstack` Packer builder is able to create new images for use with
[OpenStack](http://www.openstack.org). The builder takes a source image, runs
any provisioning necessary on the image after launching it, then creates a new
reusable image. This reusable image can then be used as the foundation of new
servers that are launched within OpenStack. The builder will create temporary
keypairs that provide temporary access to the server while the image is being
created. This simplifies configuration quite a bit.
The builder does _not_ manage images. Once it creates an image, it is up to you
to use it or delete it.
~> **Note:** To use OpenStack builder with the OpenStack Newton (Oct 2016)
or earlier, we recommend you use Packer v1.1.2 or earlier version.
~> **OpenStack Liberty or later requires OpenSSL!** To use the OpenStack
builder with OpenStack Liberty (Oct 2015) or later you need to have OpenSSL
installed _if you are using temporary key pairs_, i.e. don't use
[`ssh_keypair_name`](#ssh_keypair_name) nor
[`ssh_password`](#ssh_password). All major
OS'es have OpenSSL installed by default except Windows. This have been resolved
in OpenStack Ocata(Feb 2017).
~> **Note:** OpenStack Block Storage volume support is available only for
V3 Block Storage API. It's available in OpenStack since Mitaka release (Apr
2016).
## Configuration Reference
There are many configuration options available for the builder. They are
segmented below into two categories: required and optional parameters. Within
each category, the available configuration keys are alphabetized.
In addition to the options listed here, a
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
builder.
### Required:
@include 'builder/openstack/AccessConfig-required.mdx'
@include 'builder/openstack/ImageConfig-required.mdx'
@include 'builder/openstack/RunConfig-required.mdx'
### Optional:
@include 'builder/openstack/AccessConfig-not-required.mdx'
@include 'builder/openstack/ImageConfig-not-required.mdx'
@include 'builder/openstack/RunConfig-not-required.mdx'
### Communicator Configuration
#### Optional:
@include 'packer-plugin-sdk/communicator/Config-not-required.mdx'
@include 'packer-plugin-sdk/communicator/SSH-not-required.mdx'
@include 'packer-plugin-sdk/communicator/SSHTemporaryKeyPair-not-required.mdx'
@include 'packer-plugin-sdk/communicator/SSH-Key-Pair-Name-not-required.mdx'
@include 'packer-plugin-sdk/communicator/SSH-Private-Key-File-not-required.mdx'
@include 'packer-plugin-sdk/communicator/SSH-Agent-Auth-not-required.mdx'
@include 'packer-plugin-sdk/communicator/SSHInterface-not-required.mdx'
## Basic Example: DevStack
Here is a basic example. This is a example to build on DevStack running in a
VM.
<Tabs>
<Tab heading="JSON">
```json
{
"type": "openstack",
"identity_endpoint": "http://<devstack-ip>:5000/v3",
"tenant_name": "admin",
"domain_name": "Default",
"username": "admin",
"password": "<your admin password>",
"region": "RegionOne",
"ssh_username": "root",
"image_name": "Test image",
"source_image": "<image id>",
"flavor": "m1.tiny",
"insecure": "true"
}
```
</Tab>
<Tab heading="HCL2">
```hcl
builders "openstack" {
identity_endpoint = "http://<devstack-ip>:5000/v3"
tenant_name = "admin"
domain_name = "Default"
username = "admin"
password = "<your admin password>"
region = "RegionOne"
ssh_username = "root"
image_name = "Test image"
source_image = "<image id>"
flavor = "m1.tiny"
insecure = "true"
}
```
</Tab>
</Tabs>
## Basic Example: Rackspace public cloud
Here is a basic example. This is a working example to build a Ubuntu 12.04 LTS
(Precise Pangolin) on Rackspace OpenStack cloud offering.
<Tabs>
<Tab heading="JSON">
```json
{
"type": "openstack",
"username": "foo",
"password": "foo",
"region": "DFW",
"ssh_username": "root",
"image_name": "Test image",
"source_image": "23b564c9-c3e6-49f9-bc68-86c7a9ab5018",
"flavor": "2"
}
```
</Tab>
<Tab heading="HCL2">
```hcl
builders "openstack" {
username = "foo"
password = "foo"
region = "DFW"
ssh_username = "root"
image_name = "Test image"
source_image = "23b564c9-c3e6-49f9-bc68-86c7a9ab5018"
flavor = "2"
}
```
</Tab>
</Tabs>
## Basic Example: Private OpenStack cloud
This example builds an Ubuntu 14.04 image on a private OpenStack cloud, powered
by Metacloud.
<Tabs>
<Tab heading="JSON">
```json
{
"type": "openstack",
"ssh_username": "root",
"image_name": "ubuntu1404_packer_test_1",
"source_image": "91d9c168-d1e5-49ca-a775-3bfdbb6c97f1",
"flavor": "2"
}
```
</Tab>
<Tab heading="HCL2">
```hcl
builders "openstack" {
ssh_username = "root"
image_name = "ubuntu1404_packer_test_1"
source_image = "91d9c168-d1e5-49ca-a775-3bfdbb6c97f1"
flavor = "2"
}
```
</Tab>
</Tabs>
In this case, the connection information for connecting to OpenStack doesn't
appear in the template. That is because I source a standard OpenStack script
with environment variables set before I run this. This script is setting
environment variables like:
- `OS_AUTH_URL`
- `OS_TENANT_ID`
- `OS_USERNAME`
- `OS_PASSWORD`
This is slightly different when identity v3 is used:
- `OS_AUTH_URL`
- `OS_USERNAME`
- `OS_PASSWORD`
- `OS_DOMAIN_NAME`
- `OS_TENANT_NAME`
This will authenticate the user on the domain and scope you to the project. A
tenant is the same as a project. It's optional to use names or IDs in v3. This
means you can use `OS_USERNAME` or `OS_USERID`, `OS_TENANT_ID` or
`OS_TENANT_NAME` and `OS_DOMAIN_ID` or `OS_DOMAIN_NAME`.
The above example would be equivalent to an RC file looking like this :
```shell
export OS_AUTH_URL="https://identity.myprovider/v3"
export OS_USERNAME="myuser"
export OS_PASSWORD="password"
export OS_USER_DOMAIN_NAME="mydomain"
export OS_PROJECT_DOMAIN_NAME="mydomain"
```
## Basic Example: Instance with Block Storage root volume
A basic example of Instance with a remote root Block Storage service volume.
This is a working example to build an image on private OpenStack cloud powered
by Selectel VPC.
<Tabs>
<Tab heading="JSON">
```json
{
"type": "openstack",
"identity_endpoint": "https://api.selvpc.com/identity/v3",
"tenant_id": "2e90c5c04c7b4c509be78723e2b55b77",
"username": "foo",
"password": "foo",
"region": "ru-3",
"ssh_username": "root",
"image_name": "Test image",
"source_image": "5f58ea7e-6264-4939-9d0f-0c23072b1132",
"networks": "9aab504e-bedf-48af-9256-682a7fa3dabb",
"flavor": "1001",
"availability_zone": "ru-3a",
"use_blockstorage_volume": true,
"volume_type": "fast.ru-3a"
}
```
</Tab>
<Tab heading="HCL2">
```hcl
builders "openstack" {
identity_endpoint = "https://api.selvpc.com/identity/v3"
tenant_id = "2e90c5c04c7b4c509be78723e2b55b77"
username = "foo"
password = "foo"
region = "ru-3"
ssh_username = "root"
image_name = "Test image"
source_image = "5f58ea7e-6264-4939-9d0f-0c23072b1132"
networks = "9aab504e-bedf-48af-9256-682a7fa3dabb"
flavor = "1001"
availability_zone = "ru-3a"
use_blockstorage_volume = true
volume_type = "fast.ru-3a"
}
```
</Tab>
</Tabs>
## Notes on OpenStack Authorization
The simplest way to get all settings for authorization against OpenStack is to
go into the OpenStack Dashboard (Horizon) select your _Project_ and navigate
_Project, Access & Security_, select _API Access_ and _Download OpenStack RC
File v3_. Source the file, and select your wanted region by setting environment
variable `OS_REGION_NAME` or `OS_REGION_ID` and
`export OS_TENANT_NAME=$OS_PROJECT_NAME` or
`export OS_TENANT_ID=$OS_PROJECT_ID`.
~> `OS_TENANT_NAME` or `OS_TENANT_ID` must be used even with Identity v3,
`OS_PROJECT_NAME` and `OS_PROJECT_ID` has no effect in Packer.
To troubleshoot authorization issues test you environment variables with the
OpenStack cli. It can be installed with
$ pip install --user python-openstackclient
### Authorize Using Tokens
To authorize with a access token only `identity_endpoint` and `token` is
needed, and possibly `tenant_name` or `tenant_id` depending on your token type.
Or use the following environment variables:
- `OS_AUTH_URL`
- `OS_TOKEN`
- One of `OS_TENANT_NAME` or `OS_TENANT_ID`
### Authorize Using Application Credential
To authorize with an application credential, only `identity_endpoint`,
`application_credential_id`, and `application_credential_secret` are needed.
Or use the following environment variables:
- `OS_AUTH_URL`
- `OS_APPLICATION_CREDENTIAL_ID`
- `OS_APPLICATION_CREDENTIAL_SECRET`

View File

@ -753,10 +753,6 @@
"title": "1&amp;1",
"path": "builders/oneandone"
},
{
"title": "OpenStack",
"path": "builders/openstack"
},
{
"title": "Oracle",
"routes": [

View File

@ -37,6 +37,26 @@
"pluginTier": "community",
"version": "latest"
},
{
"title": "Openstack",
"path": "openstack",
"repo": "hashicorp/packer-plugin-openstack",
"pluginTier": "community",
"version": "latest"
},
{
"title": "Outscale",
"path": "outscale",
"repo": "hashicorp/packer-plugin-outscale",
"version": "latest",
"pluginTier": "community"
},
{
"title": "Parallels",
"path": "parallels",
"repo": "hashicorp/packer-plugin-parallels",
"version": "latest"
},
{
"title": "Proxmox",
"path": "proxmox",
@ -74,18 +94,5 @@
"path": "qemu",
"repo": "hashicorp/packer-plugin-qemu",
"version": "latest"
},
{
"title": "Outscale",
"path": "outscale",
"repo": "hashicorp/packer-plugin-outscale",
"version": "latest",
"pluginTier": "community"
},
{
"title": "Parallels",
"path": "parallels",
"repo": "hashicorp/packer-plugin-parallels",
"version": "latest"
}
]