github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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 jujutesting "github.com/juju/testing" 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 "gopkg.in/juju/names.v2" 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 s.authorizer.AdminTag = names.NewUserTag("igor") 47 facade, err := sshclient.New(s.backend, nil, s.authorizer) 48 c.Assert(err, jc.ErrorIsNil) 49 s.facade = facade 50 } 51 52 func (s *facadeSuite) TestMachineAuthNotAllowed(c *gc.C) { 53 s.authorizer.Tag = names.NewMachineTag("0") 54 _, err := sshclient.New(s.backend, nil, s.authorizer) 55 c.Assert(err, gc.Equals, common.ErrPerm) 56 } 57 58 func (s *facadeSuite) TestUnitAuthNotAllowed(c *gc.C) { 59 s.authorizer.Tag = names.NewUnitTag("foo/0") 60 _, err := sshclient.New(s.backend, nil, s.authorizer) 61 c.Assert(err, gc.Equals, common.ErrPerm) 62 } 63 64 func (s *facadeSuite) TestPublicAddress(c *gc.C) { 65 args := params.Entities{ 66 Entities: []params.Entity{{s.m0}, {s.uFoo}, {s.uOther}}, 67 } 68 results, err := s.facade.PublicAddress(args) 69 70 c.Assert(err, jc.ErrorIsNil) 71 c.Check(results, gc.DeepEquals, params.SSHAddressResults{ 72 Results: []params.SSHAddressResult{ 73 {Address: "1.1.1.1"}, 74 {Address: "3.3.3.3"}, 75 {Error: apiservertesting.NotFoundError("entity")}, 76 }, 77 }) 78 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 79 {"GetMachineForEntity", []interface{}{s.m0}}, 80 {"GetMachineForEntity", []interface{}{s.uFoo}}, 81 {"GetMachineForEntity", []interface{}{s.uOther}}, 82 }) 83 } 84 85 func (s *facadeSuite) TestPrivateAddress(c *gc.C) { 86 args := params.Entities{ 87 Entities: []params.Entity{{s.uOther}, {s.m0}, {s.uFoo}}, 88 } 89 results, err := s.facade.PrivateAddress(args) 90 91 c.Assert(err, jc.ErrorIsNil) 92 c.Check(results, gc.DeepEquals, params.SSHAddressResults{ 93 Results: []params.SSHAddressResult{ 94 {Error: apiservertesting.NotFoundError("entity")}, 95 {Address: "2.2.2.2"}, 96 {Address: "4.4.4.4"}, 97 }, 98 }) 99 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 100 {"GetMachineForEntity", []interface{}{s.uOther}}, 101 {"GetMachineForEntity", []interface{}{s.m0}}, 102 {"GetMachineForEntity", []interface{}{s.uFoo}}, 103 }) 104 } 105 106 func (s *facadeSuite) TestPublicKeys(c *gc.C) { 107 args := params.Entities{ 108 Entities: []params.Entity{{s.m0}, {s.uOther}, {s.uFoo}}, 109 } 110 results, err := s.facade.PublicKeys(args) 111 112 c.Assert(err, jc.ErrorIsNil) 113 c.Check(results, gc.DeepEquals, params.SSHPublicKeysResults{ 114 Results: []params.SSHPublicKeysResult{ 115 {PublicKeys: []string{"rsa0", "dsa0"}}, 116 {Error: apiservertesting.NotFoundError("entity")}, 117 {PublicKeys: []string{"rsa1", "dsa1"}}, 118 }, 119 }) 120 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 121 {"GetMachineForEntity", []interface{}{s.m0}}, 122 {"GetSSHHostKeys", []interface{}{names.NewMachineTag("0")}}, 123 {"GetMachineForEntity", []interface{}{s.uOther}}, 124 {"GetMachineForEntity", []interface{}{s.uFoo}}, 125 {"GetSSHHostKeys", []interface{}{names.NewMachineTag("1")}}, 126 }) 127 } 128 129 func (s *facadeSuite) TestProxyTrue(c *gc.C) { 130 s.backend.proxySSH = true 131 result, err := s.facade.Proxy() 132 c.Assert(err, jc.ErrorIsNil) 133 c.Check(result.UseProxy, jc.IsTrue) 134 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 135 {"ModelConfig", []interface{}{}}, 136 }) 137 } 138 139 func (s *facadeSuite) TestProxyFalse(c *gc.C) { 140 s.backend.proxySSH = false 141 result, err := s.facade.Proxy() 142 c.Assert(err, jc.ErrorIsNil) 143 c.Check(result.UseProxy, jc.IsFalse) 144 s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ 145 {"ModelConfig", []interface{}{}}, 146 }) 147 } 148 149 type mockBackend struct { 150 stub jujutesting.Stub 151 proxySSH bool 152 } 153 154 func (backend *mockBackend) ModelTag() names.ModelTag { 155 return names.NewModelTag("deadbeef-2f18-4fd2-967d-db9663db7bea") 156 } 157 158 func (backend *mockBackend) ModelConfig() (*config.Config, error) { 159 backend.stub.AddCall("ModelConfig") 160 attrs := testing.FakeConfig() 161 attrs["proxy-ssh"] = backend.proxySSH 162 conf, err := config.New(config.NoDefaults, attrs) 163 if err != nil { 164 return nil, errors.Trace(err) 165 } 166 return conf, nil 167 } 168 169 func (backend *mockBackend) GetMachineForEntity(tagString string) (sshclient.SSHMachine, error) { 170 backend.stub.AddCall("GetMachineForEntity", tagString) 171 switch tagString { 172 case names.NewMachineTag("0").String(): 173 return &mockMachine{ 174 tag: names.NewMachineTag("0"), 175 publicAddress: "1.1.1.1", 176 privateAddress: "2.2.2.2", 177 }, nil 178 case names.NewUnitTag("foo/0").String(): 179 return &mockMachine{ 180 tag: names.NewMachineTag("1"), 181 publicAddress: "3.3.3.3", 182 privateAddress: "4.4.4.4", 183 }, nil 184 } 185 return nil, errors.NotFoundf("entity") 186 } 187 188 func (backend *mockBackend) GetSSHHostKeys(tag names.MachineTag) (state.SSHHostKeys, error) { 189 backend.stub.AddCall("GetSSHHostKeys", tag) 190 switch tag { 191 case names.NewMachineTag("0"): 192 return state.SSHHostKeys{"rsa0", "dsa0"}, nil 193 case names.NewMachineTag("1"): 194 return state.SSHHostKeys{"rsa1", "dsa1"}, nil 195 } 196 return nil, errors.New("machine not found") 197 } 198 199 type mockMachine struct { 200 tag names.MachineTag 201 publicAddress string 202 privateAddress string 203 } 204 205 func (m *mockMachine) MachineTag() names.MachineTag { 206 return m.tag 207 } 208 209 func (m *mockMachine) PublicAddress() (network.Address, error) { 210 return network.Address{ 211 Value: m.publicAddress, 212 }, nil 213 } 214 215 func (m *mockMachine) PrivateAddress() (network.Address, error) { 216 return network.Address{ 217 Value: m.privateAddress, 218 }, nil 219 }