github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/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 PORT %d"
    18  )
    19  
    20  // Helper method to create a firewall rule string for the given machine Id and port
    21  func createFirewallRuleVm(env *joyentEnviron, machineId string, port network.Port) string {
    22  	return fmt.Sprintf(firewallRuleVm, env.Name(), machineId, strings.ToLower(port.Protocol), port.Number)
    23  }
    24  
    25  func (inst *joyentInstance) OpenPorts(machineId string, ports []network.Port) error {
    26  	if inst.env.Config().FirewallMode() != config.FwInstance {
    27  		return fmt.Errorf("invalid firewall mode %q for opening ports on instance", inst.env.Config().FirewallMode())
    28  	}
    29  
    30  	fwRules, err := inst.env.compute.cloudapi.ListFirewallRules()
    31  	if err != nil {
    32  		return fmt.Errorf("cannot get firewall rules: %v", err)
    33  	}
    34  
    35  	machineId = string(inst.Id())
    36  	for _, p := range ports {
    37  		rule := createFirewallRuleVm(inst.env, machineId, p)
    38  		if e, id := ruleExists(fwRules, rule); e {
    39  			_, err := inst.env.compute.cloudapi.EnableFirewallRule(id)
    40  			if err != nil {
    41  				return fmt.Errorf("couldn't enable rule %s: %v", rule, err)
    42  			}
    43  		} else {
    44  			_, err := inst.env.compute.cloudapi.CreateFirewallRule(cloudapi.CreateFwRuleOpts{
    45  				Enabled: true,
    46  				Rule:    rule,
    47  			})
    48  			if err != nil {
    49  				return fmt.Errorf("couldn't create rule %s: %v", rule, err)
    50  			}
    51  		}
    52  	}
    53  
    54  	logger.Infof("ports %v opened for instance %q", ports, machineId)
    55  
    56  	return nil
    57  }
    58  
    59  func (inst *joyentInstance) ClosePorts(machineId string, ports []network.Port) error {
    60  	if inst.env.Config().FirewallMode() != config.FwInstance {
    61  		return fmt.Errorf("invalid firewall mode %q for closing ports on instance", inst.env.Config().FirewallMode())
    62  	}
    63  
    64  	fwRules, err := inst.env.compute.cloudapi.ListFirewallRules()
    65  	if err != nil {
    66  		return fmt.Errorf("cannot get firewall rules: %v", err)
    67  	}
    68  
    69  	machineId = string(inst.Id())
    70  	for _, p := range ports {
    71  		rule := createFirewallRuleVm(inst.env, machineId, p)
    72  		if e, id := ruleExists(fwRules, rule); e {
    73  			_, err := inst.env.compute.cloudapi.DisableFirewallRule(id)
    74  			if err != nil {
    75  				return fmt.Errorf("couldn't disable rule %s: %v", rule, err)
    76  			}
    77  		} else {
    78  			_, err := inst.env.compute.cloudapi.CreateFirewallRule(cloudapi.CreateFwRuleOpts{
    79  				Enabled: false,
    80  				Rule:    rule,
    81  			})
    82  			if err != nil {
    83  				return fmt.Errorf("couldn't create rule %s: %v", rule, err)
    84  			}
    85  		}
    86  	}
    87  
    88  	logger.Infof("ports %v closed for instance %q", ports, machineId)
    89  
    90  	return nil
    91  }
    92  
    93  func (inst *joyentInstance) Ports(machineId string) ([]network.Port, error) {
    94  	if inst.env.Config().FirewallMode() != config.FwInstance {
    95  		return nil, fmt.Errorf("invalid firewall mode %q for retrieving ports from instance", inst.env.Config().FirewallMode())
    96  	}
    97  
    98  	machineId = string(inst.Id())
    99  	fwRules, err := inst.env.compute.cloudapi.ListMachineFirewallRules(machineId)
   100  	if err != nil {
   101  		return nil, fmt.Errorf("cannot get firewall rules: %v", err)
   102  	}
   103  
   104  	return getPorts(inst.env, fwRules), nil
   105  }