github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/resource/resourceadapters/apiserver.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package resourceadapters
     5  
     6  import (
     7  	"net/http"
     8  
     9  	"github.com/juju/errors"
    10  	"gopkg.in/juju/names.v2"
    11  
    12  	"github.com/juju/juju/apiserver/common"
    13  	"github.com/juju/juju/apiserver/common/apihttp"
    14  	"github.com/juju/juju/apiserver/facade"
    15  	"github.com/juju/juju/resource"
    16  	internalserver "github.com/juju/juju/resource/api/private/server"
    17  	"github.com/juju/juju/resource/api/server"
    18  	corestate "github.com/juju/juju/state"
    19  )
    20  
    21  // NewPublicFacade provides the public API facade for resources. It is
    22  // passed into common.RegisterStandardFacade.
    23  func NewPublicFacade(st *corestate.State, _ facade.Resources, authorizer facade.Authorizer) (*server.Facade, error) {
    24  	if !authorizer.AuthClient() {
    25  		return nil, common.ErrPerm
    26  	}
    27  
    28  	rst, err := st.Resources()
    29  	if err != nil {
    30  		return nil, errors.Trace(err)
    31  	}
    32  	newClient := func() (server.CharmStore, error) {
    33  		return newCharmStoreClient(st)
    34  	}
    35  	facade, err := server.NewFacade(rst, newClient)
    36  	if err != nil {
    37  		return nil, errors.Trace(err)
    38  	}
    39  	return facade, nil
    40  }
    41  
    42  // NewUploadHandler returns a new HTTP handler for the given args.
    43  func NewUploadHandler(args apihttp.NewHandlerArgs) http.Handler {
    44  	return server.NewLegacyHTTPHandler(
    45  		func(req *http.Request) (server.DataStore, names.Tag, error) {
    46  			st, entity, err := args.Connect(req)
    47  			if err != nil {
    48  				return nil, nil, errors.Trace(err)
    49  			}
    50  			resources, err := st.Resources()
    51  			if err != nil {
    52  				return nil, nil, errors.Trace(err)
    53  			}
    54  
    55  			return resources, entity.Tag(), nil
    56  		},
    57  	)
    58  }
    59  
    60  // NewDownloadHandler returns a new HTTP handler for the given args.
    61  func NewDownloadHandler(args apihttp.NewHandlerArgs) http.Handler {
    62  	extractor := &httpDownloadRequestExtractor{
    63  		connect: args.Connect,
    64  	}
    65  	deps := internalserver.NewLegacyHTTPHandlerDeps(extractor)
    66  	return internalserver.NewLegacyHTTPHandler(deps)
    67  }
    68  
    69  // stateConnector exposes ways to connect to Juju's state.
    70  type stateConnector interface {
    71  	// Connect connects to state for a unit agent.
    72  }
    73  
    74  // httpDownloadRequestExtractor provides the functionality needed to
    75  // handle a resource download HTTP request.
    76  type httpDownloadRequestExtractor struct {
    77  	connect func(*http.Request) (*corestate.State, corestate.Entity, error)
    78  }
    79  
    80  // NewResourceOpener returns a new resource.Opener for the given
    81  // HTTP request.
    82  func (ex *httpDownloadRequestExtractor) NewResourceOpener(req *http.Request) (resource.Opener, error) {
    83  	st, ent, err := ex.connect(req)
    84  	if err != nil {
    85  		return nil, errors.Trace(err)
    86  	}
    87  	unit, ok := ent.(*corestate.Unit)
    88  	if !ok {
    89  		logger.Errorf("unexpected type: %T", ent)
    90  		return nil, errors.Errorf("unexpected type: %T", ent)
    91  	}
    92  
    93  	resources, err := st.Resources()
    94  	if err != nil {
    95  		return nil, errors.Trace(err)
    96  	}
    97  
    98  	opener := &resourceOpener{
    99  		st:     st,
   100  		res:    resources,
   101  		userID: unit.Tag(),
   102  		unit:   unit,
   103  	}
   104  	return opener, nil
   105  }