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