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