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