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