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 }