Files
docker-machine/drivers/openstack/openstack.go
T

766 lines
19 KiB
Go
Raw Normal View History

2014-12-10 15:56:28 +01:00
package openstack
import (
"fmt"
"io/ioutil"
"net"
2014-12-10 15:56:28 +01:00
"strings"
"time"
2014-12-10 15:56:28 +01:00
2015-08-18 11:26:42 +09:00
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/mcnflag"
2015-08-18 11:26:42 +09:00
"github.com/docker/machine/libmachine/mcnutils"
"github.com/docker/machine/libmachine/ssh"
"github.com/docker/machine/libmachine/state"
2014-12-10 15:56:28 +01:00
)
type Driver struct {
*drivers.BaseDriver
AuthUrl string
ActiveTimeout int
Insecure bool
2015-04-09 17:40:21 +02:00
DomainID string
DomainName string
Username string
Password string
TenantName string
TenantId string
Region string
2015-06-05 17:31:09 -07:00
AvailabilityZone string
EndpointType string
MachineId string
FlavorName string
FlavorId string
ImageName string
ImageId string
KeyPairName string
NetworkName string
NetworkId string
PrivateKeyFile string
SecurityGroups []string
FloatingIpPool string
ComputeNetwork bool
FloatingIpPoolId string
2015-10-04 23:43:42 +09:00
IpVersion int
client Client
2014-12-10 15:56:28 +01:00
}
2015-08-18 11:26:42 +09:00
const (
defaultSSHUser = "root"
defaultSSHPort = 22
defaultActiveTimeout = 200
)
func (d *Driver) GetCreateFlags() []mcnflag.Flag {
return []mcnflag.Flag{
mcnflag.StringFlag{
EnvVar: "OS_AUTH_URL",
Name: "openstack-auth-url",
Usage: "OpenStack authentication URL",
Value: "",
},
mcnflag.BoolFlag{
EnvVar: "OS_INSECURE",
Name: "openstack-insecure",
Usage: "Disable TLS credential checking.",
},
mcnflag.StringFlag{
2015-04-09 17:40:21 +02:00
EnvVar: "OS_DOMAIN_ID",
Name: "openstack-domain-id",
Usage: "OpenStack domain ID (identity v3 only)",
Value: "",
},
mcnflag.StringFlag{
2015-04-09 17:40:21 +02:00
EnvVar: "OS_DOMAIN_NAME",
Name: "openstack-domain-name",
Usage: "OpenStack domain name (identity v3 only)",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_USERNAME",
Name: "openstack-username",
Usage: "OpenStack username",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_PASSWORD",
Name: "openstack-password",
Usage: "OpenStack password",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_TENANT_NAME",
Name: "openstack-tenant-name",
Usage: "OpenStack tenant name",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_TENANT_ID",
Name: "openstack-tenant-id",
Usage: "OpenStack tenant id",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_REGION_NAME",
Name: "openstack-region",
Usage: "OpenStack region name",
Value: "",
},
mcnflag.StringFlag{
2015-06-05 17:31:09 -07:00
EnvVar: "OS_AVAILABILITY_ZONE",
Name: "openstack-availability-zone",
Usage: "OpenStack availability zone",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_ENDPOINT_TYPE",
Name: "openstack-endpoint-type",
Usage: "OpenStack endpoint type (adminURL, internalURL or publicURL)",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_FLAVOR_ID",
Name: "openstack-flavor-id",
Usage: "OpenStack flavor id to use for the instance",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_FLAVOR_NAME",
Name: "openstack-flavor-name",
Usage: "OpenStack flavor name to use for the instance",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_IMAGE_ID",
Name: "openstack-image-id",
Usage: "OpenStack image id to use for the instance",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_IMAGE_NAME",
Name: "openstack-image-name",
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",
Usage: "OpenStack network name the machine will be connected on",
Value: "",
},
mcnflag.StringFlag{
EnvVar: "OS_SECURITY_GROUPS",
Name: "openstack-sec-groups",
Usage: "OpenStack comma separated security groups for the machine",
Value: "",
},
mcnflag.BoolFlag{
EnvVar: "OS_NOVA_NETWORK",
Name: "openstack-nova-network",
Usage: "Use the nova networking services instead of neutron.",
},
mcnflag.StringFlag{
EnvVar: "OS_FLOATINGIP_POOL",
Name: "openstack-floatingip-pool",
Usage: "OpenStack floating IP pool to get an IP from to assign to the instance",
Value: "",
},
mcnflag.IntFlag{
2015-10-04 23:43:42 +09:00
EnvVar: "OS_IP_VERSION",
Name: "openstack-ip-version",
Usage: "OpenStack version of IP address assigned for the machine",
Value: 4,
},
mcnflag.StringFlag{
EnvVar: "OS_SSH_USER",
Name: "openstack-ssh-user",
Usage: "OpenStack SSH user",
Value: defaultSSHUser,
},
mcnflag.IntFlag{
EnvVar: "OS_SSH_PORT",
Name: "openstack-ssh-port",
Usage: "OpenStack SSH port",
Value: defaultSSHPort,
},
mcnflag.IntFlag{
EnvVar: "OS_ACTIVE_TIMEOUT",
Name: "openstack-active-timeout",
Usage: "OpenStack active timeout",
Value: defaultActiveTimeout,
},
}
2014-12-10 15:56:28 +01:00
}
2015-08-18 11:26:42 +09:00
func NewDriver(hostName, storePath string) drivers.Driver {
return NewDerivedDriver(hostName, storePath)
2014-12-11 10:14:49 -05:00
}
2015-08-18 11:26:42 +09:00
func NewDerivedDriver(hostName, storePath string) *Driver {
return &Driver{
client: &GenericClient{},
ActiveTimeout: defaultActiveTimeout,
BaseDriver: &drivers.BaseDriver{
SSHUser: defaultSSHUser,
SSHPort: defaultSSHPort,
MachineName: hostName,
StorePath: storePath,
},
}
2015-03-09 23:27:17 -04:00
}
func (d *Driver) GetSSHHostname() (string, error) {
return d.GetIP()
}
2015-11-06 18:16:15 +00:00
func (d *Driver) SetClient(client Client) {
d.client = client
}
2015-11-05 18:04:40 -08:00
// DriverName returns the name of the driver
2014-12-10 15:56:28 +01:00
func (d *Driver) DriverName() string {
return "openstack"
}
func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.AuthUrl = flags.String("openstack-auth-url")
d.ActiveTimeout = flags.Int("openstack-active-timeout")
d.Insecure = flags.Bool("openstack-insecure")
2015-04-09 17:40:21 +02:00
d.DomainID = flags.String("openstack-domain-id")
d.DomainName = flags.String("openstack-domain-name")
d.Username = flags.String("openstack-username")
d.Password = flags.String("openstack-password")
d.TenantName = flags.String("openstack-tenant-name")
d.TenantId = flags.String("openstack-tenant-id")
d.Region = flags.String("openstack-region")
2015-06-05 17:31:09 -07:00
d.AvailabilityZone = flags.String("openstack-availability-zone")
d.EndpointType = flags.String("openstack-endpoint-type")
d.FlavorId = flags.String("openstack-flavor-id")
d.FlavorName = flags.String("openstack-flavor-name")
d.ImageId = flags.String("openstack-image-id")
d.ImageName = flags.String("openstack-image-name")
d.NetworkId = flags.String("openstack-net-id")
d.NetworkName = flags.String("openstack-net-name")
if flags.String("openstack-sec-groups") != "" {
d.SecurityGroups = strings.Split(flags.String("openstack-sec-groups"), ",")
2014-12-10 15:56:28 +01:00
}
d.FloatingIpPool = flags.String("openstack-floatingip-pool")
2015-10-04 23:43:42 +09:00
d.IpVersion = flags.Int("openstack-ip-version")
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")
2015-12-29 10:14:53 +01:00
d.SetSwarmConfigFromFlags(flags)
2014-12-15 02:34:41 +01:00
2014-12-10 15:56:28 +01:00
return d.checkConfig()
}
func (d *Driver) GetURL() (string, error) {
ip, err := d.GetIP()
if err != nil {
return "", err
}
if ip == "" {
return "", nil
}
return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, "2376")), nil
2014-12-10 15:56:28 +01:00
}
func (d *Driver) GetIP() (string, error) {
if d.IPAddress != "" {
return d.IPAddress, nil
}
2015-12-03 17:22:36 +01:00
log.Debug("Looking for the IP address...", map[string]string{"MachineId": d.MachineId})
if err := d.initCompute(); err != nil {
2014-12-10 15:56:28 +01:00
return "", err
}
addressType := Fixed
if d.FloatingIpPool != "" {
addressType = Floating
}
2014-12-10 15:56:28 +01:00
// Looking for the IP address in a retry loop to deal with OpenStack latency
for retryCount := 0; retryCount < 200; retryCount++ {
2015-11-05 18:04:40 -08:00
addresses, err := d.client.GetInstanceIPAddresses(d)
if err != nil {
return "", err
2014-12-10 15:56:28 +01:00
}
for _, a := range addresses {
2015-10-04 23:43:42 +09:00
if a.AddressType == addressType && a.Version == d.IpVersion {
return a.Address, nil
}
2014-12-10 15:56:28 +01:00
}
time.Sleep(2 * time.Second)
2014-12-10 15:56:28 +01:00
}
return "", fmt.Errorf("No IP found for the machine")
}
func (d *Driver) GetState() (state.State, error) {
2015-12-03 17:22:36 +01:00
log.Debug("Get status for OpenStack instance...", map[string]string{"MachineId": d.MachineId})
if err := d.initCompute(); err != nil {
return state.None, err
}
2014-12-10 15:56:28 +01:00
s, err := d.client.GetInstanceState(d)
if err != nil {
return state.None, err
}
2015-12-03 17:22:36 +01:00
log.Debug("State for OpenStack instance", map[string]string{
2014-12-10 15:56:28 +01:00
"MachineId": d.MachineId,
"State": s,
2015-12-03 17:22:36 +01:00
})
2014-12-10 15:56:28 +01:00
switch s {
case "ACTIVE":
return state.Running, nil
case "PAUSED":
return state.Paused, nil
case "SUSPENDED":
return state.Saved, nil
case "SHUTOFF":
return state.Stopped, nil
case "BUILDING":
return state.Starting, nil
case "ERROR":
return state.Error, nil
}
return state.None, nil
}
func (d *Driver) Create() error {
if err := d.resolveIds(); 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
}
2014-12-10 15:56:28 +01:00
}
if err := d.createMachine(); err != nil {
return err
}
if err := d.waitForInstanceActive(); err != nil {
return err
}
if d.FloatingIpPool != "" {
2015-11-05 18:04:40 -08:00
if err := d.assignFloatingIP(); err != nil {
return err
}
}
2015-11-05 18:04:40 -08:00
if err := d.lookForIPAddress(); err != nil {
return err
}
2014-12-10 15:56:28 +01:00
return nil
}
func (d *Driver) Start() error {
if err := d.initCompute(); err != nil {
return err
}
2015-12-30 11:50:39 +01:00
return d.client.StartInstance(d)
2014-12-10 15:56:28 +01:00
}
func (d *Driver) Stop() error {
if err := d.initCompute(); err != nil {
return err
}
2014-12-10 15:56:28 +01:00
2015-12-30 11:50:39 +01:00
return d.client.StopInstance(d)
2014-12-10 15:56:28 +01:00
}
2015-12-30 11:57:37 +01:00
func (d *Driver) Restart() error {
if err := d.initCompute(); err != nil {
2014-12-10 15:56:28 +01:00
return err
}
2015-12-30 11:57:37 +01:00
return d.client.RestartInstance(d)
}
2015-12-30 12:05:12 +01:00
func (d *Driver) Kill() error {
return d.Stop()
2014-12-10 15:56:28 +01:00
}
func (d *Driver) Remove() error {
2015-12-03 17:22:36 +01:00
log.Debug("deleting instance...", map[string]string{"MachineId": d.MachineId})
log.Info("Deleting OpenStack instance...")
if err := d.initCompute(); err != nil {
return err
}
2014-12-10 15:56:28 +01:00
if err := d.client.DeleteInstance(d); err != nil {
return err
}
2015-12-03 17:22:36 +01:00
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
2014-12-10 15:56:28 +01:00
if err := d.client.DeleteKeyPair(d, d.KeyPairName); err != nil {
return err
}
return nil
}
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"
2015-11-05 18:04:40 -08:00
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"
2014-12-10 15:56:28 +01:00
errorWrongEndpointType string = "Endpoint type must be 'publicURL', 'adminURL' or 'internalURL'"
errorUnknownFlavorName string = "Unable to find flavor named %s"
errorUnknownImageName string = "Unable to find image named %s"
errorUnknownNetworkName string = "Unable to find network named %s"
2015-12-15 22:30:49 +00:00
errorUnknownTenantName string = "Unable to find tenant named %s"
2014-12-10 15:56:28 +01:00
)
func (d *Driver) checkConfig() error {
if d.AuthUrl == "" {
2015-03-23 18:31:34 -05:00
return fmt.Errorf(errorMandatoryEnvOrOption, "Authentication URL", "OS_AUTH_URL", "--openstack-auth-url")
2014-12-10 15:56:28 +01:00
}
if d.Username == "" {
return fmt.Errorf(errorMandatoryEnvOrOption, "Username", "OS_USERNAME", "--openstack-username")
}
if d.Password == "" {
return fmt.Errorf(errorMandatoryEnvOrOption, "Password", "OS_PASSWORD", "--openstack-password")
}
if d.TenantName == "" && d.TenantId == "" {
2015-11-05 18:04:40 -08:00
return fmt.Errorf(errorMandatoryTenantNameOrID)
2014-12-10 15:56:28 +01:00
}
if d.FlavorName == "" && d.FlavorId == "" {
return fmt.Errorf(errorMandatoryOption, "Flavor name or Flavor id", "--openstack-flavor-name or --openstack-flavor-id")
2014-12-10 15:56:28 +01:00
}
if d.FlavorName != "" && d.FlavorId != "" {
return fmt.Errorf(errorExclusiveOptions, "Flavor name", "Flavor id")
2014-12-10 15:56:28 +01:00
}
if d.ImageName == "" && d.ImageId == "" {
return fmt.Errorf(errorMandatoryOption, "Image name or Image id", "--openstack-image-name or --openstack-image-id")
}
if d.ImageName != "" && d.ImageId != "" {
return fmt.Errorf(errorExclusiveOptions, "Image name", "Image id")
}
if d.NetworkName != "" && d.NetworkId != "" {
return fmt.Errorf(errorExclusiveOptions, "Network name", "Network id")
}
2014-12-11 14:34:30 -05:00
if d.EndpointType != "" && (d.EndpointType != "publicURL" && d.EndpointType != "adminURL" && d.EndpointType != "internalURL") {
2014-12-10 15:56:28 +01:00
return fmt.Errorf(errorWrongEndpointType)
}
if (d.KeyPairName != "" && d.PrivateKeyFile == "") || (d.KeyPairName == "" && d.PrivateKeyFile != "") {
return fmt.Errorf(errorBothOptions, "KeyPairName", "PrivateKeyFile")
}
2014-12-10 15:56:28 +01:00
return nil
}
func (d *Driver) resolveIds() error {
if d.NetworkName != "" && !d.ComputeNetwork {
if err := d.initNetwork(); err != nil {
return err
}
2015-11-05 18:04:40 -08:00
networkID, err := d.client.GetNetworkID(d)
if err != nil {
return err
}
2015-11-05 18:04:40 -08:00
if networkID == "" {
return fmt.Errorf(errorUnknownNetworkName, d.NetworkName)
}
2015-11-05 18:04:40 -08:00
d.NetworkId = networkID
2015-12-03 17:22:36 +01:00
log.Debug("Found network id using its name", map[string]string{
"Name": d.NetworkName,
"ID": d.NetworkId,
2015-12-03 17:22:36 +01:00
})
}
if d.FlavorName != "" {
if err := d.initCompute(); err != nil {
return err
}
2015-11-05 18:04:40 -08:00
flavorID, err := d.client.GetFlavorID(d)
if err != nil {
return err
}
2015-11-05 18:04:40 -08:00
if flavorID == "" {
return fmt.Errorf(errorUnknownFlavorName, d.FlavorName)
}
2015-11-05 18:04:40 -08:00
d.FlavorId = flavorID
2015-12-03 17:22:36 +01:00
log.Debug("Found flavor id using its name", map[string]string{
"Name": d.FlavorName,
"ID": d.FlavorId,
2015-12-03 17:22:36 +01:00
})
}
if d.ImageName != "" {
if err := d.initCompute(); err != nil {
return err
}
2015-11-05 18:04:40 -08:00
imageID, err := d.client.GetImageID(d)
if err != nil {
return err
}
2015-11-05 18:04:40 -08:00
if imageID == "" {
return fmt.Errorf(errorUnknownImageName, d.ImageName)
}
2015-11-05 18:04:40 -08:00
d.ImageId = imageID
2015-12-03 17:22:36 +01:00
log.Debug("Found image id using its name", map[string]string{
"Name": d.ImageName,
"ID": d.ImageId,
2015-12-03 17:22:36 +01:00
})
}
if d.FloatingIpPool != "" && !d.ComputeNetwork {
if err := d.initNetwork(); err != nil {
return err
}
2015-11-05 18:04:40 -08:00
f, err := d.client.GetFloatingIPPoolID(d)
if err != nil {
return err
}
if f == "" {
return fmt.Errorf(errorUnknownNetworkName, d.FloatingIpPool)
}
d.FloatingIpPoolId = f
2015-12-03 17:22:36 +01:00
log.Debug("Found floating IP pool id using its name", map[string]string{
"Name": d.FloatingIpPool,
"ID": d.FloatingIpPoolId,
2015-12-03 17:22:36 +01:00
})
}
if d.TenantName != "" && d.TenantId == "" {
2015-12-15 22:30:49 +00:00
if err := d.initIdentity(); err != nil {
return err
}
tenantId, err := d.client.GetTenantID(d)
if err != nil {
return err
}
if tenantId == "" {
return fmt.Errorf(errorUnknownTenantName, d.TenantName)
}
d.TenantId = tenantId
log.Debug("Found tenant id using its name", map[string]string{
"Name": d.TenantName,
"ID": d.TenantId,
})
}
return nil
}
func (d *Driver) initCompute() error {
if err := d.client.Authenticate(d); err != nil {
return err
}
if err := d.client.InitComputeClient(d); err != nil {
return err
}
return nil
}
2015-12-15 22:30:49 +00:00
func (d *Driver) initIdentity() error {
if err := d.client.Authenticate(d); err != nil {
return err
}
if err := d.client.InitIdentityClient(d); err != nil {
return err
}
return nil
}
func (d *Driver) initNetwork() error {
if err := d.client.Authenticate(d); err != nil {
return err
}
if err := d.client.InitNetworkClient(d); err != nil {
return err
}
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
}
2014-12-10 15:56:28 +01:00
func (d *Driver) createSSHKey() error {
sanitizeKeyPairName(&d.KeyPairName)
2015-12-03 17:22:36 +01:00
log.Debug("Creating Key Pair...", map[string]string{"Name": d.KeyPairName})
2015-03-09 23:29:52 -04:00
if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil {
2014-12-10 15:56:28 +01:00
return err
}
publicKey, err := ioutil.ReadFile(d.publicSSHKeyPath())
if err != nil {
return err
}
if err := d.initCompute(); err != nil {
return err
}
2014-12-10 15:56:28 +01:00
if err := d.client.CreateKeyPair(d, d.KeyPairName, string(publicKey)); err != nil {
return err
}
return nil
}
func (d *Driver) createMachine() error {
2015-12-03 17:22:36 +01:00
log.Debug("Creating OpenStack instance...", map[string]string{
2014-12-10 15:56:28 +01:00
"FlavorId": d.FlavorId,
"ImageId": d.ImageId,
2015-12-03 17:22:36 +01:00
})
if err := d.initCompute(); err != nil {
return err
}
2015-11-05 18:04:40 -08:00
instanceID, err := d.client.CreateInstance(d)
2014-12-10 15:56:28 +01:00
if err != nil {
return err
}
2015-11-05 18:04:40 -08:00
d.MachineId = instanceID
2014-12-10 15:56:28 +01:00
return nil
}
2015-11-05 18:04:40 -08:00
func (d *Driver) assignFloatingIP() error {
var err error
if d.ComputeNetwork {
err = d.initCompute()
} else {
err = d.initNetwork()
}
if err != nil {
return err
}
ips, err := d.client.GetFloatingIPs(d)
if err != nil {
return err
}
2015-11-05 18:04:40 -08:00
var floatingIP *FloatingIP
2015-12-03 17:22:36 +01:00
log.Debugf("Looking for an available floating IP", map[string]string{
"MachineId": d.MachineId,
"Pool": d.FloatingIpPool,
2015-12-03 17:22:36 +01:00
})
for _, ip := range ips {
if ip.PortId == "" {
2015-12-03 17:22:36 +01:00
log.Debug("Available floating IP found", map[string]string{
"MachineId": d.MachineId,
"IP": ip.Ip,
2015-12-03 17:22:36 +01:00
})
2015-11-05 18:04:40 -08:00
floatingIP = &ip
break
}
}
2015-11-05 18:04:40 -08:00
if floatingIP == nil {
floatingIP = &FloatingIP{}
2015-12-03 17:22:36 +01:00
log.Debug("No available floating IP found. Allocating a new one...", map[string]string{"MachineId": d.MachineId})
} else {
2015-12-03 17:22:36 +01:00
log.Debug("Assigning floating IP to the instance", map[string]string{"MachineId": d.MachineId})
}
2015-11-05 18:04:40 -08:00
if err := d.client.AssignFloatingIP(d, floatingIP); err != nil {
return err
}
2015-11-05 18:04:40 -08:00
d.IPAddress = floatingIP.Ip
return nil
}
func (d *Driver) waitForInstanceActive() error {
2015-12-03 17:22:36 +01:00
log.Debug("Waiting for the OpenStack instance to be ACTIVE...", map[string]string{"MachineId": d.MachineId})
if err := d.client.WaitForInstanceStatus(d, "ACTIVE"); err != nil {
2014-12-10 15:56:28 +01:00
return err
}
return nil
}
2015-11-05 18:04:40 -08:00
func (d *Driver) lookForIPAddress() error {
2014-12-10 15:56:28 +01:00
ip, err := d.GetIP()
if err != nil {
return err
}
d.IPAddress = ip
2015-12-03 17:22:36 +01:00
log.Debug("IP address found", map[string]string{
"IP": ip,
"MachineId": d.MachineId,
2015-12-03 17:22:36 +01:00
})
return nil
}
func (d *Driver) privateSSHKeyPath() string {
return d.GetSSHKeyPath()
}
2014-12-10 15:56:28 +01:00
func (d *Driver) publicSSHKeyPath() string {
2015-03-09 23:29:52 -04:00
return d.GetSSHKeyPath() + ".pub"
2014-12-10 15:56:28 +01:00
}
func sanitizeKeyPairName(s *string) {
*s = strings.Replace(*s, ".", "_", -1)
}