diff --git a/drivers/openstack/client.go b/drivers/openstack/client.go index 55919f0..1cd1393 100644 --- a/drivers/openstack/client.go +++ b/drivers/openstack/client.go @@ -11,6 +11,7 @@ import ( "github.com/docker/machine/libmachine/version" "github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud/openstack" + compute_ips "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip" "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs" "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop" "github.com/rackspace/gophercloud/openstack/compute/v2/flavors" @@ -40,7 +41,7 @@ type Client interface { GetNetworkId(d *Driver) (string, error) GetFlavorId(d *Driver) (string, error) GetImageId(d *Driver) (string, error) - AssignFloatingIP(d *Driver, floatingIp *FloatingIp, portId string) error + AssignFloatingIP(d *Driver, floatingIp *FloatingIp) error GetFloatingIPs(d *Driver) ([]FloatingIp, error) GetFloatingIpPoolId(d *Driver) (string, error) GetInstancePortId(d *Driver) (string, error) @@ -98,6 +99,8 @@ type FloatingIp struct { Ip string NetworkId string PortId string + Pool string + MachineId string } func (c *GenericClient) GetInstanceState(d *Driver) (string, error) { @@ -296,7 +299,33 @@ func (c *GenericClient) GetServerDetail(d *Driver) (*servers.Server, error) { return server, nil } -func (c *GenericClient) AssignFloatingIP(d *Driver, floatingIp *FloatingIp, portId string) error { +func (c *GenericClient) AssignFloatingIP(d *Driver, floatingIp *FloatingIp) error { + if d.ComputeNetwork { + return c.assignNovaFloatingIP(d, floatingIp) + } else { + return c.assignNeutronFloatingIP(d, floatingIp) + } +} + +func (c *GenericClient) assignNovaFloatingIP(d *Driver, floatingIp *FloatingIp) error { + if floatingIp.Ip == "" { + f, err := compute_ips.Create(c.Compute, compute_ips.CreateOpts{ + Pool: d.FloatingIpPool, + }).Extract() + if err != nil { + return err + } + floatingIp.Ip = f.IP + floatingIp.Pool = f.Pool + } + return compute_ips.Associate(c.Compute, d.MachineId, floatingIp.Ip).Err +} + +func (c *GenericClient) assignNeutronFloatingIP(d *Driver, floatingIp *FloatingIp) error { + portId, err := c.GetInstancePortId(d) + if err != nil { + return err + } if floatingIp.Id == "" { f, err := floatingips.Create(c.Network, floatingips.CreateOpts{ FloatingNetworkID: d.FloatingIpPoolId, @@ -311,7 +340,7 @@ func (c *GenericClient) AssignFloatingIP(d *Driver, floatingIp *FloatingIp, port floatingIp.PortId = f.PortID return nil } - _, err := floatingips.Update(c.Network, floatingIp.Id, floatingips.UpdateOpts{ + _, err = floatingips.Update(c.Network, floatingIp.Id, floatingips.UpdateOpts{ PortID: portId, }).Extract() if err != nil { @@ -321,6 +350,36 @@ func (c *GenericClient) AssignFloatingIP(d *Driver, floatingIp *FloatingIp, port } func (c *GenericClient) GetFloatingIPs(d *Driver) ([]FloatingIp, error) { + if d.ComputeNetwork { + return c.getNovaNetworkFloatingIPs(d) + } else { + return c.getNeutronNetworkFloatingIPs(d) + } +} + +func (c *GenericClient) getNovaNetworkFloatingIPs(d *Driver) ([]FloatingIp, error) { + pager := compute_ips.List(c.Compute) + + ips := []FloatingIp{} + err := pager.EachPage(func(page pagination.Page) (continue_paging bool, err error) { + continue_paging, err = true, nil + ip_listing, err := compute_ips.ExtractFloatingIPs(page) + + for _, ip := range ip_listing { + if ip.InstanceID == "" && ip.Pool == d.FloatingIpPool { + ips = append(ips, FloatingIp{ + Id: ip.ID, + Ip: ip.IP, + Pool: ip.Pool, + }) + } + } + return + }) + return ips, err +} + +func (c *GenericClient) getNeutronNetworkFloatingIPs(d *Driver) ([]FloatingIp, error) { pager := floatingips.List(c.Network, floatingips.ListOpts{ FloatingNetworkID: d.FloatingIpPoolId, }) diff --git a/drivers/openstack/openstack.go b/drivers/openstack/openstack.go index 8b034a4..7a59670 100644 --- a/drivers/openstack/openstack.go +++ b/drivers/openstack/openstack.go @@ -38,6 +38,7 @@ type Driver struct { NetworkId string SecurityGroups []string FloatingIpPool string + ComputeNetwork bool FloatingIpPoolId string IpVersion int client Client @@ -158,6 +159,11 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag { 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", @@ -182,16 +188,6 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag { Usage: "OpenStack SSH port", Value: defaultSSHPort, }, - mcnflag.StringFlag{ - Name: "openstack-ssh-user", - Usage: "OpenStack SSH user", - Value: defaultSSHUser, - }, - mcnflag.IntFlag{ - Name: "openstack-ssh-port", - Usage: "OpenStack SSH port", - Value: defaultSSHPort, - }, mcnflag.IntFlag{ EnvVar: "OS_ACTIVE_TIMEOUT", Name: "openstack-active-timeout", @@ -250,6 +246,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { } d.FloatingIpPool = flags.String("openstack-floatingip-pool") 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.SwarmMaster = flags.Bool("swarm-master") @@ -468,7 +465,7 @@ func (d *Driver) checkConfig() error { } func (d *Driver) resolveIds() error { - if d.NetworkName != "" { + if d.NetworkName != "" && !d.ComputeNetwork { if err := d.initNetwork(); err != nil { return err } @@ -532,7 +529,7 @@ func (d *Driver) resolveIds() error { }).Debug("Found image id using its name") } - if d.FloatingIpPool != "" { + if d.FloatingIpPool != "" && !d.ComputeNetwork { if err := d.initNetwork(); err != nil { return err } @@ -613,12 +610,14 @@ func (d *Driver) createMachine() error { } func (d *Driver) assignFloatingIp() error { + var err error - if err := d.initNetwork(); err != nil { - return err + if d.ComputeNetwork { + err = d.initCompute() + } else { + err = d.initNetwork() } - portId, err := d.client.GetInstancePortId(d) if err != nil { return err } @@ -653,7 +652,7 @@ func (d *Driver) assignFloatingIp() error { log.WithField("MachineId", d.MachineId).Debugf("Assigning floating IP to the instance") } - if err := d.client.AssignFloatingIP(d, floatingIp, portId); err != nil { + if err := d.client.AssignFloatingIP(d, floatingIp); err != nil { return err } d.IPAddress = floatingIp.Ip