github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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 // Addresses implements instance.Instance. 42 func (inst *environInstance) Addresses() ([]network.Address, error) { 43 if inst.base.Guest == nil || inst.base.Guest.IpAddress == "" { 44 return nil, nil 45 } 46 res := make([]network.Address, 0) 47 for _, net := range inst.base.Guest.Net { 48 for _, ip := range net.IpAddress { 49 scope := network.ScopeCloudLocal 50 if net.Network == inst.env.ecfg.externalNetwork() { 51 scope = network.ScopePublic 52 } 53 res = append(res, network.NewScopedAddress(ip, scope)) 54 } 55 } 56 return res, nil 57 } 58 59 func findInst(id instance.Id, instances []instance.Instance) instance.Instance { 60 for _, inst := range instances { 61 if id == inst.Id() { 62 return inst 63 } 64 } 65 return nil 66 } 67 68 // firewall stuff 69 70 // OpenPorts opens the given ports on the instance, which 71 // should have been started with the given machine id. 72 func (inst *environInstance) OpenPorts(machineID string, ports []network.PortRange) error { 73 return inst.changePorts(true, ports) 74 } 75 76 // ClosePorts closes the given ports on the instance, which 77 // should have been started with the given machine id. 78 func (inst *environInstance) ClosePorts(machineID string, ports []network.PortRange) error { 79 return inst.changePorts(false, ports) 80 } 81 82 // Ports returns the set of ports open on the instance, which 83 // should have been started with the given machine id. 84 func (inst *environInstance) Ports(machineID string) ([]network.PortRange, error) { 85 _, sshClient, err := inst.getSshClient() 86 if err != nil { 87 return nil, errors.Trace(err) 88 } 89 return sshClient.findOpenPorts() 90 } 91 92 func (inst *environInstance) changePorts(insert bool, ports []network.PortRange) error { 93 if inst.env.ecfg.externalNetwork() == "" { 94 return errors.New("Can't close/open ports without external network") 95 } 96 addresses, sshClient, err := inst.getSshClient() 97 if err != nil { 98 return errors.Trace(err) 99 } 100 101 for _, addr := range addresses { 102 if addr.Scope == network.ScopePublic { 103 err = sshClient.changePorts(addr.Value, insert, ports) 104 if err != nil { 105 return errors.Trace(err) 106 } 107 } 108 } 109 return nil 110 } 111 112 func (inst *environInstance) getSshClient() ([]network.Address, *sshClient, error) { 113 addresses, err := inst.Addresses() 114 if err != nil { 115 return nil, nil, errors.Trace(err) 116 } 117 118 var localAddr string 119 for _, addr := range addresses { 120 if addr.Scope == network.ScopeCloudLocal { 121 localAddr = addr.Value 122 break 123 } 124 } 125 126 client := newSshClient(localAddr) 127 return addresses, client, err 128 }