exoscale: ability to specify multiple security groups on instance creation

Without this feature, when a user needs a specific security group (i.e
most of the time if they want to expose a service to Internet), they
need to copy the rules needed for Docker itself into each custom
group. With this feature, they can spawn new instances with
`--exoscale-security-group docker-machine,my-custom-group`.

Signed-off-by: Vincent Bernat <Vincent.Bernat@exoscale.ch>
This commit is contained in:
Vincent Bernat 2015-06-05 10:23:37 +02:00
parent 471968b039
commit 5ba232227e
2 changed files with 58 additions and 43 deletions

View File

@ -1174,7 +1174,7 @@ Options:
- `--exoscale-instance-profile`: Instance profile.
- `--exoscale-disk-size`: Disk size for the host in GB.
- `--exoscale-image`: exoscale disk size. (10, 50, 100, 200, 400)
- `--exoscale-security-group`: Security group. It will be created if it doesn't exist.
- `--exoscale-security-group`: Comma-separated list of security groups. Non-existent groups will be created.
- `--exoscale-availability-zone`: exoscale availability zone.
If a custom security group is provided, you need to ensure that you allow TCP ports 22 and 2376 in an ingress rule. Moreover, if you want to use Swarm, also add TCP port 3376.

View File

@ -24,7 +24,7 @@ type Driver struct {
InstanceProfile string
DiskSize int
Image string
SecurityGroup string
SecurityGroups []string
AvailabilityZone string
MachineName string
KeyPair string
@ -142,7 +142,9 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.InstanceProfile = flags.String("exoscale-instance-profile")
d.DiskSize = flags.Int("exoscale-disk-size")
d.Image = flags.String("exoscale-image")
d.SecurityGroup = flags.String("exoscale-security-group")
if flags.String("exoscale-security-group") != "" {
d.SecurityGroups = strings.Split(flags.String("exoscale-security-group"), ",")
}
d.AvailabilityZone = flags.String("exoscale-availability-zone")
d.SwarmMaster = flags.Bool("swarm-master")
d.SwarmHost = flags.String("swarm-host")
@ -208,6 +210,45 @@ func (d *Driver) PreCreateCheck() error {
return nil
}
func (d *Driver) createDefaultSecurityGroup(client *egoscale.Client, group string) (string, error) {
rules := []egoscale.SecurityGroupRule{
{
SecurityGroupId: "",
Cidr: "0.0.0.0/0",
Protocol: "TCP",
Port: 22,
},
{
SecurityGroupId: "",
Cidr: "0.0.0.0/0",
Protocol: "TCP",
Port: 2376,
},
{
SecurityGroupId: "",
Cidr: "0.0.0.0/0",
Protocol: "TCP",
Port: 3376,
},
{
SecurityGroupId: "",
Cidr: "0.0.0.0/0",
Protocol: "ICMP",
IcmpType: 8,
IcmpCode: 0,
},
}
sgresp, err := client.CreateSecurityGroupWithRules(
group,
rules,
make([]egoscale.SecurityGroupRule, 0, 0))
if err != nil {
return "", err
}
sg := sgresp.Id
return sg, nil
}
func (d *Driver) Create() error {
log.Infof("Querying exoscale for the requested parameters...")
client := egoscale.NewClient(d.URL, d.ApiKey, d.ApiSecretKey)
@ -244,47 +285,21 @@ func (d *Driver) Create() error {
}
log.Debugf("Profile %v = %s", d.InstanceProfile, profile)
// Security group
sg, ok := topology.SecurityGroups[d.SecurityGroup]
if !ok {
log.Infof("Security group %v does not exist, create it",
d.SecurityGroup)
rules := []egoscale.SecurityGroupRule{
{
SecurityGroupId: "",
Cidr: "0.0.0.0/0",
Protocol: "TCP",
Port: 22,
},
{
SecurityGroupId: "",
Cidr: "0.0.0.0/0",
Protocol: "TCP",
Port: 2376,
},
{
SecurityGroupId: "",
Cidr: "0.0.0.0/0",
Protocol: "TCP",
Port: 3376,
},
{
SecurityGroupId: "",
Cidr: "0.0.0.0/0",
Protocol: "ICMP",
IcmpType: 8,
IcmpCode: 0,
},
// Security groups
sgs := make([]string, len(d.SecurityGroups))
for idx, group := range d.SecurityGroups {
sg, ok := topology.SecurityGroups[group]
if !ok {
log.Infof("Security group %v does not exist, create it",
group)
sg, err = d.createDefaultSecurityGroup(client, group)
if err != nil {
return err
}
}
sgresp, err := client.CreateSecurityGroupWithRules(d.SecurityGroup,
rules,
make([]egoscale.SecurityGroupRule, 0, 0))
if err != nil {
return err
}
sg = sgresp.Id
log.Debugf("Security group %v = %s", group, sg)
sgs[idx] = sg
}
log.Debugf("Security group %v = %s", d.SecurityGroup, sg)
log.Infof("Generate an SSH keypair...")
keypairName := fmt.Sprintf("docker-machine-%s", d.MachineName)
@ -310,7 +325,7 @@ func (d *Driver) Create() error {
machineProfile := egoscale.MachineProfile{
Template: tpl,
ServiceOffering: profile,
SecurityGroups: []string{sg},
SecurityGroups: sgs,
Userdata: userdata,
Zone: zone,
Keypair: d.KeyPair,