github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/cmd/juju/authorisedkeys_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	gc "launchpad.net/gocheck"
    11  
    12  	"launchpad.net/juju-core/juju/osenv"
    13  	jujutesting "launchpad.net/juju-core/juju/testing"
    14  	keymanagerserver "launchpad.net/juju-core/state/apiserver/keymanager"
    15  	keymanagertesting "launchpad.net/juju-core/state/apiserver/keymanager/testing"
    16  	statetesting "launchpad.net/juju-core/state/testing"
    17  	coretesting "launchpad.net/juju-core/testing"
    18  	"launchpad.net/juju-core/testing/testbase"
    19  	sshtesting "launchpad.net/juju-core/utils/ssh/testing"
    20  )
    21  
    22  type AuthorisedKeysSuite struct {
    23  	testbase.LoggingSuite
    24  	jujuHome *coretesting.FakeHome
    25  }
    26  
    27  var _ = gc.Suite(&AuthorisedKeysSuite{})
    28  
    29  var authKeysCommandNames = []string{
    30  	"add",
    31  	"delete",
    32  	"help",
    33  	"import",
    34  	"list",
    35  }
    36  
    37  func (s *AuthorisedKeysSuite) SetUpTest(c *gc.C) {
    38  	s.LoggingSuite.SetUpTest(c)
    39  	s.jujuHome = coretesting.MakeEmptyFakeHome(c)
    40  }
    41  
    42  func (s *AuthorisedKeysSuite) TearDownTest(c *gc.C) {
    43  	s.jujuHome.Restore()
    44  	s.LoggingSuite.TearDownTest(c)
    45  }
    46  
    47  func (s *AuthorisedKeysSuite) TestHelpCommands(c *gc.C) {
    48  	// Check that we have correctly registered all the sub commands
    49  	// by checking the help output.
    50  	out := badrun(c, 0, "authorised-keys", "--help")
    51  	lines := strings.Split(out, "\n")
    52  	var names []string
    53  	subcommandsFound := false
    54  	for _, line := range lines {
    55  		f := strings.Fields(line)
    56  		if len(f) == 1 && f[0] == "commands:" {
    57  			subcommandsFound = true
    58  			continue
    59  		}
    60  		if !subcommandsFound || len(f) == 0 || !strings.HasPrefix(line, "    ") {
    61  			continue
    62  		}
    63  		names = append(names, f[0])
    64  	}
    65  	// The names should be output in alphabetical order, so don't sort.
    66  	c.Assert(names, gc.DeepEquals, authKeysCommandNames)
    67  }
    68  
    69  func (s *AuthorisedKeysSuite) assertHelpOutput(c *gc.C, cmd, args string) {
    70  	if args != "" {
    71  		args = " " + args
    72  	}
    73  	expected := fmt.Sprintf("usage: juju authorised-keys %s [options]%s", cmd, args)
    74  	out := badrun(c, 0, "authorised-keys", cmd, "--help")
    75  	lines := strings.Split(out, "\n")
    76  	c.Assert(lines[0], gc.Equals, expected)
    77  }
    78  
    79  func (s *AuthorisedKeysSuite) TestHelpList(c *gc.C) {
    80  	s.assertHelpOutput(c, "list", "")
    81  }
    82  
    83  func (s *AuthorisedKeysSuite) TestHelpAdd(c *gc.C) {
    84  	s.assertHelpOutput(c, "add", "<ssh key> [...]")
    85  }
    86  
    87  func (s *AuthorisedKeysSuite) TestHelpDelete(c *gc.C) {
    88  	s.assertHelpOutput(c, "delete", "<ssh key id> [...]")
    89  }
    90  
    91  func (s *AuthorisedKeysSuite) TestHelpImport(c *gc.C) {
    92  	s.assertHelpOutput(c, "import", "<ssh key id> [...]")
    93  }
    94  
    95  type keySuiteBase struct {
    96  	jujutesting.JujuConnSuite
    97  }
    98  
    99  func (s *keySuiteBase) SetUpSuite(c *gc.C) {
   100  	s.JujuConnSuite.SetUpSuite(c)
   101  	s.PatchEnvironment(osenv.JujuEnvEnvKey, "dummyenv")
   102  }
   103  
   104  func (s *keySuiteBase) setAuthorisedKeys(c *gc.C, keys ...string) {
   105  	keyString := strings.Join(keys, "\n")
   106  	err := statetesting.UpdateConfig(s.State, map[string]interface{}{"authorized-keys": keyString})
   107  	c.Assert(err, gc.IsNil)
   108  	envConfig, err := s.State.EnvironConfig()
   109  	c.Assert(err, gc.IsNil)
   110  	c.Assert(envConfig.AuthorizedKeys(), gc.Equals, keyString)
   111  }
   112  
   113  func (s *keySuiteBase) assertEnvironKeys(c *gc.C, expected ...string) {
   114  	envConfig, err := s.State.EnvironConfig()
   115  	c.Assert(err, gc.IsNil)
   116  	keys := envConfig.AuthorizedKeys()
   117  	c.Assert(keys, gc.Equals, strings.Join(expected, "\n"))
   118  }
   119  
   120  type ListKeysSuite struct {
   121  	keySuiteBase
   122  }
   123  
   124  var _ = gc.Suite(&ListKeysSuite{})
   125  
   126  func (s *ListKeysSuite) TestListKeys(c *gc.C) {
   127  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   128  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   129  	s.setAuthorisedKeys(c, key1, key2)
   130  
   131  	context, err := coretesting.RunCommand(c, &ListKeysCommand{}, []string{})
   132  	c.Assert(err, gc.IsNil)
   133  	output := strings.TrimSpace(coretesting.Stdout(context))
   134  	c.Assert(err, gc.IsNil)
   135  	c.Assert(output, gc.Matches, "Keys for user admin:\n.*\\(user@host\\)\n.*\\(another@host\\)")
   136  }
   137  
   138  func (s *ListKeysSuite) TestListFullKeys(c *gc.C) {
   139  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   140  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   141  	s.setAuthorisedKeys(c, key1, key2)
   142  
   143  	context, err := coretesting.RunCommand(c, &ListKeysCommand{}, []string{"--full"})
   144  	c.Assert(err, gc.IsNil)
   145  	output := strings.TrimSpace(coretesting.Stdout(context))
   146  	c.Assert(err, gc.IsNil)
   147  	c.Assert(output, gc.Matches, "Keys for user admin:\n.*user@host\n.*another@host")
   148  }
   149  
   150  func (s *ListKeysSuite) TestListKeysNonDefaultUser(c *gc.C) {
   151  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   152  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   153  	s.setAuthorisedKeys(c, key1, key2)
   154  	_, err := s.State.AddUser("fred", "password")
   155  	c.Assert(err, gc.IsNil)
   156  
   157  	context, err := coretesting.RunCommand(c, &ListKeysCommand{}, []string{"--user", "fred"})
   158  	c.Assert(err, gc.IsNil)
   159  	output := strings.TrimSpace(coretesting.Stdout(context))
   160  	c.Assert(err, gc.IsNil)
   161  	c.Assert(output, gc.Matches, "Keys for user fred:\n.*\\(user@host\\)\n.*\\(another@host\\)")
   162  }
   163  
   164  func (s *ListKeysSuite) TestTooManyArgs(c *gc.C) {
   165  	_, err := coretesting.RunCommand(c, &ListKeysCommand{}, []string{"foo"})
   166  	c.Assert(err, gc.ErrorMatches, `unrecognized args: \["foo"\]`)
   167  }
   168  
   169  type AddKeySuite struct {
   170  	keySuiteBase
   171  }
   172  
   173  var _ = gc.Suite(&AddKeySuite{})
   174  
   175  func (s *AddKeySuite) TestAddKey(c *gc.C) {
   176  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   177  	s.setAuthorisedKeys(c, key1)
   178  
   179  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   180  	context, err := coretesting.RunCommand(c, &AddKeysCommand{}, []string{key2, "invalid-key"})
   181  	c.Assert(err, gc.IsNil)
   182  	c.Assert(coretesting.Stderr(context), gc.Matches, `cannot add key "invalid-key".*\n`)
   183  	s.assertEnvironKeys(c, key1, key2)
   184  }
   185  
   186  func (s *AddKeySuite) TestAddKeyNonDefaultUser(c *gc.C) {
   187  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   188  	s.setAuthorisedKeys(c, key1)
   189  	_, err := s.State.AddUser("fred", "password")
   190  	c.Assert(err, gc.IsNil)
   191  
   192  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   193  	context, err := coretesting.RunCommand(c, &AddKeysCommand{}, []string{"--user", "fred", key2})
   194  	c.Assert(err, gc.IsNil)
   195  	c.Assert(coretesting.Stderr(context), gc.Equals, "")
   196  	s.assertEnvironKeys(c, key1, key2)
   197  }
   198  
   199  type DeleteKeySuite struct {
   200  	keySuiteBase
   201  }
   202  
   203  var _ = gc.Suite(&DeleteKeySuite{})
   204  
   205  func (s *DeleteKeySuite) TestDeleteKeys(c *gc.C) {
   206  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   207  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   208  	s.setAuthorisedKeys(c, key1, key2)
   209  
   210  	context, err := coretesting.RunCommand(
   211  		c, &DeleteKeysCommand{}, []string{sshtesting.ValidKeyTwo.Fingerprint, "invalid-key"})
   212  	c.Assert(err, gc.IsNil)
   213  	c.Assert(coretesting.Stderr(context), gc.Matches, `cannot delete key id "invalid-key".*\n`)
   214  	s.assertEnvironKeys(c, key1)
   215  }
   216  
   217  func (s *DeleteKeySuite) TestDeleteKeyNonDefaultUser(c *gc.C) {
   218  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   219  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   220  	s.setAuthorisedKeys(c, key1, key2)
   221  	_, err := s.State.AddUser("fred", "password")
   222  	c.Assert(err, gc.IsNil)
   223  
   224  	context, err := coretesting.RunCommand(
   225  		c, &DeleteKeysCommand{}, []string{"--user", "fred", sshtesting.ValidKeyTwo.Fingerprint})
   226  	c.Assert(err, gc.IsNil)
   227  	c.Assert(coretesting.Stderr(context), gc.Equals, "")
   228  	s.assertEnvironKeys(c, key1)
   229  }
   230  
   231  type ImportKeySuite struct {
   232  	keySuiteBase
   233  }
   234  
   235  var _ = gc.Suite(&ImportKeySuite{})
   236  
   237  func (s *ImportKeySuite) SetUpTest(c *gc.C) {
   238  	s.keySuiteBase.SetUpTest(c)
   239  	s.PatchValue(&keymanagerserver.RunSSHImportId, keymanagertesting.FakeImport)
   240  }
   241  
   242  func (s *ImportKeySuite) TestImportKeys(c *gc.C) {
   243  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   244  	s.setAuthorisedKeys(c, key1)
   245  
   246  	context, err := coretesting.RunCommand(c, &ImportKeysCommand{}, []string{"lp:validuser", "invalid-key"})
   247  	c.Assert(err, gc.IsNil)
   248  	c.Assert(coretesting.Stderr(context), gc.Matches, `cannot import key id "invalid-key".*\n`)
   249  	s.assertEnvironKeys(c, key1, sshtesting.ValidKeyThree.Key)
   250  }
   251  
   252  func (s *ImportKeySuite) TestImportKeyNonDefaultUser(c *gc.C) {
   253  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   254  	s.setAuthorisedKeys(c, key1)
   255  	_, err := s.State.AddUser("fred", "password")
   256  	c.Assert(err, gc.IsNil)
   257  
   258  	context, err := coretesting.RunCommand(c, &ImportKeysCommand{}, []string{"--user", "fred", "lp:validuser"})
   259  	c.Assert(err, gc.IsNil)
   260  	c.Assert(coretesting.Stderr(context), gc.Equals, "")
   261  	s.assertEnvironKeys(c, key1, sshtesting.ValidKeyThree.Key)
   262  }