Add --openstack-key-pair and --openstack-private-file-name so to

import and reuse existing nova keypairs.

Signed-off-by: Fabrizio Soppelsa <fsoppelsa@mirantis.com>
This commit is contained in:
Fabrizio Soppelsa
2015-12-15 18:22:38 -08:00
parent 14ea20ffdb
commit c63d303a2e
3 changed files with 70 additions and 4 deletions
+57 -4
View File
@@ -37,6 +37,7 @@ type Driver struct {
KeyPairName string
NetworkName string
NetworkId string
PrivateKeyFile string
SecurityGroups []string
FloatingIpPool string
ComputeNetwork bool
@@ -142,12 +143,24 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
Usage: "OpenStack image name to use for the instance",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_KEYPAIR_NAME",
Name: "openstack-keypair-name",
Usage: "OpenStack keypair to use to SSH to the instance",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_NETWORK_ID",
Name: "openstack-net-id",
Usage: "OpenStack network id the machine will be connected on",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_PRIVATE_KEY_FILE",
Name: "openstack-private-key-file",
Usage: "Private keyfile to use for SSH (absolute path)",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_NETWORK_NAME",
Name: "openstack-net-name",
@@ -255,6 +268,8 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.ComputeNetwork = flags.Bool("openstack-nova-network")
d.SSHUser = flags.String("openstack-ssh-user")
d.SSHPort = flags.Int("openstack-ssh-port")
d.KeyPairName = flags.String("openstack-keypair-name")
d.PrivateKeyFile = flags.String("openstack-private-key-file")
d.SwarmMaster = flags.Bool("swarm-master")
d.SwarmHost = flags.String("swarm-host")
d.SwarmDiscovery = flags.String("swarm-discovery")
@@ -339,13 +354,18 @@ func (d *Driver) GetState() (state.State, error) {
}
func (d *Driver) Create() error {
d.KeyPairName = fmt.Sprintf("%s-%s", d.MachineName, mcnutils.GenerateRandomID())
if err := d.resolveIds(); err != nil {
return err
}
if err := d.createSSHKey(); err != nil {
return err
if d.KeyPairName != "" {
if err := d.loadSSHKey(); err != nil {
return err
}
} else {
d.KeyPairName = fmt.Sprintf("%s-%s", d.MachineName, mcnutils.GenerateRandomID())
if err := d.createSSHKey(); err != nil {
return err
}
}
if err := d.createMachine(); err != nil {
return err
@@ -397,6 +417,7 @@ func (d *Driver) Remove() error {
return err
}
log.Debug("deleting key pair...", map[string]string{"Name": d.KeyPairName})
// TODO (fsoppelsa) maybe we want to check this, in case of shared keypairs, before removal
if err := d.client.DeleteKeyPair(d, d.KeyPairName); err != nil {
return err
}
@@ -422,6 +443,7 @@ const (
errorMandatoryEnvOrOption string = "%s must be specified either using the environment variable %s or the CLI option %s"
errorMandatoryOption string = "%s must be specified using the CLI option %s"
errorExclusiveOptions string = "Either %s or %s must be specified, not both"
errorBothOptions string = "Both %s and %s must be specified"
errorMandatoryTenantNameOrID string = "Tenant id or name must be provided either using one of the environment variables OS_TENANT_ID and OS_TENANT_NAME or one of the CLI options --openstack-tenant-id and --openstack-tenant-name"
errorWrongEndpointType string = "Endpoint type must be 'publicURL', 'adminURL' or 'internalURL'"
errorUnknownFlavorName string = "Unable to find flavor named %s"
@@ -464,6 +486,9 @@ func (d *Driver) checkConfig() error {
if d.EndpointType != "" && (d.EndpointType != "publicURL" && d.EndpointType != "adminURL" && d.EndpointType != "internalURL") {
return fmt.Errorf(errorWrongEndpointType)
}
if (d.KeyPairName != "" && d.PrivateKeyFile == "") || (d.KeyPairName == "" && d.PrivateKeyFile != "") {
return fmt.Errorf(errorBothOptions, "KeyPairName", "PrivateKeyFile")
}
return nil
}
@@ -607,6 +632,30 @@ func (d *Driver) initNetwork() error {
return nil
}
func (d *Driver) loadSSHKey() error {
log.Debug("Loading Key Pair", d.KeyPairName)
if err := d.initCompute(); err != nil {
return err
}
log.Debug("Loading Private Key from", d.PrivateKeyFile)
privateKey, err := ioutil.ReadFile(d.PrivateKeyFile)
if err != nil {
return err
}
publicKey, err := d.client.GetPublicKey(d.KeyPairName)
if err != nil {
return err
}
if err := ioutil.WriteFile(d.privateSSHKeyPath(), privateKey, 0600); err != nil {
return err
}
if err := ioutil.WriteFile(d.publicSSHKeyPath(), publicKey, 0600); err != nil {
return err
}
return nil
}
func (d *Driver) createSSHKey() error {
sanitizeKeyPairName(&d.KeyPairName)
log.Debug("Creating Key Pair...", map[string]string{"Name": d.KeyPairName})
@@ -715,6 +764,10 @@ func (d *Driver) lookForIPAddress() error {
return nil
}
func (d *Driver) privateSSHKeyPath() string {
return d.GetSSHKeyPath()
}
func (d *Driver) publicSSHKeyPath() string {
return d.GetSSHKeyPath() + ".pub"
}