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