github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/cmd/juju/model/show.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for infos.
     3  
     4  package model
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/cmd"
    10  	"github.com/juju/errors"
    11  	"github.com/juju/gnuflag"
    12  	"gopkg.in/juju/names.v2"
    13  
    14  	"github.com/juju/juju/api/modelmanager"
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/cmd/juju/common"
    17  	"github.com/juju/juju/cmd/modelcmd"
    18  	"github.com/juju/juju/cmd/output"
    19  	"github.com/juju/juju/jujuclient"
    20  )
    21  
    22  const showModelCommandDoc = `Show information about the current or specified model`
    23  
    24  func NewShowCommand() cmd.Command {
    25  	showCmd := &showModelCommand{}
    26  	showCmd.RefreshModels = showCmd.ModelCommandBase.RefreshModels
    27  	return modelcmd.Wrap(showCmd, modelcmd.WrapSkipModelFlags)
    28  }
    29  
    30  // showModelCommand shows all the users with access to the current model.
    31  type showModelCommand struct {
    32  	modelcmd.ModelCommandBase
    33  	// RefreshModels hides the RefreshModels function defined
    34  	// in ModelCommandBase. This allows overriding for testing.
    35  	// NOTE: ideal solution would be to have the base implement a method
    36  	// like store.ModelByName which auto-refreshes.
    37  	RefreshModels func(jujuclient.ClientStore, string) error
    38  
    39  	out cmd.Output
    40  	api ShowModelAPI
    41  }
    42  
    43  // ShowModelAPI defines the methods on the client API that the
    44  // users command calls.
    45  type ShowModelAPI interface {
    46  	Close() error
    47  	ModelInfo([]names.ModelTag) ([]params.ModelInfoResult, error)
    48  }
    49  
    50  func (c *showModelCommand) getAPI() (ShowModelAPI, error) {
    51  	if c.api != nil {
    52  		return c.api, nil
    53  	}
    54  	api, err := c.NewControllerAPIRoot()
    55  	if err != nil {
    56  		return nil, errors.Trace(err)
    57  	}
    58  	return modelmanager.NewClient(api), nil
    59  }
    60  
    61  // Info implements Command.Info.
    62  func (c *showModelCommand) Info() *cmd.Info {
    63  	return &cmd.Info{
    64  		Name:    "show-model",
    65  		Args:    "<model name>",
    66  		Purpose: "Shows information about the current or specified model.",
    67  		Doc:     showModelCommandDoc,
    68  	}
    69  }
    70  
    71  // SetFlags implements Command.SetFlags.
    72  func (c *showModelCommand) SetFlags(f *gnuflag.FlagSet) {
    73  	c.ModelCommandBase.SetFlags(f)
    74  	c.out.AddFlags(f, "yaml", output.DefaultFormatters)
    75  }
    76  
    77  // Init implements Command.Init.
    78  func (c *showModelCommand) Init(args []string) error {
    79  	if len(args) > 0 {
    80  		c.SetModelName(args[0])
    81  		args = args[1:]
    82  	}
    83  	if err := c.ModelCommandBase.Init(args); err != nil {
    84  		return err
    85  	}
    86  	if c.ModelName() == "" {
    87  		defaultModel, err := modelcmd.GetCurrentModel(c.ClientStore())
    88  		if err != nil {
    89  			return err
    90  		}
    91  		c.SetModelName(defaultModel)
    92  	}
    93  	return nil
    94  }
    95  
    96  // Run implements Command.Run.
    97  func (c *showModelCommand) Run(ctx *cmd.Context) (err error) {
    98  	api, err := c.getAPI()
    99  	if err != nil {
   100  		return err
   101  	}
   102  	defer api.Close()
   103  
   104  	store := c.ClientStore()
   105  	modelDetails, err := store.ModelByName(
   106  		c.ControllerName(),
   107  		c.ModelName(),
   108  	)
   109  	if errors.IsNotFound(err) {
   110  		if err := c.RefreshModels(store, c.ControllerName()); err != nil {
   111  			return errors.Annotate(err, "refreshing models cache")
   112  		}
   113  		// Now try again.
   114  		modelDetails, err = store.ModelByName(
   115  			c.ControllerName(),
   116  			c.ModelName(),
   117  		)
   118  	}
   119  	if err != nil {
   120  		return errors.Annotate(err, "getting model details")
   121  	}
   122  
   123  	modelTag := names.NewModelTag(modelDetails.ModelUUID)
   124  	results, err := api.ModelInfo([]names.ModelTag{modelTag})
   125  	if err != nil {
   126  		return err
   127  	}
   128  	if results[0].Error != nil {
   129  		return results[0].Error
   130  	}
   131  	infoMap, err := c.apiModelInfoToModelInfoMap([]params.ModelInfo{*results[0].Result})
   132  	if err != nil {
   133  		return errors.Trace(err)
   134  	}
   135  	return c.out.Write(ctx, infoMap)
   136  }
   137  
   138  func (c *showModelCommand) apiModelInfoToModelInfoMap(modelInfo []params.ModelInfo) (map[string]common.ModelInfo, error) {
   139  	// TODO(perrito666) 2016-05-02 lp:1558657
   140  	now := time.Now()
   141  	output := make(map[string]common.ModelInfo)
   142  	for _, info := range modelInfo {
   143  		out, err := common.ModelInfoFromParams(info, now)
   144  		if err != nil {
   145  			return nil, errors.Trace(err)
   146  		}
   147  		out.ControllerName = c.ControllerName()
   148  		output[out.Name] = out
   149  	}
   150  	return output, nil
   151  }