github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/cloud/show.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package cloud
     5  
     6  import (
     7  	"github.com/juju/cmd"
     8  	"github.com/juju/errors"
     9  	"gopkg.in/yaml.v2"
    10  	"launchpad.net/gnuflag"
    11  
    12  	jujucloud "github.com/juju/juju/cloud"
    13  )
    14  
    15  type showCloudCommand struct {
    16  	cmd.CommandBase
    17  	out cmd.Output
    18  
    19  	CloudName string
    20  }
    21  
    22  var showCloudDoc = `
    23  Provided information includes 'defined' (public, built-in), 'type',
    24  'auth-type', 'regions', and 'endpoints'.
    25  
    26  Examples:
    27  
    28      juju show-cloud google
    29      juju show-cloud azure-china --output ~/azure_cloud_details.txt
    30  
    31  See also: list-clouds
    32            update-clouds
    33  `
    34  
    35  // NewShowCloudCommand returns a command to list cloud information.
    36  func NewShowCloudCommand() cmd.Command {
    37  	return &showCloudCommand{}
    38  }
    39  
    40  func (c *showCloudCommand) SetFlags(f *gnuflag.FlagSet) {
    41  	// We only support yaml for display purposes.
    42  	c.out.AddFlags(f, "yaml", map[string]cmd.Formatter{
    43  		"yaml": cmd.FormatYaml,
    44  	})
    45  }
    46  
    47  func (c *showCloudCommand) Init(args []string) error {
    48  	switch len(args) {
    49  	case 1:
    50  		c.CloudName = args[0]
    51  	default:
    52  		return errors.New("no cloud specified")
    53  	}
    54  	return cmd.CheckEmpty(args[1:])
    55  }
    56  
    57  func (c *showCloudCommand) Info() *cmd.Info {
    58  	return &cmd.Info{
    59  		Name:    "show-cloud",
    60  		Args:    "<cloud name>",
    61  		Purpose: "Shows detailed information on a cloud.",
    62  		Doc:     showCloudDoc,
    63  	}
    64  }
    65  
    66  func (c *showCloudCommand) Run(ctxt *cmd.Context) error {
    67  	details, err := getCloudDetails()
    68  	if err != nil {
    69  		return err
    70  	}
    71  	cloud, ok := details[c.CloudName]
    72  	if !ok {
    73  		return errors.NotFoundf("cloud %q", c.CloudName)
    74  	}
    75  	return c.out.Write(ctxt, cloud)
    76  }
    77  
    78  type regionDetails struct {
    79  	Name            string `yaml:"-" json:"-"`
    80  	Endpoint        string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"`
    81  	StorageEndpoint string `yaml:"storage-endpoint,omitempty" json:"storage-endpoint,omitempty"`
    82  }
    83  
    84  type cloudDetails struct {
    85  	Source          string   `yaml:"defined,omitempty" json:"defined,omitempty"`
    86  	CloudType       string   `yaml:"type" json:"type"`
    87  	AuthTypes       []string `yaml:"auth-types,omitempty,flow" json:"auth-types,omitempty"`
    88  	Endpoint        string   `yaml:"endpoint,omitempty" json:"endpoint,omitempty"`
    89  	StorageEndpoint string   `yaml:"storage-endpoint,omitempty" json:"storage-endpoint,omitempty"`
    90  	// Regions is for when we want to print regions in order for yaml or tabular output.
    91  	Regions yaml.MapSlice `yaml:"regions,omitempty" json:"-"`
    92  	// Regions map is for json marshalling where format is important but not order.
    93  	RegionsMap map[string]regionDetails `yaml:"-" json:"regions,omitempty"`
    94  }
    95  
    96  func makeCloudDetails(cloud jujucloud.Cloud) *cloudDetails {
    97  	result := &cloudDetails{
    98  		Source:          "public",
    99  		CloudType:       cloud.Type,
   100  		Endpoint:        cloud.Endpoint,
   101  		StorageEndpoint: cloud.StorageEndpoint,
   102  	}
   103  	result.AuthTypes = make([]string, len(cloud.AuthTypes))
   104  	for i, at := range cloud.AuthTypes {
   105  		result.AuthTypes[i] = string(at)
   106  	}
   107  	result.RegionsMap = make(map[string]regionDetails)
   108  	for _, region := range cloud.Regions {
   109  		r := regionDetails{Name: region.Name}
   110  		if region.Endpoint != result.Endpoint {
   111  			r.Endpoint = region.Endpoint
   112  		}
   113  		if region.StorageEndpoint != result.StorageEndpoint {
   114  			r.StorageEndpoint = region.StorageEndpoint
   115  		}
   116  		result.Regions = append(result.Regions, yaml.MapItem{r.Name, r})
   117  		result.RegionsMap[region.Name] = r
   118  	}
   119  	return result
   120  }