github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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  	"github.com/juju/gnuflag"
    10  	"gopkg.in/yaml.v2"
    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:
    32      clouds
    33      update-clouds
    34  `
    35  
    36  // NewShowCloudCommand returns a command to list cloud information.
    37  func NewShowCloudCommand() cmd.Command {
    38  	return &showCloudCommand{}
    39  }
    40  
    41  func (c *showCloudCommand) SetFlags(f *gnuflag.FlagSet) {
    42  	c.CommandBase.SetFlags(f)
    43  	// We only support yaml for display purposes.
    44  	c.out.AddFlags(f, "yaml", map[string]cmd.Formatter{
    45  		"yaml": cmd.FormatYaml,
    46  	})
    47  }
    48  
    49  func (c *showCloudCommand) Init(args []string) error {
    50  	switch len(args) {
    51  	case 1:
    52  		c.CloudName = args[0]
    53  	default:
    54  		return errors.New("no cloud specified")
    55  	}
    56  	return cmd.CheckEmpty(args[1:])
    57  }
    58  
    59  func (c *showCloudCommand) Info() *cmd.Info {
    60  	return &cmd.Info{
    61  		Name:    "show-cloud",
    62  		Args:    "<cloud name>",
    63  		Purpose: "Shows detailed information on a cloud.",
    64  		Doc:     showCloudDoc,
    65  	}
    66  }
    67  
    68  func (c *showCloudCommand) Run(ctxt *cmd.Context) error {
    69  	details, err := getCloudDetails()
    70  	if err != nil {
    71  		return err
    72  	}
    73  	cloud, ok := details[c.CloudName]
    74  	if !ok {
    75  		return errors.NotFoundf("cloud %q", c.CloudName)
    76  	}
    77  	return c.out.Write(ctxt, cloud)
    78  }
    79  
    80  type regionDetails struct {
    81  	Name             string `yaml:"-" json:"-"`
    82  	Endpoint         string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"`
    83  	IdentityEndpoint string `yaml:"identity-endpoint,omitempty" json:"identity-endpoint,omitempty"`
    84  	StorageEndpoint  string `yaml:"storage-endpoint,omitempty" json:"storage-endpoint,omitempty"`
    85  }
    86  
    87  type cloudDetails struct {
    88  	Source           string   `yaml:"defined,omitempty" json:"defined,omitempty"`
    89  	CloudType        string   `yaml:"type" json:"type"`
    90  	AuthTypes        []string `yaml:"auth-types,omitempty,flow" json:"auth-types,omitempty"`
    91  	Endpoint         string   `yaml:"endpoint,omitempty" json:"endpoint,omitempty"`
    92  	IdentityEndpoint string   `yaml:"identity-endpoint,omitempty" json:"identity-endpoint,omitempty"`
    93  	StorageEndpoint  string   `yaml:"storage-endpoint,omitempty" json:"storage-endpoint,omitempty"`
    94  	// Regions is for when we want to print regions in order for yaml or tabular output.
    95  	Regions yaml.MapSlice `yaml:"regions,omitempty" json:"-"`
    96  	// Regions map is for json marshalling where format is important but not order.
    97  	RegionsMap   map[string]regionDetails `yaml:"-" json:"regions,omitempty"`
    98  	Config       map[string]interface{}   `yaml:"config,omitempty" json:"config,omitempty"`
    99  	RegionConfig jujucloud.RegionConfig   `yaml:"region-config,omitempty" json:"region-config,omitempty"`
   100  }
   101  
   102  func makeCloudDetails(cloud jujucloud.Cloud) *cloudDetails {
   103  	result := &cloudDetails{
   104  		Source:           "public",
   105  		CloudType:        cloud.Type,
   106  		Endpoint:         cloud.Endpoint,
   107  		IdentityEndpoint: cloud.IdentityEndpoint,
   108  		StorageEndpoint:  cloud.StorageEndpoint,
   109  		Config:           cloud.Config,
   110  		RegionConfig:     cloud.RegionConfig,
   111  	}
   112  	result.AuthTypes = make([]string, len(cloud.AuthTypes))
   113  	for i, at := range cloud.AuthTypes {
   114  		result.AuthTypes[i] = string(at)
   115  	}
   116  	result.RegionsMap = make(map[string]regionDetails)
   117  	for _, region := range cloud.Regions {
   118  		r := regionDetails{Name: region.Name}
   119  		if region.Endpoint != result.Endpoint {
   120  			r.Endpoint = region.Endpoint
   121  		}
   122  		if region.IdentityEndpoint != result.IdentityEndpoint {
   123  			r.IdentityEndpoint = region.IdentityEndpoint
   124  		}
   125  		if region.StorageEndpoint != result.StorageEndpoint {
   126  			r.StorageEndpoint = region.StorageEndpoint
   127  		}
   128  		result.Regions = append(result.Regions, yaml.MapItem{r.Name, r})
   129  		result.RegionsMap[region.Name] = r
   130  	}
   131  	return result
   132  }
   133  
   134  func getCloudDetails() (map[string]*cloudDetails, error) {
   135  	result, err := listCloudDetails()
   136  	if err != nil {
   137  		return nil, errors.Trace(err)
   138  	}
   139  	return result.all(), nil
   140  }