github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/plugins/juju-metadata/validateimagemetadata_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 "strings" 8 9 "github.com/juju/cmd" 10 "github.com/juju/cmd/cmdtesting" 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils" 13 "gopkg.in/amz.v3/aws" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/cloud" 17 "github.com/juju/juju/cmd/modelcmd" 18 "github.com/juju/juju/core/model" 19 "github.com/juju/juju/environs/config" 20 "github.com/juju/juju/environs/filestorage" 21 "github.com/juju/juju/environs/imagemetadata" 22 "github.com/juju/juju/environs/simplestreams" 23 "github.com/juju/juju/jujuclient" 24 "github.com/juju/juju/jujuclient/jujuclienttesting" 25 coretesting "github.com/juju/juju/testing" 26 ) 27 28 type ValidateImageMetadataSuite struct { 29 coretesting.FakeJujuXDGDataHomeSuite 30 metadataDir string 31 store *jujuclient.MemStore 32 } 33 34 var _ = gc.Suite(&ValidateImageMetadataSuite{}) 35 36 func runValidateImageMetadata(c *gc.C, store jujuclient.ClientStore, args ...string) (*cmd.Context, error) { 37 cmd := &validateImageMetadataCommand{} 38 cmd.SetClientStore(store) 39 return cmdtesting.RunCommand(c, modelcmd.WrapController(cmd), args...) 40 } 41 42 var validateInitImageErrorTests = []struct { 43 args []string 44 err string 45 }{ 46 { 47 args: []string{"-p", "ec2", "-r", "region", "-d", "dir"}, 48 err: `series required if provider type is specified`, 49 }, { 50 args: []string{"-p", "ec2", "-s", "series", "-d", "dir"}, 51 err: `region required if provider type is specified`, 52 }, { 53 args: []string{"-p", "ec2", "-s", "series", "-r", "region"}, 54 err: `metadata directory required if provider type is specified`, 55 }, 56 } 57 58 func (s *ValidateImageMetadataSuite) TestInitErrors(c *gc.C) { 59 for i, t := range validateInitImageErrorTests { 60 c.Logf("test %d", i) 61 cmd := &validateImageMetadataCommand{} 62 cmd.SetClientStore(jujuclienttesting.MinimalStore()) 63 err := cmdtesting.InitCommand(modelcmd.WrapController(cmd), t.args) 64 c.Check(err, gc.ErrorMatches, t.err) 65 } 66 } 67 68 func (s *ValidateImageMetadataSuite) TestInvalidProviderError(c *gc.C) { 69 _, err := runValidateImageMetadata(c, s.store, "-p", "foo", "-s", "series", "-r", "region", "-d", "dir") 70 c.Check(err, gc.ErrorMatches, `no registered provider for "foo"`) 71 } 72 73 func (s *ValidateImageMetadataSuite) TestUnsupportedProviderError(c *gc.C) { 74 _, err := runValidateImageMetadata(c, s.store, "-p", "maas", "-s", "series", "-r", "region", "-d", "dir") 75 c.Check(err, gc.ErrorMatches, `maas provider does not support image metadata validation`) 76 } 77 78 func (s *ValidateImageMetadataSuite) makeLocalMetadata(c *gc.C, id, region, series, endpoint, stream string) error { 79 im := &imagemetadata.ImageMetadata{ 80 Id: id, 81 Arch: "amd64", 82 Stream: stream, 83 } 84 cloudSpec := simplestreams.CloudSpec{ 85 Region: region, 86 Endpoint: endpoint, 87 } 88 targetStorage, err := filestorage.NewFileStorageWriter(s.metadataDir) 89 if err != nil { 90 return err 91 } 92 err = imagemetadata.MergeAndWriteMetadata(series, []*imagemetadata.ImageMetadata{im}, &cloudSpec, targetStorage) 93 if err != nil { 94 return err 95 } 96 return nil 97 } 98 99 func cacheTestEnvConfig(c *gc.C, store *jujuclient.MemStore) { 100 ec2UUID := utils.MustNewUUID().String() 101 ec2Config, err := config.New(config.UseDefaults, map[string]interface{}{ 102 "name": "ec2", 103 "type": "ec2", 104 "default-series": "precise", 105 "controller-uuid": coretesting.ControllerTag.Id(), 106 "uuid": ec2UUID, 107 }) 108 c.Assert(err, jc.ErrorIsNil) 109 store.Controllers["ec2-controller"] = jujuclient.ControllerDetails{ 110 ControllerUUID: coretesting.ControllerTag.Id(), 111 CACert: coretesting.CACert, 112 } 113 store.Controllers["ec2-controller-lts"] = jujuclient.ControllerDetails{ 114 ControllerUUID: coretesting.ControllerTag.Id(), 115 CACert: coretesting.CACert, 116 } 117 store.Models["ec2-controller"] = &jujuclient.ControllerModels{ 118 Models: map[string]jujuclient.ModelDetails{ 119 "admin/ec2": { 120 ModelType: model.IAAS, 121 }, 122 "admin/ec2-latest-lts": { 123 ModelType: model.IAAS, 124 }, 125 }, 126 CurrentModel: "admin/controller", 127 } 128 store.Accounts["ec2-controller"] = jujuclient.AccountDetails{ 129 User: "admin", 130 } 131 store.Accounts["ec2-controller-lts"] = jujuclient.AccountDetails{ 132 User: "admin", 133 } 134 135 store.BootstrapConfig["ec2-controller"] = jujuclient.BootstrapConfig{ 136 ControllerConfig: coretesting.FakeControllerConfig(), 137 ControllerModelUUID: ec2UUID, 138 Config: ec2Config.AllAttrs(), 139 Cloud: "ec2", 140 CloudType: "ec2", 141 CloudRegion: "us-east-1", 142 CloudEndpoint: "https://ec2.us-east-1.amazonaws.com", 143 } 144 145 azureUUID := utils.MustNewUUID().String() 146 azureConfig, err := config.New(config.UseDefaults, map[string]interface{}{ 147 "name": "azure", 148 "type": "azure", 149 "controller-uuid": coretesting.ControllerTag.Id(), 150 "uuid": azureUUID, 151 "default-series": "raring", 152 }) 153 c.Assert(err, jc.ErrorIsNil) 154 store.Controllers["azure-controller"] = jujuclient.ControllerDetails{ 155 ControllerUUID: coretesting.ControllerTag.Id(), 156 CACert: coretesting.CACert, 157 } 158 store.Models["azure-controller"] = &jujuclient.ControllerModels{ 159 Models: map[string]jujuclient.ModelDetails{ 160 "admin/azure": { 161 ModelType: model.IAAS, 162 }, 163 }, 164 CurrentModel: "admin/controller", 165 } 166 store.Accounts["azure-controller"] = jujuclient.AccountDetails{ 167 User: "admin", 168 } 169 store.BootstrapConfig["azure-controller"] = jujuclient.BootstrapConfig{ 170 ControllerConfig: coretesting.FakeControllerConfig(), 171 ControllerModelUUID: azureUUID, 172 Config: azureConfig.AllAttrs(), 173 Cloud: "azure", 174 CloudType: "azure", 175 CloudRegion: "West US", 176 CloudEndpoint: "https://management.azure.com", 177 CloudStorageEndpoint: "https://core.windows.net", 178 Credential: "default", 179 } 180 store.Credentials["azure"] = cloud.CloudCredential{ 181 AuthCredentials: map[string]cloud.Credential{ 182 "default": cloud.NewCredential( 183 "service-principal-secret", 184 map[string]string{ 185 "application-id": "application-id", 186 "subscription-id": "subscription-id", 187 "application-password": "application-password", 188 }, 189 ), 190 }, 191 } 192 } 193 194 func (s *ValidateImageMetadataSuite) SetUpTest(c *gc.C) { 195 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 196 s.metadataDir = c.MkDir() 197 198 s.store = jujuclienttesting.MinimalStore() 199 cacheTestEnvConfig(c, s.store) 200 201 s.PatchEnvironment("AWS_ACCESS_KEY_ID", "access") 202 s.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret") 203 // All of the following are recognized as fallbacks by goamz. 204 s.PatchEnvironment("AWS_ACCESS_KEY", "") 205 s.PatchEnvironment("AWS_SECRET_KEY", "") 206 s.PatchEnvironment("EC2_ACCESS_KEY", "") 207 s.PatchEnvironment("EC2_SECRET_KEY", "") 208 } 209 210 func (s *ValidateImageMetadataSuite) setupEc2LocalMetadata(c *gc.C, region, stream string) { 211 ec2Region, ok := aws.Regions[region] 212 if !ok { 213 c.Fatalf("unknown ec2 region %q", region) 214 } 215 endpoint := ec2Region.EC2Endpoint 216 s.makeLocalMetadata(c, "1234", region, "precise", endpoint, stream) 217 } 218 219 func (s *ValidateImageMetadataSuite) assertEc2LocalMetadataUsingEnvironment(c *gc.C, stream string) { 220 s.setupEc2LocalMetadata(c, "us-east-1", stream) 221 ctx, err := runValidateImageMetadata(c, s.store, "-c", "ec2-controller", "-d", s.metadataDir, "--stream", stream) 222 c.Assert(err, jc.ErrorIsNil) 223 stdout := cmdtesting.Stdout(ctx) 224 stderr := cmdtesting.Stderr(ctx) 225 strippedOut := strings.Replace(stdout, "\n", "", -1) 226 c.Check(strippedOut, gc.Matches, 227 `ImageIds:.*"1234".*Region:.*us-east-1.*Resolve Metadata:.*source: local metadata directory.*`, 228 ) 229 c.Check(stderr, gc.Matches, "") 230 } 231 232 func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataUsingEnvironment(c *gc.C) { 233 s.assertEc2LocalMetadataUsingEnvironment(c, "") 234 s.assertEc2LocalMetadataUsingEnvironment(c, imagemetadata.ReleasedStream) 235 s.assertEc2LocalMetadataUsingEnvironment(c, "daily") 236 } 237 238 func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataUsingIncompleteEnvironment(c *gc.C) { 239 s.PatchEnvironment("AWS_ACCESS_KEY_ID", "") 240 s.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "") 241 s.PatchEnvironment("EC2_ACCESS_KEY", "") 242 s.PatchEnvironment("EC2_SECRET_KEY", "") 243 s.setupEc2LocalMetadata(c, "us-east-1", "") 244 _, err := runValidateImageMetadata(c, s.store, "-c", "ec2-controller", "-d", s.metadataDir) 245 c.Assert(err, gc.ErrorMatches, `detecting credentials.*AWS_SECRET_ACCESS_KEY not found in environment`) 246 } 247 248 func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataWithManualParams(c *gc.C) { 249 s.setupEc2LocalMetadata(c, "us-west-1", "") 250 ctx, err := runValidateImageMetadata(c, s.store, 251 "-p", "ec2", "-s", "precise", "-r", "us-west-1", 252 "-u", "https://ec2.us-west-1.amazonaws.com", "-d", s.metadataDir, 253 ) 254 c.Assert(err, jc.ErrorIsNil) 255 errOut := cmdtesting.Stdout(ctx) 256 strippedOut := strings.Replace(errOut, "\n", "", -1) 257 c.Check( 258 strippedOut, gc.Matches, 259 `ImageIds:.*"1234".*Region:.*us-west-1.*Resolve Metadata:.*source: local metadata directory.*`) 260 } 261 262 func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataNoMatch(c *gc.C) { 263 s.setupEc2LocalMetadata(c, "us-east-1", "") 264 _, err := runValidateImageMetadata(c, s.store, 265 "-p", "ec2", "-s", "raring", "-r", "us-west-1", 266 "-u", "https://ec2.us-west-1.amazonaws.com", "-d", s.metadataDir, 267 ) 268 c.Check(err, gc.ErrorMatches, "(.|\n)*Resolve Metadata:(.|\n)*") 269 _, err = runValidateImageMetadata(c, s.store, 270 "-p", "ec2", "-s", "precise", "-r", "region", 271 "-u", "https://ec2.region.amazonaws.com", "-d", s.metadataDir, 272 ) 273 c.Check(err, gc.ErrorMatches, `unknown region "region"`) 274 } 275 276 func (s *ValidateImageMetadataSuite) TestOpenstackLocalMetadataWithManualParams(c *gc.C) { 277 s.makeLocalMetadata(c, "1234", "region-2", "raring", "some-auth-url", "") 278 ctx, err := runValidateImageMetadata(c, s.store, 279 "-p", "openstack", "-s", "raring", "-r", "region-2", 280 "-u", "some-auth-url", "-d", s.metadataDir, 281 ) 282 c.Assert(err, jc.ErrorIsNil) 283 errOut := cmdtesting.Stdout(ctx) 284 strippedOut := strings.Replace(errOut, "\n", "", -1) 285 c.Check( 286 strippedOut, gc.Matches, 287 `ImageIds:.*"1234".*Region:.*region-2.*Resolve Metadata:.*source: local metadata directory.*`) 288 } 289 290 func (s *ValidateImageMetadataSuite) TestOpenstackLocalMetadataNoMatch(c *gc.C) { 291 s.makeLocalMetadata(c, "1234", "region-2", "raring", "some-auth-url", "") 292 _, err := runValidateImageMetadata(c, s.store, 293 "-p", "openstack", "-s", "precise", "-r", "region-2", 294 "-u", "some-auth-url", "-d", s.metadataDir, 295 ) 296 c.Check(err, gc.ErrorMatches, "(.|\n)*Resolve Metadata:(.|\n)*") 297 _, err = runValidateImageMetadata(c, s.store, 298 "-p", "openstack", "-s", "raring", "-r", "region-3", 299 "-u", "some-auth-url", "-d", s.metadataDir, 300 ) 301 c.Check(err, gc.ErrorMatches, "(.|\n)*Resolve Metadata:(.|\n)*") 302 } 303 304 func (s *ValidateImageMetadataSuite) TestImagesDataSourceHasKey(c *gc.C) { 305 ds := imagesDataSources("test.me") 306 // This data source does not require to contain signed data. 307 // However, it may still contain it. 308 // Since we will always try to read signed data first, 309 // we want to be able to try to read this signed data 310 // with a user provided public key. For this test, none is provided. 311 // Bugs #1542127, #1542131 312 c.Assert(ds[0].PublicSigningKey(), gc.Equals, "") 313 }