builder/amazon/instance: upload x509 cert
This commit is contained in:
parent
42f78804fe
commit
39b3b18d81
|
@ -3,6 +3,8 @@
|
||||||
package instance
|
package instance
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/mitchellh/goamz/aws"
|
"github.com/mitchellh/goamz/aws"
|
||||||
"github.com/mitchellh/goamz/ec2"
|
"github.com/mitchellh/goamz/ec2"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
|
@ -10,6 +12,7 @@ import (
|
||||||
"github.com/mitchellh/packer/builder/common"
|
"github.com/mitchellh/packer/builder/common"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The unique ID for this builder
|
// The unique ID for this builder
|
||||||
|
@ -21,6 +24,10 @@ type Config struct {
|
||||||
common.PackerConfig `mapstructure:",squash"`
|
common.PackerConfig `mapstructure:",squash"`
|
||||||
awscommon.AccessConfig `mapstructure:",squash"`
|
awscommon.AccessConfig `mapstructure:",squash"`
|
||||||
awscommon.RunConfig `mapstructure:",squash"`
|
awscommon.RunConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
|
X509CertPath string `mapstructure:"x509_cert_path"`
|
||||||
|
X509KeyPath string `mapstructure:"x509_key_path"`
|
||||||
|
X509UploadPath string `mapstructure:"x509_upload_path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Builder struct {
|
type Builder struct {
|
||||||
|
@ -39,6 +46,24 @@ func (b *Builder) Prepare(raws ...interface{}) error {
|
||||||
errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare()...)
|
errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare()...)
|
||||||
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare()...)
|
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare()...)
|
||||||
|
|
||||||
|
if b.config.X509CertPath == "" {
|
||||||
|
errs = packer.MultiErrorAppend(errs, errors.New("x509_cert_path is required"))
|
||||||
|
} else if _, err := os.Stat(b.config.X509CertPath); err != nil {
|
||||||
|
errs = packer.MultiErrorAppend(
|
||||||
|
errs, fmt.Errorf("x509_cert_path points to bad file: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.config.X509KeyPath == "" {
|
||||||
|
errs = packer.MultiErrorAppend(errs, errors.New("x509_key_path is required"))
|
||||||
|
} else if _, err := os.Stat(b.config.X509KeyPath); err != nil {
|
||||||
|
errs = packer.MultiErrorAppend(
|
||||||
|
errs, fmt.Errorf("x509_key_path points to bad file: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.config.X509UploadPath == "" {
|
||||||
|
errs = packer.MultiErrorAppend(errs, errors.New("x509_upload_path is required"))
|
||||||
|
}
|
||||||
|
|
||||||
if errs != nil && len(errs.Errors) > 0 {
|
if errs != nil && len(errs.Errors) > 0 {
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
@ -62,7 +87,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
|
|
||||||
// Setup the state bag and initial state for the steps
|
// Setup the state bag and initial state for the steps
|
||||||
state := make(map[string]interface{})
|
state := make(map[string]interface{})
|
||||||
state["config"] = b.config
|
state["config"] = &b.config
|
||||||
state["ec2"] = ec2conn
|
state["ec2"] = ec2conn
|
||||||
state["hook"] = hook
|
state["hook"] = hook
|
||||||
state["ui"] = ui
|
state["ui"] = ui
|
||||||
|
@ -85,6 +110,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
SSHWaitTimeout: b.config.SSHTimeout(),
|
SSHWaitTimeout: b.config.SSHTimeout(),
|
||||||
},
|
},
|
||||||
&common.StepProvision{},
|
&common.StepProvision{},
|
||||||
|
&StepUploadX509Cert{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run!
|
// Run!
|
||||||
|
|
|
@ -2,11 +2,26 @@ package instance
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testConfig() map[string]interface{} {
|
func testConfig() map[string]interface{} {
|
||||||
return map[string]interface{}{}
|
tf, err := ioutil.TempFile("", "packer")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return map[string]interface{}{
|
||||||
|
"instance_type": "m1.small",
|
||||||
|
"region": "us-east-1",
|
||||||
|
"source_ami": "foo",
|
||||||
|
"ssh_username": "bob",
|
||||||
|
"x509_cert_path": tf.Name(),
|
||||||
|
"x509_key_path": tf.Name(),
|
||||||
|
"x509_upload_path": "/foo",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuilder_ImplementsBuilder(t *testing.T) {
|
func TestBuilder_ImplementsBuilder(t *testing.T) {
|
||||||
|
@ -28,3 +43,72 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
||||||
t.Fatal("should have error")
|
t.Fatal("should have error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuilderPrepare_X509CertPath(t *testing.T) {
|
||||||
|
b := &Builder{}
|
||||||
|
config := testConfig()
|
||||||
|
|
||||||
|
config["x509_cert_path"] = ""
|
||||||
|
err := b.Prepare(config)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should have error")
|
||||||
|
}
|
||||||
|
|
||||||
|
config["x509_cert_path"] = "i/am/a/file/that/doesnt/exist"
|
||||||
|
err = b.Prepare(config)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("should have error")
|
||||||
|
}
|
||||||
|
|
||||||
|
tf, err := ioutil.TempFile("", "packer")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error tempfile: %s", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(tf.Name())
|
||||||
|
|
||||||
|
config["x509_cert_path"] = tf.Name()
|
||||||
|
err = b.Prepare(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("should not have error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuilderPrepare_X509KeyPath(t *testing.T) {
|
||||||
|
b := &Builder{}
|
||||||
|
config := testConfig()
|
||||||
|
|
||||||
|
config["x509_key_path"] = ""
|
||||||
|
err := b.Prepare(config)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should have error")
|
||||||
|
}
|
||||||
|
|
||||||
|
config["x509_key_path"] = "i/am/a/file/that/doesnt/exist"
|
||||||
|
err = b.Prepare(config)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("should have error")
|
||||||
|
}
|
||||||
|
|
||||||
|
tf, err := ioutil.TempFile("", "packer")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error tempfile: %s", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(tf.Name())
|
||||||
|
|
||||||
|
config["x509_key_path"] = tf.Name()
|
||||||
|
err = b.Prepare(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("should not have error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuilderPrepare_X509UploadPath(t *testing.T) {
|
||||||
|
b := &Builder{}
|
||||||
|
config := testConfig()
|
||||||
|
|
||||||
|
config["x509_upload_path"] = ""
|
||||||
|
err := b.Prepare(config)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should have error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package instance
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StepUploadX509Cert struct{}
|
||||||
|
|
||||||
|
func (s *StepUploadX509Cert) Run(state map[string]interface{}) multistep.StepAction {
|
||||||
|
comm := state["communicator"].(packer.Communicator)
|
||||||
|
config := state["config"].(*Config)
|
||||||
|
ui := state["ui"].(packer.Ui)
|
||||||
|
|
||||||
|
x509RemoteCertPath := config.X509UploadPath + "/cert.pem"
|
||||||
|
x509RemoteKeyPath := config.X509UploadPath + "/key.pem"
|
||||||
|
|
||||||
|
ui.Say("Uploading X509 Certificate...")
|
||||||
|
if err := s.uploadSingle(comm, x509RemoteCertPath, config.X509CertPath); err != nil {
|
||||||
|
state["error"] = fmt.Errorf("Error uploading X509 cert: %s", err)
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.uploadSingle(comm, x509RemoteKeyPath, config.X509KeyPath); err != nil {
|
||||||
|
state["error"] = fmt.Errorf("Error uploading X509 cert: %s", err)
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepUploadX509Cert) Cleanup(map[string]interface{}) {}
|
||||||
|
|
||||||
|
func (s *StepUploadX509Cert) uploadSingle(comm packer.Communicator, dst, src string) error {
|
||||||
|
f, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
return comm.Upload(dst, f)
|
||||||
|
}
|
Loading…
Reference in New Issue