github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/api/modelgeneration/modelgeneration.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package modelgeneration 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 10 "github.com/juju/juju/api/base" 11 "github.com/juju/juju/apiserver/params" 12 ) 13 14 // Client provides methods that the Juju client command uses to interact 15 // with models stored in the Juju Server. 16 type Client struct { 17 base.ClientFacade 18 facade base.FacadeCaller 19 } 20 21 // NewClient creates a new `Client` based on an existing authenticated API 22 // connection. 23 func NewClient(st base.APICallCloser) *Client { 24 frontend, backend := base.NewClientFacade(st, "ModelGeneration") 25 return &Client{ClientFacade: frontend, facade: backend} 26 } 27 28 // AddGeneration adds a model generation to the config. 29 func (c *Client) AddGeneration(modelUUID string) error { 30 var result params.ErrorResult 31 err := c.facade.FacadeCall("AddGeneration", argForModel(modelUUID), &result) 32 if err != nil { 33 return errors.Trace(err) 34 } 35 if result.Error != nil { 36 return errors.Trace(result.Error) 37 } 38 return nil 39 } 40 41 // CancelGeneration cancels a model generation to the config. 42 func (c *Client) CancelGeneration(modelUUID string) error { 43 var result params.ErrorResult 44 err := c.facade.FacadeCall("CancelGeneration", argForModel(modelUUID), &result) 45 if err != nil { 46 return errors.Trace(err) 47 } 48 if result.Error != nil { 49 return errors.Trace(result.Error) 50 } 51 return nil 52 } 53 54 // AdvanceGeneration advances a unit and/or applications to the 'next' 55 // generation. The boolean return indicates whether the generation was 56 // automatically completed as a result of unit advancement. 57 func (c *Client) AdvanceGeneration(modelUUID string, entities []string) (bool, error) { 58 var result params.AdvanceGenerationResult 59 arg := params.AdvanceGenerationArg{Model: argForModel(modelUUID)} 60 if len(entities) == 0 { 61 return false, errors.Trace(errors.New("No units or applications to advance")) 62 } 63 for _, entity := range entities { 64 switch { 65 case names.IsValidApplication(entity): 66 arg.Entities = append(arg.Entities, 67 params.Entity{Tag: names.NewApplicationTag(entity).String()}) 68 case names.IsValidUnit(entity): 69 arg.Entities = append(arg.Entities, 70 params.Entity{Tag: names.NewUnitTag(entity).String()}) 71 default: 72 return false, errors.Trace(errors.New("Must be application or unit")) 73 } 74 } 75 err := c.facade.FacadeCall("AdvanceGeneration", arg, &result) 76 if err != nil { 77 return false, errors.Trace(err) 78 } 79 80 // If there were errors based on the advancing units, return those. 81 // Otherwise check the results of auto-completion. 82 if err := result.AdvanceResults.Combine(); err != nil { 83 return false, errors.Trace(err) 84 } 85 res := result.CompleteResult 86 if res.Error != nil { 87 return false, errors.Trace(res.Error) 88 } 89 return res.Result, nil 90 } 91 92 // HasNextGeneration returns true if the model has a "next" generation that 93 // has not yet been completed. 94 func (c *Client) HasNextGeneration(modelUUID string) (bool, error) { 95 var result params.BoolResult 96 err := c.facade.FacadeCall("HasNextGeneration", argForModel(modelUUID), &result) 97 if err != nil { 98 return false, errors.Trace(err) 99 } 100 if result.Error != nil { 101 return false, errors.Trace(result.Error) 102 } 103 return result.Result, nil 104 } 105 106 func argForModel(modelUUID string) params.Entity { 107 return params.Entity{Tag: names.NewModelTag(modelUUID).String()} 108 }