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