github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/payload/api/private/server/unitfacade.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package server
     5  
     6  // TODO(ericsnow) Eliminate the params import if possible.
     7  
     8  import (
     9  	"github.com/juju/errors"
    10  
    11  	"github.com/juju/juju/apiserver/params"
    12  	"github.com/juju/juju/payload"
    13  	"github.com/juju/juju/payload/api"
    14  	internal "github.com/juju/juju/payload/api/private"
    15  )
    16  
    17  // UnitPayloads exposes the State functionality for a unit's payloads.
    18  type UnitPayloads interface {
    19  	// Track tracks a payload for the unit and info.
    20  	Track(info payload.Payload) error
    21  	// List returns information on the payload with the id on the unit.
    22  	List(ids ...string) ([]payload.Result, error)
    23  	// Settatus sets the status for the payload with the given id on the unit.
    24  	SetStatus(id, status string) error
    25  	// LookUp returns the payload ID for the given name/rawID pair.
    26  	LookUp(name, rawID string) (string, error)
    27  	// Untrack removes the information for the payload with the given id.
    28  	Untrack(id string) error
    29  }
    30  
    31  // UnitFacade serves payload-specific API methods.
    32  type UnitFacade struct {
    33  	// State exposes the payload aspect of Juju's state.
    34  	State UnitPayloads
    35  }
    36  
    37  // NewUnitFacade builds a new facade for the given State.
    38  func NewUnitFacade(st UnitPayloads) *UnitFacade {
    39  	return &UnitFacade{State: st}
    40  }
    41  
    42  // Track stores a payload to be tracked in state.
    43  func (uf UnitFacade) Track(args internal.TrackArgs) (internal.PayloadResults, error) {
    44  	logger.Debugf("tracking %d payloads from API", len(args.Payloads))
    45  
    46  	var r internal.PayloadResults
    47  	for _, apiPayload := range args.Payloads {
    48  		pl, err := api.API2Payload(apiPayload)
    49  		if err != nil {
    50  			return r, errors.Trace(err)
    51  		}
    52  		logger.Debugf("tracking payload from API: %#v", pl)
    53  
    54  		id, err := uf.track(pl.Payload)
    55  		res := internal.NewPayloadResult(id, err)
    56  		r.Results = append(r.Results, res)
    57  	}
    58  	return r, nil
    59  }
    60  
    61  func (uf UnitFacade) track(pl payload.Payload) (string, error) {
    62  	if err := uf.State.Track(pl); err != nil {
    63  		return "", errors.Trace(err)
    64  	}
    65  	id, err := uf.State.LookUp(pl.Name, pl.ID)
    66  	if err != nil {
    67  		return "", errors.Trace(err)
    68  	}
    69  	return id, nil
    70  }
    71  
    72  // List builds the list of payload being tracked for
    73  // the given unit and IDs. If no IDs are provided then all tracked
    74  // payloads for the unit are returned.
    75  func (uf UnitFacade) List(args params.Entities) (internal.PayloadResults, error) {
    76  	if len(args.Entities) == 0 {
    77  		return uf.listAll()
    78  	}
    79  
    80  	var ids []string
    81  	for _, entity := range args.Entities {
    82  		id, err := internal.API2ID(entity.Tag)
    83  		if err != nil {
    84  			return internal.PayloadResults{}, errors.Trace(err)
    85  		}
    86  		ids = append(ids, id)
    87  	}
    88  
    89  	results, err := uf.State.List(ids...)
    90  	if err != nil {
    91  		return internal.PayloadResults{}, errors.Trace(err)
    92  	}
    93  
    94  	var r internal.PayloadResults
    95  	for _, result := range results {
    96  		res := internal.Result2api(result)
    97  		r.Results = append(r.Results, res)
    98  	}
    99  	return r, nil
   100  }
   101  
   102  func (uf UnitFacade) listAll() (internal.PayloadResults, error) {
   103  	var r internal.PayloadResults
   104  
   105  	results, err := uf.State.List()
   106  	if err != nil {
   107  		return r, errors.Trace(err)
   108  	}
   109  
   110  	for _, result := range results {
   111  		pl := result.Payload
   112  		id, err := uf.State.LookUp(pl.Name, pl.ID)
   113  		if err != nil {
   114  			logger.Errorf("failed to look up ID for %q: %v", pl.FullID(), err)
   115  			id = ""
   116  		}
   117  		apipl := api.Payload2api(*pl)
   118  
   119  		res := internal.NewPayloadResult(id, nil)
   120  		res.Payload = &apipl
   121  		r.Results = append(r.Results, res)
   122  	}
   123  	return r, nil
   124  }
   125  
   126  // LookUp identifies the payload with the provided name and raw ID.
   127  func (uf UnitFacade) LookUp(args internal.LookUpArgs) (internal.PayloadResults, error) {
   128  	var r internal.PayloadResults
   129  	for _, arg := range args.Args {
   130  		id, err := uf.State.LookUp(arg.Name, arg.ID)
   131  		res := internal.NewPayloadResult(id, err)
   132  		r.Results = append(r.Results, res)
   133  	}
   134  	return r, nil
   135  }
   136  
   137  // SetStatus sets the raw status of a payload.
   138  func (uf UnitFacade) SetStatus(args internal.SetStatusArgs) (internal.PayloadResults, error) {
   139  	var r internal.PayloadResults
   140  	for _, arg := range args.Args {
   141  		id, err := internal.API2ID(arg.Tag)
   142  		if err != nil {
   143  			return r, errors.Trace(err)
   144  		}
   145  
   146  		err = uf.State.SetStatus(id, arg.Status)
   147  		res := internal.NewPayloadResult(id, err)
   148  		r.Results = append(r.Results, res)
   149  	}
   150  	return r, nil
   151  }
   152  
   153  // Untrack marks the identified payload as no longer being tracked.
   154  func (uf UnitFacade) Untrack(args params.Entities) (internal.PayloadResults, error) {
   155  	var r internal.PayloadResults
   156  	for _, entity := range args.Entities {
   157  		id, err := internal.API2ID(entity.Tag)
   158  		if err != nil {
   159  			return r, errors.Trace(err)
   160  		}
   161  
   162  		err = uf.State.Untrack(id)
   163  		res := internal.NewPayloadResult(id, err)
   164  		r.Results = append(r.Results, res)
   165  	}
   166  	return r, nil
   167  }