github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/api/undertaker/undertaker.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package undertaker 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 "github.com/juju/juju/status" 13 "github.com/juju/juju/watcher" 14 ) 15 16 // NewWatcherFunc exists to let us test Watch properly. 17 type NewWatcherFunc func(base.APICaller, params.NotifyWatchResult) watcher.NotifyWatcher 18 19 // Client provides access to the undertaker API 20 type Client struct { 21 modelTag names.ModelTag 22 caller base.FacadeCaller 23 newWatcher NewWatcherFunc 24 } 25 26 // NewClient creates a new client for accessing the undertaker API. 27 func NewClient(caller base.APICaller, newWatcher NewWatcherFunc) (*Client, error) { 28 modelTag, ok := caller.ModelTag() 29 if !ok { 30 return nil, errors.New("undertaker client is not appropriate for controller-only API") 31 } 32 return &Client{ 33 modelTag: modelTag, 34 caller: base.NewFacadeCaller(caller, "Undertaker"), 35 newWatcher: newWatcher, 36 }, nil 37 } 38 39 // ModelInfo returns information on the model needed by the undertaker worker. 40 func (c *Client) ModelInfo() (params.UndertakerModelInfoResult, error) { 41 result := params.UndertakerModelInfoResult{} 42 err := c.entityFacadeCall("ModelInfo", &result) 43 return result, errors.Trace(err) 44 } 45 46 // ProcessDyingModel checks if a dying model has any machines or services. 47 // If there are none, the model's life is changed from dying to dead. 48 func (c *Client) ProcessDyingModel() error { 49 return c.entityFacadeCall("ProcessDyingModel", nil) 50 } 51 52 // RemoveModel removes any records of this model from Juju. 53 func (c *Client) RemoveModel() error { 54 return c.entityFacadeCall("RemoveModel", nil) 55 } 56 57 // SetStatus sets the status of the model. 58 func (c *Client) SetStatus(status status.Status, message string, data map[string]interface{}) error { 59 args := params.SetStatus{ 60 Entities: []params.EntityStatusArgs{ 61 {c.modelTag.String(), status.String(), message, data}, 62 }, 63 } 64 var results params.ErrorResults 65 if err := c.caller.FacadeCall("SetStatus", args, &results); err != nil { 66 return errors.Trace(err) 67 } 68 if len(results.Results) != 1 { 69 return errors.Errorf("expected 1 result, got %d", len(results.Results)) 70 } 71 if results.Results[0].Error != nil { 72 return errors.Trace(results.Results[0].Error) 73 } 74 return nil 75 } 76 77 func (c *Client) entityFacadeCall(name string, results interface{}) error { 78 args := params.Entities{ 79 Entities: []params.Entity{{c.modelTag.String()}}, 80 } 81 return c.caller.FacadeCall(name, args, results) 82 } 83 84 // WatchModelResources starts a watcher for changes to the model's 85 // machines and services. 86 func (c *Client) WatchModelResources() (watcher.NotifyWatcher, error) { 87 var results params.NotifyWatchResults 88 err := c.entityFacadeCall("WatchModelResources", &results) 89 if err != nil { 90 return nil, err 91 } 92 93 if len(results.Results) != 1 { 94 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 95 } 96 result := results.Results[0] 97 if result.Error != nil { 98 return nil, result.Error 99 } 100 w := c.newWatcher(c.caller.RawAPICaller(), result) 101 return w, nil 102 }