Merge pull request #7551 from krzyszko/gcp_encryption_key
Googlecompute builder image encryption support
This commit is contained in:
commit
fdae14bc18
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/hashicorp/packer/helper/config"
|
"github.com/hashicorp/packer/helper/config"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
|
compute "google.golang.org/api/compute/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var reImageFamily = regexp.MustCompile(`^[a-z]([-a-z0-9]{0,61}[a-z0-9])?$`)
|
var reImageFamily = regexp.MustCompile(`^[a-z]([-a-z0-9]{0,61}[a-z0-9])?$`)
|
||||||
|
@ -36,6 +37,7 @@ type Config struct {
|
||||||
DiskType string `mapstructure:"disk_type"`
|
DiskType string `mapstructure:"disk_type"`
|
||||||
ImageName string `mapstructure:"image_name"`
|
ImageName string `mapstructure:"image_name"`
|
||||||
ImageDescription string `mapstructure:"image_description"`
|
ImageDescription string `mapstructure:"image_description"`
|
||||||
|
ImageEncryptionKey *compute.CustomerEncryptionKey `mapstructure:"image_encryption_key"`
|
||||||
ImageFamily string `mapstructure:"image_family"`
|
ImageFamily string `mapstructure:"image_family"`
|
||||||
ImageLabels map[string]string `mapstructure:"image_labels"`
|
ImageLabels map[string]string `mapstructure:"image_labels"`
|
||||||
ImageLicenses []string `mapstructure:"image_licenses"`
|
ImageLicenses []string `mapstructure:"image_licenses"`
|
||||||
|
|
|
@ -156,6 +156,21 @@ func TestConfigPrepare(t *testing.T) {
|
||||||
"foo bar",
|
"foo bar",
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"image_encryption_key",
|
||||||
|
map[string]string{"kmsKeyName": "foo"},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"image_encryption_key",
|
||||||
|
map[string]string{"No such key": "foo"},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"image_encryption_key",
|
||||||
|
map[string]string{"kmsKeyName": "foo", "RawKey": "foo"},
|
||||||
|
false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"scopes",
|
"scopes",
|
||||||
[]string{},
|
[]string{},
|
||||||
|
|
|
@ -3,6 +3,8 @@ package googlecompute
|
||||||
import (
|
import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
compute "google.golang.org/api/compute/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Driver is the interface that has to be implemented to communicate
|
// Driver is the interface that has to be implemented to communicate
|
||||||
|
@ -11,7 +13,7 @@ import (
|
||||||
type Driver interface {
|
type Driver interface {
|
||||||
// CreateImage creates an image from the given disk in Google Compute
|
// CreateImage creates an image from the given disk in Google Compute
|
||||||
// Engine.
|
// Engine.
|
||||||
CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string) (<-chan *Image, <-chan error)
|
CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string, image_encryption_key *compute.CustomerEncryptionKey) (<-chan *Image, <-chan error)
|
||||||
|
|
||||||
// DeleteImage deletes the image with the given name.
|
// DeleteImage deletes the image with the given name.
|
||||||
DeleteImage(name string) <-chan error
|
DeleteImage(name string) <-chan error
|
||||||
|
|
|
@ -104,13 +104,14 @@ func NewDriverGCE(ui packer.Ui, p string, a *AccountFile) (Driver, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *driverGCE) CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string) (<-chan *Image, <-chan error) {
|
func (d *driverGCE) CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string, image_encryption_key *compute.CustomerEncryptionKey) (<-chan *Image, <-chan error) {
|
||||||
gce_image := &compute.Image{
|
gce_image := &compute.Image{
|
||||||
Description: description,
|
Description: description,
|
||||||
Name: name,
|
Name: name,
|
||||||
Family: family,
|
Family: family,
|
||||||
Labels: image_labels,
|
Labels: image_labels,
|
||||||
Licenses: image_licenses,
|
Licenses: image_licenses,
|
||||||
|
ImageEncryptionKey: image_encryption_key,
|
||||||
SourceDisk: fmt.Sprintf("%s%s/zones/%s/disks/%s", d.service.BasePath, d.projectId, zone, disk),
|
SourceDisk: fmt.Sprintf("%s%s/zones/%s/disks/%s", d.service.BasePath, d.projectId, zone, disk),
|
||||||
SourceType: "RAW",
|
SourceType: "RAW",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package googlecompute
|
package googlecompute
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
compute "google.golang.org/api/compute/v1"
|
||||||
|
)
|
||||||
|
|
||||||
// DriverMock is a Driver implementation that is a mocked out so that
|
// DriverMock is a Driver implementation that is a mocked out so that
|
||||||
// it can be used for tests.
|
// it can be used for tests.
|
||||||
|
@ -8,6 +12,7 @@ type DriverMock struct {
|
||||||
CreateImageName string
|
CreateImageName string
|
||||||
CreateImageDesc string
|
CreateImageDesc string
|
||||||
CreateImageFamily string
|
CreateImageFamily string
|
||||||
|
CreateImageEncryptionKey *compute.CustomerEncryptionKey
|
||||||
CreateImageLabels map[string]string
|
CreateImageLabels map[string]string
|
||||||
CreateImageLicenses []string
|
CreateImageLicenses []string
|
||||||
CreateImageZone string
|
CreateImageZone string
|
||||||
|
@ -82,7 +87,7 @@ type DriverMock struct {
|
||||||
WaitForInstanceErrCh <-chan error
|
WaitForInstanceErrCh <-chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DriverMock) CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string) (<-chan *Image, <-chan error) {
|
func (d *DriverMock) CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string, image_encryption_key *compute.CustomerEncryptionKey) (<-chan *Image, <-chan error) {
|
||||||
d.CreateImageName = name
|
d.CreateImageName = name
|
||||||
d.CreateImageDesc = description
|
d.CreateImageDesc = description
|
||||||
d.CreateImageFamily = family
|
d.CreateImageFamily = family
|
||||||
|
@ -90,6 +95,7 @@ func (d *DriverMock) CreateImage(name, description, family, zone, disk string, i
|
||||||
d.CreateImageLicenses = image_licenses
|
d.CreateImageLicenses = image_licenses
|
||||||
d.CreateImageZone = zone
|
d.CreateImageZone = zone
|
||||||
d.CreateImageDisk = disk
|
d.CreateImageDisk = disk
|
||||||
|
d.CreateImageEncryptionKey = image_encryption_key
|
||||||
if d.CreateImageResultProjectId == "" {
|
if d.CreateImageResultProjectId == "" {
|
||||||
d.CreateImageResultProjectId = "test"
|
d.CreateImageResultProjectId = "test"
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (s *StepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
||||||
|
|
||||||
imageCh, errCh := driver.CreateImage(
|
imageCh, errCh := driver.CreateImage(
|
||||||
config.ImageName, config.ImageDescription, config.ImageFamily, config.Zone,
|
config.ImageName, config.ImageDescription, config.ImageFamily, config.Zone,
|
||||||
config.DiskName, config.ImageLabels, config.ImageLicenses)
|
config.DiskName, config.ImageLabels, config.ImageLicenses, config.ImageEncryptionKey)
|
||||||
var err error
|
var err error
|
||||||
select {
|
select {
|
||||||
case err = <-errCh:
|
case err = <-errCh:
|
||||||
|
|
|
@ -47,6 +47,7 @@ func TestStepCreateImage(t *testing.T) {
|
||||||
assert.Equal(t, d.CreateImageDisk, c.DiskName, "Incorrect disk passed to driver.")
|
assert.Equal(t, d.CreateImageDisk, c.DiskName, "Incorrect disk passed to driver.")
|
||||||
assert.Equal(t, d.CreateImageLabels, c.ImageLabels, "Incorrect image_labels passed to driver.")
|
assert.Equal(t, d.CreateImageLabels, c.ImageLabels, "Incorrect image_labels passed to driver.")
|
||||||
assert.Equal(t, d.CreateImageLicenses, c.ImageLicenses, "Incorrect image_licenses passed to driver.")
|
assert.Equal(t, d.CreateImageLicenses, c.ImageLicenses, "Incorrect image_licenses passed to driver.")
|
||||||
|
assert.Equal(t, d.CreateImageEncryptionKey, c.ImageEncryptionKey, "Incorrect image_encryption_key passed to driver.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStepCreateImage_errorOnChannel(t *testing.T) {
|
func TestStepCreateImage_errorOnChannel(t *testing.T) {
|
||||||
|
|
|
@ -270,6 +270,17 @@ builder.
|
||||||
- `image_name` (string) - The unique name of the resulting image. Defaults to
|
- `image_name` (string) - The unique name of the resulting image. Defaults to
|
||||||
`"packer-{{timestamp}}"`.
|
`"packer-{{timestamp}}"`.
|
||||||
|
|
||||||
|
- `image_encryption_key` (object of encryption key) - Image encryption key to apply to the created image. Possible values:
|
||||||
|
* kmsKeyName - The name of the encryption key that is stored in Google Cloud KMS.
|
||||||
|
* RawKey: - A 256-bit customer-supplied encryption key, encodes in RFC 4648 base64.
|
||||||
|
|
||||||
|
example:
|
||||||
|
``` json
|
||||||
|
{
|
||||||
|
"kmsKeyName": "projects/${project}/locations/${region}/keyRings/computeEngine/cryptoKeys/computeEngine/cryptoKeyVersions/4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
- `instance_name` (string) - A name to give the launched instance. Beware
|
- `instance_name` (string) - A name to give the launched instance. Beware
|
||||||
that this must be unique. Defaults to `"packer-{{uuid}}"`.
|
that this must be unique. Defaults to `"packer-{{uuid}}"`.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue