github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/runner/jujuc/status-get.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package jujuc
     5  
     6  import (
     7  	"github.com/juju/cmd"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/gnuflag"
    10  
    11  	jujucmd "github.com/juju/juju/cmd"
    12  	"github.com/juju/juju/core/status"
    13  )
    14  
    15  // StatusGetCommand implements the status-get command.
    16  type StatusGetCommand struct {
    17  	cmd.CommandBase
    18  	ctx             Context
    19  	includeData     bool
    20  	applicationWide bool
    21  	out             cmd.Output
    22  }
    23  
    24  func NewStatusGetCommand(ctx Context) (cmd.Command, error) {
    25  	return &StatusGetCommand{ctx: ctx}, nil
    26  }
    27  
    28  func (c *StatusGetCommand) Info() *cmd.Info {
    29  	doc := `
    30  By default, only the status value is printed.
    31  If the --include-data flag is passed, the associated data are printed also.
    32  `
    33  	return jujucmd.Info(&cmd.Info{
    34  		Name:    "status-get",
    35  		Args:    "[--include-data] [--application]",
    36  		Purpose: "print status information",
    37  		Doc:     doc,
    38  	})
    39  }
    40  
    41  func (c *StatusGetCommand) SetFlags(f *gnuflag.FlagSet) {
    42  	c.out.AddFlags(f, "smart", cmd.DefaultFormatters)
    43  	f.BoolVar(&c.includeData, "include-data", false, "print all status data")
    44  	f.BoolVar(&c.applicationWide, "application", false, "print status for all units of this application if this unit is the leader")
    45  }
    46  
    47  func (c *StatusGetCommand) Init(args []string) error {
    48  	return cmd.CheckEmpty(args)
    49  }
    50  
    51  // StatusInfo is a record of the status information for a application or a unit's workload.
    52  type StatusInfo struct {
    53  	Tag    string
    54  	Status string
    55  	Info   string
    56  	Data   map[string]interface{}
    57  }
    58  
    59  // ApplicationStatusInfo holds StatusInfo for an Application and all its Units.
    60  type ApplicationStatusInfo struct {
    61  	Application StatusInfo
    62  	Units       []StatusInfo
    63  }
    64  
    65  func toDetails(info StatusInfo, includeData bool) map[string]interface{} {
    66  	details := make(map[string]interface{})
    67  	details["status"] = info.Status
    68  	if includeData {
    69  		data := make(map[string]interface{})
    70  		for k, v := range info.Data {
    71  			data[k] = v
    72  		}
    73  		details["status-data"] = data
    74  		details["message"] = info.Info
    75  	}
    76  	return details
    77  }
    78  
    79  func (c *StatusGetCommand) ApplicationStatus(ctx *cmd.Context) error {
    80  	applicationStatus, err := c.ctx.ApplicationStatus()
    81  	if err != nil {
    82  		if errors.IsNotImplemented(err) {
    83  			return c.out.Write(ctx, status.Unknown)
    84  		}
    85  		return errors.Annotatef(err, "finding application status")
    86  	}
    87  	if !c.includeData && c.out.Name() == "smart" {
    88  		return c.out.Write(ctx, applicationStatus.Application.Status)
    89  	}
    90  	statusDetails := make(map[string]interface{})
    91  	details := toDetails(applicationStatus.Application, c.includeData)
    92  
    93  	units := make(map[string]interface{}, len(applicationStatus.Units))
    94  	for _, unit := range applicationStatus.Units {
    95  		units[unit.Tag] = toDetails(unit, c.includeData)
    96  	}
    97  	details["units"] = units
    98  	statusDetails["application-status"] = details
    99  	c.out.Write(ctx, statusDetails)
   100  
   101  	return nil
   102  
   103  }
   104  
   105  func (c *StatusGetCommand) unitOrApplicationStatus(ctx *cmd.Context) error {
   106  	var err error
   107  
   108  	if c.applicationWide {
   109  		return c.ApplicationStatus(ctx)
   110  	}
   111  
   112  	unitStatus, err := c.ctx.UnitStatus()
   113  	if err != nil {
   114  		if errors.IsNotImplemented(err) {
   115  			return c.out.Write(ctx, status.Unknown)
   116  		}
   117  		return errors.Annotatef(err, "finding workload status")
   118  	}
   119  	if !c.includeData && c.out.Name() == "smart" {
   120  		return c.out.Write(ctx, unitStatus.Status)
   121  	}
   122  	c.out.Write(ctx, toDetails(*unitStatus, c.includeData))
   123  	return nil
   124  }
   125  
   126  func (c *StatusGetCommand) Run(ctx *cmd.Context) error {
   127  	return c.unitOrApplicationStatus(ctx)
   128  }