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 }