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 }