github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/provider/joyent/instance_firewall.go (about)

     1  // Copyright 2013 Joyent Inc.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package joyent
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/joyent/gosdc/cloudapi"
    11  
    12  	"github.com/juju/juju/environs/config"
    13  	"github.com/juju/juju/network"
    14  )
    15  
    16  const (
    17  	firewallRuleVm = "FROM tag %s TO vm %s ALLOW %s %s"
    18  )
    19  
    20  // Helper method to create a firewall rule string for the given machine Id and port
    21  func createFirewallRuleVm(envName string, machineId string, portRange network.PortRange) string {
    22  	ports := []string{}
    23  	for p := portRange.FromPort; p <= portRange.ToPort; p++ {
    24  		ports = append(ports, fmt.Sprintf("PORT %d", p))
    25  	}
    26  	var portList string
    27  	if len(ports) > 1 {
    28  		portList = fmt.Sprintf("( %s )", strings.Join(ports, " AND "))
    29  	} else if len(ports) == 1 {
    30  		portList = ports[0]
    31  	}
    32  	return fmt.Sprintf(firewallRuleVm, envName, machineId, strings.ToLower(portRange.Protocol), portList)
    33  }
    34  
    35  func (inst *joyentInstance) OpenPorts(machineId string, ports []network.PortRange) error {
    36  	if inst.env.Config().FirewallMode() != config.FwInstance {
    37  		return fmt.Errorf("invalid firewall mode %q for opening ports on instance", inst.env.Config().FirewallMode())
    38  	}
    39  
    40  	fwRules, err := inst.env.compute.cloudapi.ListFirewallRules()
    41  	if err != nil {
    42  		return fmt.Errorf("cannot get firewall rules: %v", err)
    43  	}
    44  
    45  	machineId = string(inst.Id())
    46  	for _, p := range ports {
    47  		rule := createFirewallRuleVm(inst.env.Config().Name(), machineId, p)
    48  		if e, id := ruleExists(fwRules, rule); e {
    49  			_, err := inst.env.compute.cloudapi.EnableFirewallRule(id)
    50  			if err != nil {
    51  				return fmt.Errorf("couldn't enable rule %s: %v", rule, err)
    52  			}
    53  		} else {
    54  			_, err := inst.env.compute.cloudapi.CreateFirewallRule(cloudapi.CreateFwRuleOpts{
    55  				Enabled: true,
    56  				Rule:    rule,
    57  			})
    58  			if err != nil {
    59  				return fmt.Errorf("couldn't create rule %s: %v", rule, err)
    60  			}
    61  		}
    62  	}
    63  
    64  	logger.Infof("ports %v opened for instance %q", ports, machineId)
    65  
    66  	return nil
    67  }
    68  
    69  func (inst *joyentInstance) ClosePorts(machineId string, ports []network.PortRange) error {
    70  	if inst.env.Config().FirewallMode() != config.FwInstance {
    71  		return fmt.Errorf("invalid firewall mode %q for closing ports on instance", inst.env.Config().FirewallMode())
    72  	}
    73  
    74  	fwRules, err := inst.env.compute.cloudapi.ListFirewallRules()
    75  	if err != nil {
    76  		return fmt.Errorf("cannot get firewall rules: %v", err)
    77  	}
    78  
    79  	machineId = string(inst.Id())
    80  	for _, p := range ports {
    81  		rule := createFirewallRuleVm(inst.env.Config().Name(), machineId, p)
    82  		if e, id := ruleExists(fwRules, rule); e {
    83  			_, err := inst.env.compute.cloudapi.DisableFirewallRule(id)
    84  			if err != nil {
    85  				return fmt.Errorf("couldn't disable rule %s: %v", rule, err)
    86  			}
    87  		} else {
    88  			_, err := inst.env.compute.cloudapi.CreateFirewallRule(cloudapi.CreateFwRuleOpts{
    89  				Enabled: false,
    90  				Rule:    rule,
    91  			})
    92  			if err != nil {
    93  				return fmt.Errorf("couldn't create rule %s: %v", rule, err)
    94  			}
    95  		}
    96  	}
    97  
    98  	logger.Infof("ports %v closed for instance %q", ports, machineId)
    99  
   100  	return nil
   101  }
   102  
   103  func (inst *joyentInstance) Ports(machineId string) ([]network.PortRange, error) {
   104  	if inst.env.Config().FirewallMode() != config.FwInstance {
   105  		return nil, fmt.Errorf("invalid firewall mode %q for retrieving ports from instance", inst.env.Config().FirewallMode())
   106  	}
   107  
   108  	machineId = string(inst.Id())
   109  	fwRules, err := inst.env.compute.cloudapi.ListMachineFirewallRules(machineId)
   110  	if err != nil {
   111  		return nil, fmt.Errorf("cannot get firewall rules: %v", err)
   112  	}
   113  
   114  	return getPorts(inst.env.Config().Name(), fwRules), nil
   115  }