github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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 "github.com/juju/juju/provider/common" 15 "github.com/juju/juju/status" 16 ) 17 18 type environInstance struct { 19 base *mo.VirtualMachine 20 env *environ 21 } 22 23 var _ instance.Instance = (*environInstance)(nil) 24 25 func newInstance(base *mo.VirtualMachine, env *environ) *environInstance { 26 return &environInstance{ 27 base: base, 28 env: env, 29 } 30 } 31 32 // Id implements instance.Instance. 33 func (inst *environInstance) Id() instance.Id { 34 return instance.Id(inst.base.Name) 35 } 36 37 // Status implements instance.Instance. 38 func (inst *environInstance) Status() instance.InstanceStatus { 39 // TODO(perrito666) I wont change the commented line because it was 40 // there and I have not enough knowledge about this provider 41 // but that method does not exist. 42 // return inst.base.Status() 43 return instance.InstanceStatus{ 44 Status: status.Pending, 45 } 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 _, client, err := inst.getInstanceConfigurator() 93 if err != nil { 94 return nil, errors.Trace(err) 95 } 96 return client.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, client, err := inst.getInstanceConfigurator() 104 if err != nil { 105 return errors.Trace(err) 106 } 107 108 for _, addr := range addresses { 109 if addr.Scope == network.ScopePublic { 110 err = client.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) getInstanceConfigurator() ([]network.Address, common.InstanceConfigurator, 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 := common.NewSshInstanceConfigurator(localAddr) 134 return addresses, client, err 135 }