github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/provider/vsphere/instance.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // +build !gccgo 5 6 package vsphere 7 8 import ( 9 "github.com/juju/errors" 10 "github.com/juju/govmomi/vim25/mo" 11 12 "github.com/juju/juju/instance" 13 "github.com/juju/juju/network" 14 ) 15 16 type environInstance struct { 17 base *mo.VirtualMachine 18 env *environ 19 } 20 21 var _ instance.Instance = (*environInstance)(nil) 22 23 func newInstance(base *mo.VirtualMachine, env *environ) *environInstance { 24 return &environInstance{ 25 base: base, 26 env: env, 27 } 28 } 29 30 // Id implements instance.Instance. 31 func (inst *environInstance) Id() instance.Id { 32 return instance.Id(inst.base.Name) 33 } 34 35 // Status implements instance.Instance. 36 func (inst *environInstance) Status() string { 37 //return inst.base.Status() 38 return "" 39 } 40 41 // Refresh implements instance.Instance. 42 func (inst *environInstance) Refresh() error { 43 env := inst.env.getSnapshot() 44 err := env.client.Refresh(inst.base) 45 return errors.Trace(err) 46 } 47 48 // Addresses implements instance.Instance. 49 func (inst *environInstance) Addresses() ([]network.Address, error) { 50 if inst.base.Guest == nil || inst.base.Guest.IpAddress == "" { 51 return nil, nil 52 } 53 res := make([]network.Address, 0) 54 for _, net := range inst.base.Guest.Net { 55 for _, ip := range net.IpAddress { 56 scope := network.ScopeCloudLocal 57 if net.Network == inst.env.ecfg.externalNetwork() { 58 scope = network.ScopePublic 59 } 60 res = append(res, network.NewScopedAddress(ip, scope)) 61 } 62 } 63 return res, nil 64 } 65 66 func findInst(id instance.Id, instances []instance.Instance) instance.Instance { 67 for _, inst := range instances { 68 if id == inst.Id() { 69 return inst 70 } 71 } 72 return nil 73 } 74 75 // firewall stuff 76 77 // OpenPorts opens the given ports on the instance, which 78 // should have been started with the given machine id. 79 func (inst *environInstance) OpenPorts(machineID string, ports []network.PortRange) error { 80 return inst.changePorts(true, ports) 81 } 82 83 // ClosePorts closes the given ports on the instance, which 84 // should have been started with the given machine id. 85 func (inst *environInstance) ClosePorts(machineID string, ports []network.PortRange) error { 86 return inst.changePorts(false, ports) 87 } 88 89 // Ports returns the set of ports open on the instance, which 90 // should have been started with the given machine id. 91 func (inst *environInstance) Ports(machineID string) ([]network.PortRange, error) { 92 _, sshClient, err := inst.getSshClient() 93 if err != nil { 94 return nil, errors.Trace(err) 95 } 96 return sshClient.findOpenPorts() 97 } 98 99 func (inst *environInstance) changePorts(insert bool, ports []network.PortRange) error { 100 if inst.env.ecfg.externalNetwork() == "" { 101 return errors.New("Can't close/open ports without external network") 102 } 103 addresses, sshClient, err := inst.getSshClient() 104 if err != nil { 105 return errors.Trace(err) 106 } 107 108 for _, addr := range addresses { 109 if addr.Scope == network.ScopePublic { 110 err = sshClient.changePorts(addr.Value, insert, ports) 111 if err != nil { 112 return errors.Trace(err) 113 } 114 } 115 } 116 return nil 117 } 118 119 func (inst *environInstance) getSshClient() ([]network.Address, *sshClient, error) { 120 addresses, err := inst.Addresses() 121 if err != nil { 122 return nil, nil, errors.Trace(err) 123 } 124 125 var localAddr string 126 for _, addr := range addresses { 127 if addr.Scope == network.ScopeCloudLocal { 128 localAddr = addr.Value 129 break 130 } 131 } 132 133 client := newSshClient(localAddr) 134 return addresses, client, err 135 }