github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/apiserver/sshclient/facade_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package sshclient_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names" 9 jujutesting "github.com/juju/testing" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/apiserver/sshclient" 16 apiservertesting "github.com/juju/juju/apiserver/testing" 17 "github.com/juju/juju/environs/config" 18 "github.com/juju/juju/network" 19 "github.com/juju/juju/state" 20 "github.com/juju/juju/testing" 21 ) 22 23 type facadeSuite struct { 24 testing.BaseSuite 25 backend *mockBackend 26 authorizer *apiservertesting.FakeAuthorizer 27 facade *sshclient.Facade 28 m0, uFoo, uOther string 29 } 30 31 var _ = gc.Suite(&facadeSuite{}) 32 33 func (s *facadeSuite) SetUpSuite(c *gc.C) { 34 s.BaseSuite.SetUpSuite(c) 35 s.m0 = names.NewMachineTag("0").String() 36 s.uFoo = names.NewUnitTag("foo/0").String() 37 s.uOther = names.NewUnitTag("other/1").String() 38 } 39 40 func (s *facadeSuite) SetUpTest(c *gc.C) { 41 s.BaseSuite.SetUpTest(c) 42 43 s.backend = new(mockBackend) 44 s.authorizer = new(apiservertesting.FakeAuthorizer) 45 s.authorizer.Tag = names.NewUserTag("igor") 46 facade, err := sshclient.New(s.backend, nil, s.authorizer) 47 c.Assert(err, jc.ErrorIsNil) 48 s.facade = facade 49 } 50 51 func (s *facadeSuite) TestMachineAuthNotAllowed(c *gc.C) { 52 s.authorizer.Tag = names.NewMachineTag("0") 53 _, err := sshclient.New(s.backend, nil, s.authorizer) 54 c.Assert(err, gc.Equals, common.ErrPerm) 55 } 56 57 func (s *facadeSuite) TestUnitAuthNotAllowed(c *gc.C) { 58 s.authorizer.Tag = names.NewUnitTag("foo/0") 59 _, err := sshclient.New(s.backend, nil, s.authorizer) 60 c.Assert(err, gc.Equals, common.ErrPerm) 61 } 62 63 func (s *facadeSuite) TestPublicAddress(c *gc.C) { 64 args := params.Entities{ 65 Entities: []params.Entity{{s.m0}, {s.uFoo}, {s.uOther}}, 66 } 67 results, err := s.facade.PublicAddress(args) 68 69 c.Assert(err, jc.ErrorIsNil) 70 c.Check(results, gc.DeepEquals, params.SSHAddressResults{ 71 Results: []params.SSHAddressResult{ 72 {Address: "1.1.1.1"}, 73 {Address: "3.3.3.3"}, 74 {Error: apiservertesting.ErrUnauthorized}, 75 }, 76 }) 77 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 78 {"GetMachineForEntity", []interface{}{s.m0}}, 79 {"GetMachineForEntity", []interface{}{s.uFoo}}, 80 {"GetMachineForEntity", []interface{}{s.uOther}}, 81 }) 82 } 83 84 func (s *facadeSuite) TestPrivateAddress(c *gc.C) { 85 args := params.Entities{ 86 Entities: []params.Entity{{s.uOther}, {s.m0}, {s.uFoo}}, 87 } 88 results, err := s.facade.PrivateAddress(args) 89 90 c.Assert(err, jc.ErrorIsNil) 91 c.Check(results, gc.DeepEquals, params.SSHAddressResults{ 92 Results: []params.SSHAddressResult{ 93 {Error: apiservertesting.ErrUnauthorized}, 94 {Address: "2.2.2.2"}, 95 {Address: "4.4.4.4"}, 96 }, 97 }) 98 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 99 {"GetMachineForEntity", []interface{}{s.uOther}}, 100 {"GetMachineForEntity", []interface{}{s.m0}}, 101 {"GetMachineForEntity", []interface{}{s.uFoo}}, 102 }) 103 } 104 105 func (s *facadeSuite) TestPublicKeys(c *gc.C) { 106 args := params.Entities{ 107 Entities: []params.Entity{{s.m0}, {s.uOther}, {s.uFoo}}, 108 } 109 results, err := s.facade.PublicKeys(args) 110 111 c.Assert(err, jc.ErrorIsNil) 112 c.Check(results, gc.DeepEquals, params.SSHPublicKeysResults{ 113 Results: []params.SSHPublicKeysResult{ 114 {PublicKeys: []string{"rsa0", "dsa0"}}, 115 {Error: apiservertesting.ErrUnauthorized}, 116 {PublicKeys: []string{"rsa1", "dsa1"}}, 117 }, 118 }) 119 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 120 {"GetMachineForEntity", []interface{}{s.m0}}, 121 {"GetSSHHostKeys", []interface{}{names.NewMachineTag("0")}}, 122 {"GetMachineForEntity", []interface{}{s.uOther}}, 123 {"GetMachineForEntity", []interface{}{s.uFoo}}, 124 {"GetSSHHostKeys", []interface{}{names.NewMachineTag("1")}}, 125 }) 126 } 127 128 func (s *facadeSuite) TestProxyTrue(c *gc.C) { 129 s.backend.proxySSH = true 130 result, err := s.facade.Proxy() 131 c.Assert(err, jc.ErrorIsNil) 132 c.Check(result.UseProxy, jc.IsTrue) 133 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 134 {"ModelConfig", []interface{}{}}, 135 }) 136 } 137 138 func (s *facadeSuite) TestProxyFalse(c *gc.C) { 139 s.backend.proxySSH = false 140 result, err := s.facade.Proxy() 141 c.Assert(err, jc.ErrorIsNil) 142 c.Check(result.UseProxy, jc.IsFalse) 143 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 144 {"ModelConfig", []interface{}{}}, 145 }) 146 } 147 148 type mockBackend struct { 149 stub jujutesting.Stub 150 proxySSH bool 151 } 152 153 func (backend *mockBackend) ModelConfig() (*config.Config, error) { 154 backend.stub.AddCall("ModelConfig") 155 attrs := testing.FakeConfig() 156 attrs["proxy-ssh"] = backend.proxySSH 157 conf, err := config.New(config.NoDefaults, attrs) 158 if err != nil { 159 return nil, errors.Trace(err) 160 } 161 return conf, nil 162 } 163 164 func (backend *mockBackend) GetMachineForEntity(tagString string) (sshclient.SSHMachine, error) { 165 backend.stub.AddCall("GetMachineForEntity", tagString) 166 switch tagString { 167 case names.NewMachineTag("0").String(): 168 return &mockMachine{ 169 tag: names.NewMachineTag("0"), 170 publicAddress: "1.1.1.1", 171 privateAddress: "2.2.2.2", 172 }, nil 173 case names.NewUnitTag("foo/0").String(): 174 return &mockMachine{ 175 tag: names.NewMachineTag("1"), 176 publicAddress: "3.3.3.3", 177 privateAddress: "4.4.4.4", 178 }, nil 179 } 180 return nil, errors.New("unknown entity") 181 } 182 183 func (backend *mockBackend) GetSSHHostKeys(tag names.MachineTag) (state.SSHHostKeys, error) { 184 backend.stub.AddCall("GetSSHHostKeys", tag) 185 switch tag { 186 case names.NewMachineTag("0"): 187 return state.SSHHostKeys{"rsa0", "dsa0"}, nil 188 case names.NewMachineTag("1"): 189 return state.SSHHostKeys{"rsa1", "dsa1"}, nil 190 } 191 return nil, errors.New("machine not found") 192 } 193 194 type mockMachine struct { 195 tag names.MachineTag 196 publicAddress string 197 privateAddress string 198 } 199 200 func (m *mockMachine) MachineTag() names.MachineTag { 201 return m.tag 202 } 203 204 func (m *mockMachine) PublicAddress() (network.Address, error) { 205 return network.Address{ 206 Value: m.publicAddress, 207 }, nil 208 } 209 210 func (m *mockMachine) PrivateAddress() (network.Address, error) { 211 return network.Address{ 212 Value: m.privateAddress, 213 }, nil 214 }