github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/model/addgeneration.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package model
     5  
     6  import (
     7  	"github.com/juju/cmd"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/gnuflag"
    10  
    11  	"github.com/juju/juju/api/modelgeneration"
    12  	jujucmd "github.com/juju/juju/cmd"
    13  	"github.com/juju/juju/cmd/modelcmd"
    14  	"github.com/juju/juju/core/model"
    15  )
    16  
    17  const (
    18  	addGenerationSummary = "Adds a new generation to the model."
    19  	addGenerationDoc     = `
    20  Users need to be able to roll changes to applications in a safe guided 
    21  processes that controls the flow such that not all units of an HA application 
    22  are hit at once. This also allows some manual canary testing and provides 
    23  control over the flow of changes out to the model. 
    24  
    25  Examples:
    26      juju add-generation
    27  
    28  See also:
    29      advance-generation
    30      cancel-generation
    31      switch-generation
    32  `
    33  )
    34  
    35  // NewAddGenerationCommand wraps addGenerationCommand with sane model settings.
    36  func NewAddGenerationCommand() cmd.Command {
    37  	return modelcmd.Wrap(&addGenerationCommand{})
    38  }
    39  
    40  // addGenerationCommand is the simplified command for accessing and setting
    41  // attributes related to adding model generations.
    42  type addGenerationCommand struct {
    43  	modelcmd.ModelCommandBase
    44  
    45  	api AddGenerationCommandAPI
    46  }
    47  
    48  // AddGenerationCommandAPI defines an API interface to be used during testing.
    49  //go:generate mockgen -package mocks -destination ./mocks/addgeneration_mock.go github.com/juju/juju/cmd/juju/model AddGenerationCommandAPI
    50  type AddGenerationCommandAPI interface {
    51  	Close() error
    52  	AddGeneration(string) error
    53  }
    54  
    55  // Info implements part of the cmd.Command interface.
    56  func (c *addGenerationCommand) Info() *cmd.Info {
    57  	info := &cmd.Info{
    58  		Name:    "add-generation",
    59  		Purpose: addGenerationSummary,
    60  		Doc:     addGenerationDoc,
    61  	}
    62  	return jujucmd.Info(info)
    63  }
    64  
    65  // SetFlags implements part of the cmd.Command interface.
    66  func (c *addGenerationCommand) SetFlags(f *gnuflag.FlagSet) {
    67  	c.ModelCommandBase.SetFlags(f)
    68  }
    69  
    70  // Init implements part of the cmd.Command interface.
    71  func (c *addGenerationCommand) Init(args []string) error {
    72  	if len(args) != 0 {
    73  		return errors.Errorf("No arguments allowed")
    74  	}
    75  	return nil
    76  }
    77  
    78  // getAPI returns the API. This allows passing in a test AddGenerationCommandAPI
    79  // implementation.
    80  func (c *addGenerationCommand) getAPI() (AddGenerationCommandAPI, error) {
    81  	if c.api != nil {
    82  		return c.api, nil
    83  	}
    84  	api, err := c.NewAPIRoot()
    85  	if err != nil {
    86  		return nil, errors.Annotate(err, "opening API connection")
    87  	}
    88  	client := modelgeneration.NewClient(api)
    89  	return client, nil
    90  }
    91  
    92  // Run implements the meaty part of the cmd.Command interface.
    93  func (c *addGenerationCommand) Run(ctx *cmd.Context) error {
    94  	client, err := c.getAPI()
    95  	if err != nil {
    96  		return err
    97  	}
    98  	defer client.Close()
    99  
   100  	_, modelDetails, err := c.ModelCommandBase.ModelDetails()
   101  	if err != nil {
   102  		return errors.Annotate(err, "getting model details")
   103  	}
   104  
   105  	if err = client.AddGeneration(modelDetails.ModelUUID); err != nil {
   106  		return err
   107  	}
   108  
   109  	// Now update the model store with the 'next' generation for this
   110  	// model.
   111  	if err = c.SetModelGeneration(model.GenerationNext); err != nil {
   112  		return err
   113  	}
   114  
   115  	ctx.Stdout.Write([]byte("target generation set to next\n"))
   116  	return nil
   117  }