github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/testing/environ.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package testing 5 6 import ( 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 11 gc "launchpad.net/gocheck" 12 13 "launchpad.net/juju-core/environs/config" 14 "launchpad.net/juju-core/juju/osenv" 15 "launchpad.net/juju-core/testing/testbase" 16 "launchpad.net/juju-core/utils/ssh" 17 ) 18 19 // FakeAuthKeys holds the authorized key used for testing 20 // purposes in FakeConfig. It is valid for parsing with the utils/ssh 21 // authorized-key utilities. 22 const FakeAuthKeys = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAYQDP8fPSAMFm2PQGoVUks/FENVUMww1QTK6m++Y2qX9NGHm43kwEzxfoWR77wo6fhBhgFHsQ6ogE/cYLx77hOvjTchMEP74EVxSce0qtDjI7SwYbOpAButRId3g/Ef4STz8= joe@0.1.2.4` 23 24 func init() { 25 _, err := ssh.ParseAuthorisedKey(FakeAuthKeys) 26 if err != nil { 27 panic("FakeAuthKeys does not hold a valid authorized key: " + err.Error()) 28 } 29 } 30 31 // FakeConfig() returns an environment configuration for a 32 // fake provider with all required attributes set. 33 func FakeConfig() Attrs { 34 return Attrs{ 35 "type": "someprovider", 36 "name": "testenv", 37 "authorized-keys": FakeAuthKeys, 38 "firewall-mode": config.FwInstance, 39 "admin-secret": "fish", 40 "ca-cert": CACert, 41 "ca-private-key": CAKey, 42 "ssl-hostname-verification": true, 43 "development": false, 44 "state-port": 19034, 45 "api-port": 17777, 46 "default-series": config.DefaultSeries, 47 } 48 } 49 50 // EnvironConfig returns a default environment configuration suitable for 51 // setting in the state. 52 func EnvironConfig(c *gc.C) *config.Config { 53 return CustomEnvironConfig(c, Attrs{}) 54 } 55 56 // CustomEnvironConfig returns an environment configuration with 57 // additional specified keys added. 58 func CustomEnvironConfig(c *gc.C, extra Attrs) *config.Config { 59 attrs := FakeConfig().Merge(Attrs{ 60 "agent-version": "1.2.3", 61 }).Merge(extra).Delete("admin-secret", "ca-private-key") 62 cfg, err := config.New(config.NoDefaults, attrs) 63 c.Assert(err, gc.IsNil) 64 return cfg 65 } 66 67 const ( 68 SampleEnvName = "erewhemos" 69 EnvDefault = "default:\n " + SampleEnvName + "\n" 70 ) 71 72 const DefaultMongoPassword = "conn-from-name-secret" 73 74 // Environment names below are explicit as it makes them more readable. 75 const SingleEnvConfigNoDefault = ` 76 environments: 77 erewhemos: 78 type: dummy 79 state-server: true 80 authorized-keys: i-am-a-key 81 admin-secret: ` + DefaultMongoPassword + ` 82 ` 83 84 const SingleEnvConfig = EnvDefault + SingleEnvConfigNoDefault 85 86 const MultipleEnvConfigNoDefault = ` 87 environments: 88 erewhemos: 89 type: dummy 90 state-server: true 91 authorized-keys: i-am-a-key 92 admin-secret: ` + DefaultMongoPassword + ` 93 erewhemos-2: 94 type: dummy 95 state-server: true 96 authorized-keys: i-am-a-key 97 admin-secret: ` + DefaultMongoPassword + ` 98 ` 99 100 const MultipleEnvConfig = EnvDefault + MultipleEnvConfigNoDefault 101 102 const SampleCertName = "erewhemos" 103 104 type TestFile struct { 105 Name, Data string 106 } 107 108 type FakeHome struct { 109 oldHomeEnv string 110 oldEnvironment map[string]string 111 oldJujuHome string 112 files []TestFile 113 } 114 115 // MakeFakeHomeNoEnvironments creates a new temporary directory through the 116 // test checker, and overrides the HOME environment variable to point to this 117 // new temporary directory. 118 // 119 // No ~/.juju/environments.yaml exists, but CAKeys are written for each of the 120 // 'certNames' specified, and the id_rsa.pub file is written to to the .ssh 121 // dir. 122 func MakeFakeHomeNoEnvironments(c *gc.C, certNames ...string) *FakeHome { 123 fake := MakeEmptyFakeHome(c) 124 125 for _, name := range certNames { 126 err := ioutil.WriteFile(osenv.JujuHomePath(name+"-cert.pem"), []byte(CACert), 0600) 127 c.Assert(err, gc.IsNil) 128 err = ioutil.WriteFile(osenv.JujuHomePath(name+"-private-key.pem"), []byte(CAKey), 0600) 129 c.Assert(err, gc.IsNil) 130 } 131 132 err := os.Mkdir(HomePath(".ssh"), 0777) 133 c.Assert(err, gc.IsNil) 134 err = ioutil.WriteFile(HomePath(".ssh", "id_rsa.pub"), []byte("auth key\n"), 0666) 135 c.Assert(err, gc.IsNil) 136 137 return fake 138 } 139 140 // MakeFakeHome creates a new temporary directory through the test checker, 141 // and overrides the HOME environment variable to point to this new temporary 142 // directory. 143 // 144 // A new ~/.juju/environments.yaml file is created with the content of the 145 // `envConfig` parameter, and CAKeys are written for each of the 'certNames' 146 // specified. 147 func MakeFakeHome(c *gc.C, envConfig string, certNames ...string) *FakeHome { 148 fake := MakeFakeHomeNoEnvironments(c, certNames...) 149 150 envs := osenv.JujuHomePath("environments.yaml") 151 err := ioutil.WriteFile(envs, []byte(envConfig), 0644) 152 c.Assert(err, gc.IsNil) 153 154 return fake 155 } 156 157 func MakeEmptyFakeHome(c *gc.C) *FakeHome { 158 fake := MakeEmptyFakeHomeWithoutJuju(c) 159 err := os.Mkdir(osenv.JujuHome(), 0700) 160 c.Assert(err, gc.IsNil) 161 return fake 162 } 163 164 func MakeEmptyFakeHomeWithoutJuju(c *gc.C) *FakeHome { 165 oldHomeEnv := osenv.Home() 166 oldEnvironment := make(map[string]string) 167 for _, name := range []string{ 168 osenv.JujuHomeEnvKey, 169 osenv.JujuEnvEnvKey, 170 osenv.JujuLoggingConfigEnvKey, 171 } { 172 oldEnvironment[name] = os.Getenv(name) 173 } 174 fakeHome := c.MkDir() 175 osenv.SetHome(fakeHome) 176 os.Setenv(osenv.JujuHomeEnvKey, "") 177 os.Setenv(osenv.JujuEnvEnvKey, "") 178 os.Setenv(osenv.JujuLoggingConfigEnvKey, "") 179 jujuHome := filepath.Join(fakeHome, ".juju") 180 oldJujuHome := osenv.SetJujuHome(jujuHome) 181 return &FakeHome{ 182 oldHomeEnv: oldHomeEnv, 183 oldEnvironment: oldEnvironment, 184 oldJujuHome: oldJujuHome, 185 files: []TestFile{}, 186 } 187 } 188 189 func HomePath(names ...string) string { 190 all := append([]string{osenv.Home()}, names...) 191 return filepath.Join(all...) 192 } 193 194 func (h *FakeHome) Restore() { 195 osenv.SetJujuHome(h.oldJujuHome) 196 for name, value := range h.oldEnvironment { 197 os.Setenv(name, value) 198 } 199 osenv.SetHome(h.oldHomeEnv) 200 } 201 202 func (h *FakeHome) AddFiles(c *gc.C, files []TestFile) { 203 for _, f := range files { 204 path := HomePath(f.Name) 205 err := os.MkdirAll(filepath.Dir(path), 0700) 206 c.Assert(err, gc.IsNil) 207 err = ioutil.WriteFile(path, []byte(f.Data), 0666) 208 c.Assert(err, gc.IsNil) 209 h.files = append(h.files, f) 210 } 211 } 212 213 // FileContents returns the test file contents for the 214 // given specified path (which may be relative, so 215 // we compare with the base filename only). 216 func (h *FakeHome) FileContents(c *gc.C, path string) string { 217 for _, f := range h.files { 218 if filepath.Base(f.Name) == filepath.Base(path) { 219 return f.Data 220 } 221 } 222 c.Fatalf("path attribute holds unknown test file: %q", path) 223 panic("unreachable") 224 } 225 226 // FileExists returns if the given relative file path exists 227 // in the fake home. 228 func (h *FakeHome) FileExists(path string) bool { 229 for _, f := range h.files { 230 if f.Name == path { 231 return true 232 } 233 } 234 return false 235 } 236 237 func MakeFakeHomeWithFiles(c *gc.C, files []TestFile) *FakeHome { 238 fake := MakeEmptyFakeHome(c) 239 fake.AddFiles(c, files) 240 return fake 241 } 242 243 func MakeSampleHome(c *gc.C) *FakeHome { 244 return MakeFakeHome(c, SingleEnvConfig, SampleCertName) 245 } 246 247 func MakeMultipleEnvHome(c *gc.C) *FakeHome { 248 return MakeFakeHome(c, MultipleEnvConfig, SampleCertName, SampleCertName+"-2") 249 } 250 251 type FakeHomeSuite struct { 252 testbase.LoggingSuite 253 Home *FakeHome 254 } 255 256 func (s *FakeHomeSuite) SetUpTest(c *gc.C) { 257 s.LoggingSuite.SetUpTest(c) 258 s.Home = MakeSampleHome(c) 259 s.AddCleanup(func(*gc.C) { s.Home.Restore() }) 260 }