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  }