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

     1  // Copyright 2018 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/gnuflag"
     9  
    10  	jujucmd "github.com/juju/juju/cmd"
    11  	"github.com/juju/juju/cmd/juju/common"
    12  	"github.com/juju/juju/core/application"
    13  )
    14  
    15  // GoalStateCommand implements the config-get command.
    16  type GoalStateCommand struct {
    17  	cmd.CommandBase
    18  	ctx Context
    19  	out cmd.Output
    20  }
    21  
    22  func NewGoalStateCommand(ctx Context) (cmd.Command, error) {
    23  	return &GoalStateCommand{ctx: ctx}, nil
    24  }
    25  
    26  func (c *GoalStateCommand) Info() *cmd.Info {
    27  	doc := `
    28  'goal-state' command will list the charm units and relations, specifying their status and their relations to other units in different charms.
    29  `
    30  	return jujucmd.Info(&cmd.Info{
    31  		Name:    "goal-state",
    32  		Purpose: "print the status of the charm's peers and related units",
    33  		Doc:     doc,
    34  	})
    35  }
    36  
    37  func (c *GoalStateCommand) SetFlags(f *gnuflag.FlagSet) {
    38  	c.out.AddFlags(f, "yaml", map[string]cmd.Formatter{
    39  		"yaml": cmd.FormatYaml,
    40  		"json": cmd.FormatJson})
    41  }
    42  
    43  func (c *GoalStateCommand) Init(args []string) error {
    44  	return cmd.CheckEmpty(args[:])
    45  }
    46  
    47  func (c *GoalStateCommand) Run(ctx *cmd.Context) error {
    48  	goalState, err := c.ctx.GoalState()
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	goalStateFormated := formatGoalState(*goalState)
    54  	return c.out.Write(ctx, goalStateFormated)
    55  }
    56  
    57  // goalStateStatusContents is used to format application.GoalState.Since
    58  // using strings.
    59  type goalStateStatusContents struct {
    60  	Status string `json:"status" yaml:"status"`
    61  	Since  string `json:"since,omitempty" yaml:"since,omitempty"`
    62  }
    63  
    64  // unitsGoalStateContents keeps the collection of units and their GoalStateStatus.
    65  type unitsGoalStateContents map[string]goalStateStatusContents
    66  
    67  // formattedGoalState is responsible to organize the Units and Relations with a specific
    68  // unit, and transmit this information from the facade to the worker.
    69  type formattedGoalState struct {
    70  	Units     unitsGoalStateContents            `json:"units" yaml:"units"`
    71  	Relations map[string]unitsGoalStateContents `json:"relations" yaml:"relations"`
    72  }
    73  
    74  // formatGoalState moves information from application GoalState struct to
    75  // application GoalState struct.
    76  func formatGoalState(gs application.GoalState) formattedGoalState {
    77  	result := formattedGoalState{}
    78  
    79  	copyUnits := func(units application.UnitsGoalState) unitsGoalStateContents {
    80  		copiedUnits := unitsGoalStateContents{}
    81  		for name, gs := range units {
    82  			copiedUnits[name] = goalStateStatusContents{
    83  				Status: gs.Status,
    84  				Since:  common.FormatTime(gs.Since, true),
    85  			}
    86  		}
    87  		return copiedUnits
    88  	}
    89  
    90  	result.Units = copyUnits(gs.Units)
    91  	result.Relations = make(map[string]unitsGoalStateContents, len(gs.Relations))
    92  	for relation, units := range gs.Relations {
    93  		result.Relations[relation] = copyUnits(units)
    94  	}
    95  
    96  	return result
    97  }