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 }