From 6690cb837476028a6991e5ab704f57fb0ec19e95 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Mon, 11 Feb 2019 15:26:15 +0000 Subject: [PATCH] Allow configuration of invoke URL pattern via environment variables --- api/server/fn_annotator.go | 28 +++++++++++++++------------- api/server/server.go | 29 ++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/api/server/fn_annotator.go b/api/server/fn_annotator.go index 479e3278f5..d4076f15f7 100644 --- a/api/server/fn_annotator.go +++ b/api/server/fn_annotator.go @@ -8,22 +8,24 @@ import ( "github.com/gin-gonic/gin" ) -//FnAnnotator Is used to inject trigger context (such as request URLs) into outbound trigger resources +//FnAnnotator Is used to inject fn context (such as request URLs) into outbound fn resources type FnAnnotator interface { // Annotates a trigger on read AnnotateFn(ctx *gin.Context, a *models.App, fn *models.Fn) (*models.Fn, error) } -type requestBasedFnAnnotator struct{} +type requestBasedFnAnnotator struct { + group, template string +} -func annotateFnWithBaseURL(baseURL string, app *models.App, fn *models.Fn) (*models.Fn, error) { +func annotateFnWithBaseURL(baseURL, group, template string, app *models.App, fn *models.Fn) (*models.Fn, error) { baseURL = strings.TrimSuffix(baseURL, "/") - src := strings.TrimPrefix(fn.ID, "/") - triggerPath := fmt.Sprintf("%s/invoke/%s", baseURL, src) + path := strings.Replace(template, ":fn_id", fn.ID, -1) + invokePath := fmt.Sprintf("%s%s%s", baseURL, group, path) newT := fn.Clone() - newAnnotations, err := newT.Annotations.With(models.FnInvokeEndpointAnnotation, triggerPath) + newAnnotations, err := newT.Annotations.With(models.FnInvokeEndpointAnnotation, invokePath) if err != nil { return nil, err } @@ -39,25 +41,25 @@ func (tp *requestBasedFnAnnotator) AnnotateFn(ctx *gin.Context, app *models.App, scheme = "https" } - return annotateFnWithBaseURL(fmt.Sprintf("%s://%s", scheme, ctx.Request.Host), app, t) + return annotateFnWithBaseURL(fmt.Sprintf("%s://%s", scheme, ctx.Request.Host), tp.group, tp.template, app, t) } //NewRequestBasedFnAnnotator creates a FnAnnotator that inspects the incoming request host and port, and uses this to generate fn invoke endpoint URLs based on those -func NewRequestBasedFnAnnotator() FnAnnotator { - return &requestBasedFnAnnotator{} +func NewRequestBasedFnAnnotator(group, template string) FnAnnotator { + return &requestBasedFnAnnotator{group: group, template: template} } type staticURLFnAnnotator struct { - baseURL string + baseURL, group, template string } //NewStaticURLFnAnnotator annotates triggers bases on a given, specified URL base - e.g. "https://my.domain" ---> "https://my.domain/t/app/source" -func NewStaticURLFnAnnotator(baseURL string) FnAnnotator { +func NewStaticURLFnAnnotator(baseURL, group, template string) FnAnnotator { - return &staticURLFnAnnotator{baseURL: baseURL} + return &staticURLFnAnnotator{baseURL: baseURL, group: group, template: template} } func (s *staticURLFnAnnotator) AnnotateFn(ctx *gin.Context, app *models.App, trigger *models.Fn) (*models.Fn, error) { - return annotateFnWithBaseURL(s.baseURL, app, trigger) + return annotateFnWithBaseURL(s.baseURL, s.group, s.template, app, trigger) } diff --git a/api/server/server.go b/api/server/server.go index 175fd359d0..05d9220912 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -119,6 +119,18 @@ const ( // EnvMaxRequestSize sets the limit in bytes for any API request's length. EnvMaxRequestSize = "FN_MAX_REQUEST_SIZE" + // EnvInvokeGroup sets the API group for the invoke endpoint + EnvInvokeGroup = "FN_INVOKE_GROUP" + + // EnvInvokeTemplate sets the API path for the invoke endpoing + EnvInvokeTemplate = "FN_INVOKE_PATH" + + // DefaultInvokeGroup is "/invoke" + DefaultInvokeGroup = "/invoke" + + // DefaultInvokeTemplate is "/:fn_id" + DefaultInvokeTemplate = "/:fn_id" + // DefaultLogFormat is text DefaultLogFormat = "text" @@ -266,14 +278,16 @@ func NewFromEnv(ctx context.Context, opts ...Option) *Server { opts = append(opts, LimitRequestBody(int64(getEnvInt(EnvMaxRequestSize, 0)))) + invokeGroup := getEnv(EnvInvokeGroup, DefaultInvokeGroup) + invokeTemplate := getEnv(EnvInvokeTemplate, DefaultInvokeTemplate) publicLBURL := getEnv(EnvPublicLoadBalancerURL, "") if publicLBURL != "" { logrus.Infof("using LB Base URL: '%s'", publicLBURL) opts = append(opts, WithTriggerAnnotator(NewStaticURLTriggerAnnotator(publicLBURL))) - opts = append(opts, WithFnAnnotator(NewStaticURLFnAnnotator(publicLBURL))) + opts = append(opts, WithFnAnnotator(NewStaticURLFnAnnotator(publicLBURL, invokeGroup, invokeTemplate))) } else { opts = append(opts, WithTriggerAnnotator(NewRequestBasedTriggerAnnotator())) - opts = append(opts, WithFnAnnotator(NewRequestBasedFnAnnotator())) + opts = append(opts, WithFnAnnotator(NewRequestBasedFnAnnotator(invokeGroup, invokeTemplate))) } // Agent handling depends on node type and several other options so it must be the last processed option. @@ -1105,9 +1119,7 @@ func (s *Server) bindHandlers(ctx context.Context) { profilerSetup(admin, "/debug") // Pure runners don't have any route, they have grpc - switch s.nodeType { - - case ServerTypeFull, ServerTypeAPI: + if s.nodeType == ServerTypeFull || s.nodeType == ServerTypeAPI { cleanv2 := engine.Group("/v2") v2 := cleanv2.Group("") v2.Use(s.apiMiddlewareWrapper()) @@ -1159,8 +1171,7 @@ func (s *Server) bindHandlers(ctx context.Context) { } } - switch s.nodeType { - case ServerTypeFull, ServerTypeLB, ServerTypeRunner: + if s.nodeType == ServerTypeFull || s.nodeType == ServerTypeLB || s.nodeType == ServerTypeRunner { if !s.noHTTTPTriggerEndpoint { lbTriggerGroup := engine.Group("/t") lbTriggerGroup.Any("/:app_name", s.handleHTTPTriggerCall) @@ -1168,8 +1179,8 @@ func (s *Server) bindHandlers(ctx context.Context) { } if !s.noFnInvokeEndpoint { - lbFnInvokeGroup := engine.Group("/invoke") - lbFnInvokeGroup.POST("/:fn_id", s.handleFnInvokeCall) + lbFnInvokeGroup := engine.Group(getEnv(EnvInvokeGroup, DefaultInvokeGroup)) + lbFnInvokeGroup.POST(getEnv(EnvInvokeTemplate, DefaultInvokeTemplate), s.handleFnInvokeCall) } }