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