github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/api/machineactions/machineactions.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Copyright 2016 Cloudbase Solutions
     3  // Licensed under the AGPLv3, see LICENCE file for details.
     4  
     5  // machineactions implements the the api side of
     6  // running actions on machines
     7  package machineactions
     8  
     9  import (
    10  	"github.com/juju/errors"
    11  	"github.com/juju/juju/api/base"
    12  	apiwatcher "github.com/juju/juju/api/watcher"
    13  	"github.com/juju/juju/apiserver/params"
    14  	"github.com/juju/juju/watcher"
    15  	"github.com/juju/names"
    16  )
    17  
    18  type Client struct {
    19  	facade base.FacadeCaller
    20  }
    21  
    22  func NewClient(caller base.APICaller) *Client {
    23  	return &Client{base.NewFacadeCaller(caller, "MachineActions")}
    24  }
    25  
    26  // WatchActionNotifications returns a StringsWatcher for observing the
    27  // IDs of Actions added to the Machine. The initial event will contain the
    28  // IDs of any Actions pending at the time the Watcher is made.
    29  func (c *Client) WatchActionNotifications(agent names.MachineTag) (watcher.StringsWatcher, error) {
    30  	var results params.StringsWatchResults
    31  	args := params.Entities{
    32  		Entities: []params.Entity{{Tag: agent.String()}},
    33  	}
    34  
    35  	err := c.facade.FacadeCall("WatchActionNotifications", args, &results)
    36  	if err != nil {
    37  		return nil, errors.Trace(err)
    38  	}
    39  
    40  	if len(results.Results) != 1 {
    41  		return nil, errors.Errorf("expected 1 result, got %d", len(results.Results))
    42  	}
    43  
    44  	result := results.Results[0]
    45  	if result.Error != nil {
    46  		return nil, errors.Trace(result.Error)
    47  	}
    48  	w := apiwatcher.NewStringsWatcher(c.facade.RawAPICaller(), result)
    49  	return w, nil
    50  }
    51  
    52  func (c *Client) getOneAction(tag names.ActionTag) (params.ActionResult, error) {
    53  	nothing := params.ActionResult{}
    54  
    55  	args := params.Entities{
    56  		Entities: []params.Entity{{Tag: tag.String()}},
    57  	}
    58  
    59  	var results params.ActionResults
    60  	err := c.facade.FacadeCall("Actions", args, &results)
    61  	if err != nil {
    62  		return nothing, errors.Trace(err)
    63  	}
    64  
    65  	if len(results.Results) > 1 {
    66  		return nothing, errors.Errorf("expected only 1 action query result, got %d", len(results.Results))
    67  	}
    68  
    69  	result := results.Results[0]
    70  	if result.Error != nil {
    71  		return nothing, errors.Trace(result.Error)
    72  	}
    73  
    74  	return result, nil
    75  }
    76  
    77  // Action returns the Action with the given tag.
    78  func (c *Client) Action(tag names.ActionTag) (*Action, error) {
    79  	result, err := c.getOneAction(tag)
    80  	if err != nil {
    81  		return nil, errors.Trace(err)
    82  	}
    83  	return &Action{
    84  		name:   result.Action.Name,
    85  		params: result.Action.Parameters,
    86  	}, nil
    87  }
    88  
    89  // ActionBegin marks an action as running.
    90  func (c *Client) ActionBegin(tag names.ActionTag) error {
    91  	var results params.ErrorResults
    92  
    93  	args := params.Entities{
    94  		Entities: []params.Entity{{Tag: tag.String()}},
    95  	}
    96  
    97  	err := c.facade.FacadeCall("BeginActions", args, &results)
    98  	if err != nil {
    99  		return errors.Trace(err)
   100  	}
   101  
   102  	return results.OneError()
   103  }
   104  
   105  // ActionFinish captures the structured output of an action.
   106  func (c *Client) ActionFinish(tag names.ActionTag, status string, actionResults map[string]interface{}, message string) error {
   107  	var results params.ErrorResults
   108  
   109  	args := params.ActionExecutionResults{
   110  		Results: []params.ActionExecutionResult{{
   111  			ActionTag: tag.String(),
   112  			Status:    status,
   113  			Results:   actionResults,
   114  			Message:   message,
   115  		}},
   116  	}
   117  
   118  	err := c.facade.FacadeCall("FinishActions", args, &results)
   119  	if err != nil {
   120  		return errors.Trace(err)
   121  	}
   122  
   123  	return results.OneError()
   124  }
   125  
   126  // RunningActions returns a list of actions running for the given machine tag.
   127  func (c *Client) RunningActions(agent names.MachineTag) ([]params.ActionResult, error) {
   128  	var results params.ActionsByReceivers
   129  
   130  	args := params.Entities{
   131  		Entities: []params.Entity{{Tag: agent.String()}},
   132  	}
   133  
   134  	err := c.facade.FacadeCall("RunningActions", args, &results)
   135  	if err != nil {
   136  		return nil, errors.Trace(err)
   137  	}
   138  
   139  	if len(results.Actions) != 1 {
   140  		return nil, errors.Errorf("expected 1 result, got %d", len(results.Actions))
   141  	}
   142  
   143  	result := results.Actions[0]
   144  	if result.Error != nil {
   145  		return nil, result.Error
   146  	}
   147  
   148  	return result.Actions, nil
   149  }