mirror of https://github.com/docker/docs.git
				
				
				
			Merge pull request #2593 from fsoppelsa/1738-reusekeypairs
Add --openstack-keypair-name and --openstack-private-key-file
This commit is contained in:
		
						commit
						626bd0df89
					
				|  | @ -28,10 +28,12 @@ Options: | |||
| -   `--openstack-floatingip-pool`: The IP pool that will be used to get a public IP can assign it to the machine. If there is an | ||||
|     IP address already allocated but not assigned to any machine, this IP will be chosen and assigned to the machine. If | ||||
|     there is no IP address already allocated a new IP will be allocated and assigned to the machine. | ||||
| -   `--openstack-keypair-name`: Specify the existing Nova keypair to use. | ||||
| -   `--openstack-insecure`: Explicitly allow openstack driver to perform "insecure" SSL (https) requests. The server's certificate will not be verified against any certificate authorities. This option should be used with caution. | ||||
| -   `--openstack-ip-version`: If the instance has both IPv4 and IPv6 address, you can select IP version. If not provided `4` will be used. | ||||
| -   `--openstack-net-name` or `--openstack-net-id`: Identify the private network the machine will be connected on. If your OpenStack project project contains only one private network it will be use automatically. | ||||
| -   `--openstack-password`: User password. It can be omitted if the standard environment variable `OS_PASSWORD` is set. | ||||
| -   `--openstack-private-key-file`: Used with `--openstack-keypair-name`, associates the private key to the keypair. | ||||
| -   `--openstack-region`: The region to work on. Can be omitted if there is only one region on the OpenStack. | ||||
| -   `--openstack-sec-groups`: If security groups are available on your OpenStack you can specify a comma separated list | ||||
|     to use for the machine (e.g. `secgrp001,secgrp002`). | ||||
|  | @ -57,9 +59,11 @@ Environment variables and default values: | |||
| | `--openstack-image-name`        | `OS_IMAGE_NAME`        | -           | | ||||
| | `--openstack-insecure`          | `OS_INSECURE`          | `false`     | | ||||
| | `--openstack-ip-version`        | `OS_IP_VERSION`        | `4`         | | ||||
| | `--openstack-keypair-name`      | `OS_KEYPAIR_NAME`      | -           | | ||||
| | `--openstack-net-id`            | `OS_NETWORK_ID`        | -           | | ||||
| | `--openstack-net-name`          | `OS_NETWORK_NAME`      | -           | | ||||
| | `--openstack-password`          | `OS_PASSWORD`          | -           | | ||||
| | `--openstack-private-key-file`  | `OS_PRIVATE_KEY_FILE`  | -           | | ||||
| | `--openstack-region`            | `OS_REGION_NAME`       | -           | | ||||
| | `--openstack-sec-groups`        | `OS_SECURITY_GROUPS`   | -           | | ||||
| | `--openstack-ssh-port`          | `OS_SSH_PORT`          | `22`        | | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ type Client interface { | |||
| 	DeleteInstance(d *Driver) error | ||||
| 	WaitForInstanceStatus(d *Driver, status string) error | ||||
| 	GetInstanceIPAddresses(d *Driver) ([]IPAddress, error) | ||||
| 	GetPublicKey(keyPairName string) ([]byte, error) | ||||
| 	CreateKeyPair(d *Driver, name string, publicKey string) error | ||||
| 	DeleteKeyPair(d *Driver, name string) error | ||||
| 	GetNetworkID(d *Driver) (string, error) | ||||
|  | @ -300,6 +301,14 @@ func (c *GenericClient) GetTenantID(d *Driver) (string, error) { | |||
| 	return tenantId, err | ||||
| } | ||||
| 
 | ||||
| func (c *GenericClient) GetPublicKey(keyPairName string) ([]byte, error) { | ||||
| 	kp, err := keypairs.Get(c.Compute, keyPairName).Extract() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return []byte(kp.PublicKey), nil | ||||
| } | ||||
| 
 | ||||
| func (c *GenericClient) CreateKeyPair(d *Driver, name string, publicKey string) error { | ||||
| 	opts := keypairs.CreateOpts{ | ||||
| 		Name:      name, | ||||
|  |  | |||
|  | @ -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" | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue