github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/provider/ec2/instance.go (about) 1 // Copyright 2011-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package ec2 5 6 import ( 7 "fmt" 8 "sync" 9 10 "gopkg.in/amz.v3/ec2" 11 12 "github.com/juju/juju/environs/config" 13 "github.com/juju/juju/instance" 14 "github.com/juju/juju/network" 15 ) 16 17 type ec2Instance struct { 18 e *environ 19 20 mu sync.Mutex 21 *ec2.Instance 22 } 23 24 func (inst *ec2Instance) String() string { 25 return string(inst.Id()) 26 } 27 28 var _ instance.Instance = (*ec2Instance)(nil) 29 30 func (inst *ec2Instance) getInstance() *ec2.Instance { 31 inst.mu.Lock() 32 defer inst.mu.Unlock() 33 return inst.Instance 34 } 35 36 func (inst *ec2Instance) Id() instance.Id { 37 return instance.Id(inst.getInstance().InstanceId) 38 } 39 40 func (inst *ec2Instance) Status() string { 41 return inst.getInstance().State.Name 42 } 43 44 // Refresh implements instance.Refresh(), requerying the 45 // Instance details over the ec2 api 46 func (inst *ec2Instance) Refresh() error { 47 _, err := inst.refresh() 48 return err 49 } 50 51 // refresh requeries Instance details over the ec2 api. 52 func (inst *ec2Instance) refresh() (*ec2.Instance, error) { 53 id := inst.Id() 54 insts, err := inst.e.Instances([]instance.Id{id}) 55 if err != nil { 56 return nil, err 57 } 58 inst.mu.Lock() 59 defer inst.mu.Unlock() 60 inst.Instance = insts[0].(*ec2Instance).Instance 61 return inst.Instance, nil 62 } 63 64 // Addresses implements network.Addresses() returning generic address 65 // details for the instance, and requerying the ec2 api if required. 66 func (inst *ec2Instance) Addresses() ([]network.Address, error) { 67 // TODO(gz): Stop relying on this requerying logic, maybe remove error 68 instInstance := inst.getInstance() 69 var addresses []network.Address 70 possibleAddresses := []network.Address{ 71 { 72 Value: instInstance.IPAddress, 73 Type: network.IPv4Address, 74 Scope: network.ScopePublic, 75 }, 76 { 77 Value: instInstance.PrivateIPAddress, 78 Type: network.IPv4Address, 79 Scope: network.ScopeCloudLocal, 80 }, 81 } 82 for _, address := range possibleAddresses { 83 if address.Value != "" { 84 addresses = append(addresses, address) 85 } 86 } 87 return addresses, nil 88 } 89 90 func (inst *ec2Instance) OpenPorts(machineId string, ports []network.PortRange) error { 91 if inst.e.Config().FirewallMode() != config.FwInstance { 92 return fmt.Errorf("invalid firewall mode %q for opening ports on instance", 93 inst.e.Config().FirewallMode()) 94 } 95 name := inst.e.machineGroupName(machineId) 96 if err := inst.e.openPortsInGroup(name, ports); err != nil { 97 return err 98 } 99 logger.Infof("opened ports in security group %s: %v", name, ports) 100 return nil 101 } 102 103 func (inst *ec2Instance) ClosePorts(machineId string, ports []network.PortRange) error { 104 if inst.e.Config().FirewallMode() != config.FwInstance { 105 return fmt.Errorf("invalid firewall mode %q for closing ports on instance", 106 inst.e.Config().FirewallMode()) 107 } 108 name := inst.e.machineGroupName(machineId) 109 if err := inst.e.closePortsInGroup(name, ports); err != nil { 110 return err 111 } 112 logger.Infof("closed ports in security group %s: %v", name, ports) 113 return nil 114 } 115 116 func (inst *ec2Instance) Ports(machineId string) ([]network.PortRange, error) { 117 if inst.e.Config().FirewallMode() != config.FwInstance { 118 return nil, fmt.Errorf("invalid firewall mode %q for retrieving ports from instance", 119 inst.e.Config().FirewallMode()) 120 } 121 name := inst.e.machineGroupName(machineId) 122 ranges, err := inst.e.portsInGroup(name) 123 if err != nil { 124 return nil, err 125 } 126 return ranges, nil 127 }