Rackspace/Openstack - Add/enhance --*-net-* create switches.

Signed-off-by: Robert Jones <robert@justjones.org>
This commit is contained in:
Robert Jones 2015-07-05 17:08:39 +00:00
parent 26b00ce1ec
commit 07cadc68a5
4 changed files with 120 additions and 52 deletions

View File

@ -41,7 +41,8 @@ type Client interface {
GetPublicKey(keyPairName string) ([]byte, error) GetPublicKey(keyPairName string) ([]byte, error)
CreateKeyPair(d *Driver, name string, publicKey string) error CreateKeyPair(d *Driver, name string, publicKey string) error
DeleteKeyPair(d *Driver, name string) error DeleteKeyPair(d *Driver, name string) error
GetNetworkID(d *Driver) (string, error) GetNetworkIDs(d *Driver) ([]string, error)
GetNetworkID(d *Driver, networkName string) (string, error)
GetFlavorID(d *Driver) (string, error) GetFlavorID(d *Driver) (string, error)
GetImageID(d *Driver) (string, error) GetImageID(d *Driver) (string, error)
AssignFloatingIP(d *Driver, floatingIP *FloatingIP) error AssignFloatingIP(d *Driver, floatingIP *FloatingIP) error
@ -66,12 +67,12 @@ func (c *GenericClient) CreateInstance(d *Driver) (string, error) {
SecurityGroups: d.SecurityGroups, SecurityGroups: d.SecurityGroups,
AvailabilityZone: d.AvailabilityZone, AvailabilityZone: d.AvailabilityZone,
} }
if d.NetworkId != "" { if len(d.NetworkIds) > 0 {
serverOpts.Networks = []servers.Network{ networks := make([]servers.Network, len(d.NetworkIds))
{ for i, networkId := range d.NetworkIds {
UUID: d.NetworkId, networks[i] = servers.Network{UUID: networkId}
},
} }
serverOpts.Networks = networks
} }
log.Info("Creating machine...") log.Info("Creating machine...")
@ -199,15 +200,23 @@ func (c *GenericClient) GetInstanceIPAddresses(d *Driver) ([]IPAddress, error) {
return addresses, nil return addresses, nil
} }
func (c *GenericClient) GetNetworkID(d *Driver) (string, error) { func (c *GenericClient) GetNetworkIDs(d *Driver) ([]string, error) {
return c.getNetworkID(d, d.NetworkName) networkIDs := make([]string, len(d.NetworkNames))
for i, networkName := range d.NetworkNames {
id, err := c.GetNetworkID(d, networkName)
if err != nil {
return nil, err
}
networkIDs[i] = id
}
return networkIDs, nil
} }
func (c *GenericClient) GetFloatingIPPoolID(d *Driver) (string, error) { func (c *GenericClient) GetFloatingIPPoolID(d *Driver) (string, error) {
return c.getNetworkID(d, d.FloatingIpPool) return c.GetNetworkID(d, d.FloatingIPPool)
} }
func (c *GenericClient) getNetworkID(d *Driver, networkName string) (string, error) { func (c *GenericClient) GetNetworkID(d *Driver, networkName string) (string, error) {
opts := networks.ListOpts{Name: networkName} opts := networks.ListOpts{Name: networkName}
pager := networks.List(c.Network, opts) pager := networks.List(c.Network, opts)
networkID := "" networkID := ""
@ -345,7 +354,7 @@ func (c *GenericClient) AssignFloatingIP(d *Driver, floatingIP *FloatingIP) erro
func (c *GenericClient) assignNovaFloatingIP(d *Driver, floatingIP *FloatingIP) error { func (c *GenericClient) assignNovaFloatingIP(d *Driver, floatingIP *FloatingIP) error {
if floatingIP.Ip == "" { if floatingIP.Ip == "" {
f, err := compute_ips.Create(c.Compute, compute_ips.CreateOpts{ f, err := compute_ips.Create(c.Compute, compute_ips.CreateOpts{
Pool: d.FloatingIpPool, Pool: d.FloatingIPPool,
}).Extract() }).Extract()
if err != nil { if err != nil {
return err return err
@ -363,7 +372,7 @@ func (c *GenericClient) assignNeutronFloatingIP(d *Driver, floatingIP *FloatingI
} }
if floatingIP.Id == "" { if floatingIP.Id == "" {
f, err := floatingips.Create(c.Network, floatingips.CreateOpts{ f, err := floatingips.Create(c.Network, floatingips.CreateOpts{
FloatingNetworkID: d.FloatingIpPoolId, FloatingNetworkID: d.FloatingIPPoolId,
PortID: portID, PortID: portID,
}).Extract() }).Extract()
if err != nil { if err != nil {
@ -400,7 +409,7 @@ func (c *GenericClient) getNovaNetworkFloatingIPs(d *Driver) ([]FloatingIP, erro
ipListing, err := compute_ips.ExtractFloatingIPs(page) ipListing, err := compute_ips.ExtractFloatingIPs(page)
for _, ip := range ipListing { for _, ip := range ipListing {
if ip.InstanceID == "" && ip.Pool == d.FloatingIpPool { if ip.InstanceID == "" && ip.Pool == d.FloatingIPPool {
ips = append(ips, FloatingIP{ ips = append(ips, FloatingIP{
Id: ip.ID, Id: ip.ID,
Ip: ip.IP, Ip: ip.IP,
@ -415,11 +424,11 @@ func (c *GenericClient) getNovaNetworkFloatingIPs(d *Driver) ([]FloatingIP, erro
func (c *GenericClient) getNeutronNetworkFloatingIPs(d *Driver) ([]FloatingIP, error) { func (c *GenericClient) getNeutronNetworkFloatingIPs(d *Driver) ([]FloatingIP, error) {
log.Debug("Listing floating IPs", map[string]string{ log.Debug("Listing floating IPs", map[string]string{
"FloatingNetworkId": d.FloatingIpPoolId, "FloatingNetworkId": d.FloatingIPPoolId,
"TenantID": d.TenantId, "TenantID": d.TenantId,
}) })
pager := floatingips.List(c.Network, floatingips.ListOpts{ pager := floatingips.List(c.Network, floatingips.ListOpts{
FloatingNetworkID: d.FloatingIpPoolId, FloatingNetworkID: d.FloatingIPPoolId,
TenantID: d.TenantId, TenantID: d.TenantId,
}) })
@ -449,7 +458,7 @@ func (c *GenericClient) getNeutronNetworkFloatingIPs(d *Driver) ([]FloatingIP, e
func (c *GenericClient) GetInstancePortID(d *Driver) (string, error) { func (c *GenericClient) GetInstancePortID(d *Driver) (string, error) {
pager := ports.List(c.Network, ports.ListOpts{ pager := ports.List(c.Network, ports.ListOpts{
DeviceID: d.MachineId, DeviceID: d.MachineId,
NetworkID: d.NetworkId, NetworkID: d.NetworkIds[0],
}) })
var portID string var portID string

View File

@ -35,13 +35,13 @@ type Driver struct {
ImageName string ImageName string
ImageId string ImageId string
KeyPairName string KeyPairName string
NetworkName string NetworkNames []string
NetworkId string NetworkIds []string
PrivateKeyFile string PrivateKeyFile string
SecurityGroups []string SecurityGroups []string
FloatingIpPool string FloatingIPPool string
ComputeNetwork bool ComputeNetwork bool
FloatingIpPoolId string FloatingIPPoolId string
IpVersion int IpVersion int
client Client client Client
} }
@ -149,22 +149,22 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
Usage: "OpenStack keypair to use to SSH to the instance", Usage: "OpenStack keypair to use to SSH to the instance",
Value: "", Value: "",
}, },
mcnflag.StringFlag{
EnvVar: "OS_NETWORK_ID",
Name: "openstack-net-id",
Usage: "OpenStack network id the machine will be connected on",
Value: "",
},
mcnflag.StringFlag{ mcnflag.StringFlag{
EnvVar: "OS_PRIVATE_KEY_FILE", EnvVar: "OS_PRIVATE_KEY_FILE",
Name: "openstack-private-key-file", Name: "openstack-private-key-file",
Usage: "Private keyfile to use for SSH (absolute path)", Usage: "Private keyfile to use for SSH (absolute path)",
Value: "", Value: "",
}, },
mcnflag.StringFlag{
EnvVar: "OS_NETWORK_ID",
Name: "openstack-net-id",
Usage: "OpenStack comma separated networks id the machine will be connected on",
Value: "",
},
mcnflag.StringFlag{ mcnflag.StringFlag{
EnvVar: "OS_NETWORK_NAME", EnvVar: "OS_NETWORK_NAME",
Name: "openstack-net-name", Name: "openstack-net-name",
Usage: "OpenStack network name the machine will be connected on", Usage: "OpenStack comma separated network names the machine will be connected on",
Value: "", Value: "",
}, },
mcnflag.StringFlag{ mcnflag.StringFlag{
@ -181,7 +181,7 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
mcnflag.StringFlag{ mcnflag.StringFlag{
EnvVar: "OS_FLOATINGIP_POOL", EnvVar: "OS_FLOATINGIP_POOL",
Name: "openstack-floatingip-pool", Name: "openstack-floatingip-pool",
Usage: "OpenStack floating IP pool to get an IP from to assign to the instance", Usage: "OpenStack floating IP pool to get an IP from to assign to the instance (first network only)",
Value: "", Value: "",
}, },
mcnflag.IntFlag{ mcnflag.IntFlag{
@ -258,12 +258,16 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.FlavorName = flags.String("openstack-flavor-name") d.FlavorName = flags.String("openstack-flavor-name")
d.ImageId = flags.String("openstack-image-id") d.ImageId = flags.String("openstack-image-id")
d.ImageName = flags.String("openstack-image-name") d.ImageName = flags.String("openstack-image-name")
d.NetworkId = flags.String("openstack-net-id") if flags.String("openstack-net-id") != "" {
d.NetworkName = flags.String("openstack-net-name") d.NetworkIds = strings.Split(flags.String("openstack-net-id"), ",")
}
if flags.String("openstack-net-name") != "" {
d.NetworkNames = strings.Split(flags.String("openstack-net-name"), ",")
}
if flags.String("openstack-sec-groups") != "" { if flags.String("openstack-sec-groups") != "" {
d.SecurityGroups = strings.Split(flags.String("openstack-sec-groups"), ",") d.SecurityGroups = strings.Split(flags.String("openstack-sec-groups"), ",")
} }
d.FloatingIpPool = flags.String("openstack-floatingip-pool") d.FloatingIPPool = flags.String("openstack-floatingip-pool")
d.IpVersion = flags.Int("openstack-ip-version") d.IpVersion = flags.Int("openstack-ip-version")
d.ComputeNetwork = flags.Bool("openstack-nova-network") d.ComputeNetwork = flags.Bool("openstack-nova-network")
d.SSHUser = flags.String("openstack-ssh-user") d.SSHUser = flags.String("openstack-ssh-user")
@ -298,7 +302,7 @@ func (d *Driver) GetIP() (string, error) {
} }
addressType := Fixed addressType := Fixed
if d.FloatingIpPool != "" { if d.FloatingIPPool != "" {
addressType = Floating addressType = Floating
} }
@ -371,7 +375,7 @@ func (d *Driver) Create() error {
if err := d.waitForInstanceActive(); err != nil { if err := d.waitForInstanceActive(); err != nil {
return err return err
} }
if d.FloatingIpPool != "" { if d.FloatingIPPool != "" {
if err := d.assignFloatingIP(); err != nil { if err := d.assignFloatingIP(); err != nil {
return err return err
} }
@ -468,8 +472,8 @@ func (d *Driver) checkConfig() error {
return fmt.Errorf(errorExclusiveOptions, "Image name", "Image id") return fmt.Errorf(errorExclusiveOptions, "Image name", "Image id")
} }
if d.NetworkName != "" && d.NetworkId != "" { if len(d.NetworkNames) > 0 && len(d.NetworkIds) > 0 {
return fmt.Errorf(errorExclusiveOptions, "Network name", "Network id") return fmt.Errorf(errorExclusiveOptions, "Network names", "Network ids")
} }
if d.EndpointType != "" && (d.EndpointType != "publicURL" && d.EndpointType != "adminURL" && d.EndpointType != "internalURL") { if d.EndpointType != "" && (d.EndpointType != "publicURL" && d.EndpointType != "adminURL" && d.EndpointType != "internalURL") {
return fmt.Errorf(errorWrongEndpointType) return fmt.Errorf(errorWrongEndpointType)
@ -481,27 +485,27 @@ func (d *Driver) checkConfig() error {
} }
func (d *Driver) resolveIds() error { func (d *Driver) resolveIds() error {
if d.NetworkName != "" && !d.ComputeNetwork { if len(d.NetworkNames) > 0 && !d.ComputeNetwork {
if err := d.initNetwork(); err != nil { if err := d.initNetwork(); err != nil {
return err return err
} }
networkIds, err := d.client.GetNetworkIDs(d)
networkID, err := d.client.GetNetworkID(d)
if err != nil { if err != nil {
return err return err
} }
if networkID == "" { if len(networkIds) == 0 {
return fmt.Errorf(errorUnknownNetworkName, d.NetworkName) return fmt.Errorf(errorUnknownNetworkName, strings.Join(d.NetworkNames, ",")) // TODO specific name
} }
d.NetworkId = networkID d.NetworkIds = networkIds
for i, networkName := range d.NetworkNames {
log.Debug("Found network id using its name", map[string]string{ log.Debug("Found network id using its name", map[string]string{
"Name": d.NetworkName, "Name": networkName,
"ID": d.NetworkId, "ID": d.NetworkIds[i],
}) })
} }
}
if d.FlavorName != "" { if d.FlavorName != "" {
if err := d.initCompute(); err != nil { if err := d.initCompute(); err != nil {
@ -545,7 +549,7 @@ func (d *Driver) resolveIds() error {
}) })
} }
if d.FloatingIpPool != "" && !d.ComputeNetwork { if d.FloatingIPPool != "" && !d.ComputeNetwork {
if err := d.initNetwork(); err != nil { if err := d.initNetwork(); err != nil {
return err return err
} }
@ -556,13 +560,13 @@ func (d *Driver) resolveIds() error {
} }
if f == "" { if f == "" {
return fmt.Errorf(errorUnknownNetworkName, d.FloatingIpPool) return fmt.Errorf(errorUnknownNetworkName, d.FloatingIPPool)
} }
d.FloatingIpPoolId = f d.FloatingIPPoolId = f
log.Debug("Found floating IP pool id using its name", map[string]string{ log.Debug("Found floating IP pool id using its name", map[string]string{
"Name": d.FloatingIpPool, "Name": d.FloatingIPPool,
"ID": d.FloatingIpPoolId, "ID": d.FloatingIPPoolId,
}) })
} }
@ -703,7 +707,7 @@ func (d *Driver) assignFloatingIP() error {
log.Debugf("Looking for an available floating IP", map[string]string{ log.Debugf("Looking for an available floating IP", map[string]string{
"MachineId": d.MachineId, "MachineId": d.MachineId,
"Pool": d.FloatingIpPool, "Pool": d.FloatingIPPool,
}) })
for _, ip := range ips { for _, ip := range ips {

View File

@ -53,6 +53,44 @@ func (c *Client) Authenticate(d *openstack.Driver) error {
return nil return nil
} }
func (c *Client) InitNetworkClient(d *openstack.Driver) error {
if c.Network != nil {
return nil
}
network, err := rackspace.NewNetworkV2(c.Provider, gophercloud.EndpointOpts{
Region: d.Region,
})
if err != nil {
return err
}
c.Network = network
return nil
}
func (c *Client) GetNetworkIDs(d *openstack.Driver) ([]string, error) {
networkIds := make([]string, len(d.NetworkNames))
for i, networkName := range d.NetworkNames {
id, err := c.GetNetworkID(d, networkName)
if err != nil {
return nil, err
}
networkIds[i] = id
}
return networkIds, nil
}
func (c *Client) GetNetworkID(d *openstack.Driver, networkName string) (string, error) {
switch networkName {
case "public", "PublicNet":
return "00000000-0000-0000-0000-000000000000", nil
case "private", "ServiceNet":
return "11111111-1111-1111-1111-111111111111", nil
default:
return c.GenericClient.GetNetworkID(d, networkName)
}
}
// StartInstance is unfortunately not supported on Rackspace at this time. // StartInstance is unfortunately not supported on Rackspace at this time.
func (c *Client) StartInstance(d *openstack.Driver) error { func (c *Client) StartInstance(d *openstack.Driver) error {
return unsupportedOpErr("start") return unsupportedOpErr("start")

View File

@ -2,6 +2,7 @@ package rackspace
import ( import (
"fmt" "fmt"
"strings"
"github.com/docker/machine/drivers/openstack" "github.com/docker/machine/drivers/openstack"
"github.com/docker/machine/libmachine/drivers" "github.com/docker/machine/libmachine/drivers"
@ -62,6 +63,16 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
Value: defaultFlavorID, Value: defaultFlavorID,
EnvVar: "OS_FLAVOR_ID", EnvVar: "OS_FLAVOR_ID",
}, },
mcnflag.StringFlag{
Name: "rackspace-net-id",
Usage: "Rackspace comma separated network ids the machine will be connected on",
Value: "",
},
mcnflag.StringFlag{
Name: "rackspace-net-name",
Usage: "Rackspace comma separated network names the machine will be connected on (eg, PublicNet,ServiceNet,MyNet)",
Value: "",
},
mcnflag.StringFlag{ mcnflag.StringFlag{
Name: "rackspace-ssh-user", Name: "rackspace-ssh-user",
Usage: "SSH user for the newly booted machine. Set to root by default", Usage: "SSH user for the newly booted machine. Set to root by default",
@ -117,6 +128,12 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.EndpointType = flags.String("rackspace-endpoint-type") d.EndpointType = flags.String("rackspace-endpoint-type")
d.ImageId = flags.String("rackspace-image-id") d.ImageId = flags.String("rackspace-image-id")
d.FlavorId = flags.String("rackspace-flavor-id") d.FlavorId = flags.String("rackspace-flavor-id")
if flags.String("rackspace-net-id") != "" {
d.NetworkIds = strings.Split(flags.String("rackspace-net-id"), ",")
}
if flags.String("rackspace-net-name") != "" {
d.NetworkNames = strings.Split(flags.String("rackspace-net-name"), ",")
}
d.SSHUser = flags.String("rackspace-ssh-user") d.SSHUser = flags.String("rackspace-ssh-user")
d.SSHPort = flags.Int("rackspace-ssh-port") d.SSHPort = flags.Int("rackspace-ssh-port")
d.SetSwarmConfigFromFlags(flags) d.SetSwarmConfigFromFlags(flags)