~ubuntu-branches/ubuntu/saucy/juju-core/saucy

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/cmd/plugins/juju-metadata/validatemetadata.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 16:02:16 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20130820160216-5yu1llasa2e2youn
Tags: 1.13.1-0ubuntu1
* New upstream release.
  - Build and install juju metadata plugin.
  - d/NEWS: Add some guidance on upgrading environments from 1.11.x
    to 1.13.x.
* d/NEWS: Add details about lack of upgrade path from juju < 1.11
  and how to interact with older juju environments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package main
 
5
 
 
6
import (
 
7
        "fmt"
 
8
        "net/http"
 
9
        "os"
 
10
        "strings"
 
11
 
 
12
        "launchpad.net/gnuflag"
 
13
 
 
14
        "launchpad.net/juju-core/cmd"
 
15
        "launchpad.net/juju-core/environs"
 
16
        "launchpad.net/juju-core/environs/imagemetadata"
 
17
)
 
18
 
 
19
// ValidateImageMetadataCommand
 
20
type ValidateImageMetadataCommand struct {
 
21
        cmd.EnvCommandBase
 
22
        providerType string
 
23
        metadataDir  string
 
24
        series       string
 
25
        region       string
 
26
        endpoint     string
 
27
}
 
28
 
 
29
var validateImagesMetadataDoc = `
 
30
validate-images loads simplestreams metadata and validates the contents by looking for images
 
31
belonging to the specified cloud.
 
32
 
 
33
The cloud specificaton comes from the current Juju environment, as specified in the usual way
 
34
from either ~/.juju/environments.yaml, the -e option, or JUJU_ENV. Series, Region, and Endpoint
 
35
are the key attributes.
 
36
 
 
37
The key environment attributes may be overridden using command arguments, so that the validation
 
38
may be peformed on arbitary metadata.
 
39
 
 
40
Examples:
 
41
 
 
42
- validate using the current environment settings but with series raring
 
43
 juju metadata validate-images -s raring
 
44
 
 
45
- validate using the current environment settings but with series raring and using metadata from local directory
 
46
 juju metadata validate-images -s raring -d <some directory>
 
47
 
 
48
A key use case is to validate newly generated metadata prior to deployment to production.
 
49
In this case, the metadata is placed in a local directory, a cloud provider type is specified (ec2, openstack etc),
 
50
and the validation is performed for each supported region and series.
 
51
 
 
52
Example bash snippet:
 
53
 
 
54
#!/bin/bash
 
55
 
 
56
juju metadata validate-images -p ec2 -r us-east-1 -s precise -d <some directory>
 
57
RETVAL=$?
 
58
[ $RETVAL -eq 0 ] && echo Success
 
59
[ $RETVAL -ne 0 ] && echo Failure
 
60
`
 
61
 
 
62
func (c *ValidateImageMetadataCommand) Info() *cmd.Info {
 
63
        return &cmd.Info{
 
64
                Name:    "validate-images",
 
65
                Purpose: "validate image metadata and ensure image(s) exist for an environment",
 
66
                Doc:     validateImagesMetadataDoc,
 
67
        }
 
68
}
 
69
 
 
70
func (c *ValidateImageMetadataCommand) SetFlags(f *gnuflag.FlagSet) {
 
71
        c.EnvCommandBase.SetFlags(f)
 
72
        f.StringVar(&c.providerType, "p", "", "the provider type eg ec2, openstack")
 
73
        f.StringVar(&c.metadataDir, "d", "", "directory where metadata files are found")
 
74
        f.StringVar(&c.series, "s", "", "the series for which to validate (overrides env config series)")
 
75
        f.StringVar(&c.region, "r", "", "the region for which to validate (overrides env config region)")
 
76
        f.StringVar(&c.endpoint, "u", "", "the cloud endpoint URL for which to validate (overrides env config endpoint)")
 
77
}
 
78
 
 
79
func (c *ValidateImageMetadataCommand) Init(args []string) error {
 
80
        if c.providerType != "" {
 
81
                if c.series == "" {
 
82
                        return fmt.Errorf("series required if provider type is specified")
 
83
                }
 
84
                if c.region == "" {
 
85
                        return fmt.Errorf("region required if provider type is specified")
 
86
                }
 
87
                if c.metadataDir == "" {
 
88
                        return fmt.Errorf("metadata directory required if provider type is specified")
 
89
                }
 
90
        }
 
91
        return c.EnvCommandBase.Init(args)
 
92
}
 
93
 
 
94
func (c *ValidateImageMetadataCommand) Run(context *cmd.Context) error {
 
95
        var params *imagemetadata.MetadataLookupParams
 
96
 
 
97
        if c.providerType == "" {
 
98
                environ, err := environs.NewFromName(c.EnvName)
 
99
                if err != nil {
 
100
                        return err
 
101
                }
 
102
                mdLookup, ok := environ.(imagemetadata.ImageMetadataValidator)
 
103
                if !ok {
 
104
                        return fmt.Errorf("%s provider does not support image metadata validation", environ.Config().Type())
 
105
                }
 
106
                params, err = mdLookup.MetadataLookupParams(c.region)
 
107
                if err != nil {
 
108
                        return err
 
109
                }
 
110
        } else {
 
111
                prov, err := environs.Provider(c.providerType)
 
112
                if err != nil {
 
113
                        return err
 
114
                }
 
115
                mdLookup, ok := prov.(imagemetadata.ImageMetadataValidator)
 
116
                if !ok {
 
117
                        return fmt.Errorf("%s provider does not support image metadata validation", c.providerType)
 
118
                }
 
119
                params, err = mdLookup.MetadataLookupParams(c.region)
 
120
                if err != nil {
 
121
                        return err
 
122
                }
 
123
        }
 
124
 
 
125
        if c.series != "" {
 
126
                params.Series = c.series
 
127
        }
 
128
        if c.region != "" {
 
129
                params.Region = c.region
 
130
        }
 
131
        if c.endpoint != "" {
 
132
                params.Endpoint = c.endpoint
 
133
        }
 
134
        // If the metadata files are to be loaded from a directory, we need to register
 
135
        // a file http transport.
 
136
        if c.metadataDir != "" {
 
137
                if _, err := os.Stat(c.metadataDir); err != nil {
 
138
                        return err
 
139
                }
 
140
 
 
141
                params.BaseURLs = []string{"file://" + c.metadataDir}
 
142
                t := &http.Transport{}
 
143
                t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
 
144
                c := &http.Client{Transport: t}
 
145
                imagemetadata.SetHttpClient(c)
 
146
        }
 
147
 
 
148
        image_ids, err := imagemetadata.ValidateImageMetadata(params)
 
149
        if err != nil {
 
150
                return err
 
151
        }
 
152
 
 
153
        if len(image_ids) > 0 {
 
154
                fmt.Fprintf(context.Stdout, "matching image ids for region %q:\n%s\n", params.Region, strings.Join(image_ids, "\n"))
 
155
        } else {
 
156
                return fmt.Errorf("no matching image ids for region %s using URLs:\n%s", params.Region, strings.Join(params.BaseURLs, "\n"))
 
157
        }
 
158
        return nil
 
159
}