diff --git a/docs/index.md b/docs/index.md index c7918ed995..960c94b6d9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -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. diff --git a/drivers/exoscale/exoscale.go b/drivers/exoscale/exoscale.go index 5a62d3cdda..5002af1bbb 100644 --- a/drivers/exoscale/exoscale.go +++ b/drivers/exoscale/exoscale.go @@ -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,