Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow configuration of invoke URL pattern via environment variables #1400

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions api/server/fn_annotator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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)

}
6 changes: 3 additions & 3 deletions api/server/fn_annotator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestAnnotateFnDefaultProvider(t *testing.T) {
}

// defaults the fn endpoint to the base URL if it's not already set
tep := NewRequestBasedFnAnnotator()
tep := NewRequestBasedFnAnnotator(DefaultInvokeGroup, DefaultInvokeTemplate)

c, _ := gin.CreateTestContext(httptest.NewRecorder())
c.Request = httptest.NewRequest("GET", "/v2/foo/bar", bytes2.NewBuffer([]byte{}))
Expand Down Expand Up @@ -67,7 +67,7 @@ func TestHttpsFn(t *testing.T) {
}

// defaults the Fn endpoint to the base URL if it's not already set
tep := NewRequestBasedFnAnnotator()
tep := NewRequestBasedFnAnnotator(DefaultInvokeGroup, DefaultInvokeTemplate)

c, _ := gin.CreateTestContext(httptest.NewRecorder())
c.Request = httptest.NewRequest("GET", "/v2/foo/bar", bytes2.NewBuffer([]byte{}))
Expand Down Expand Up @@ -97,7 +97,7 @@ func TestHttpsFn(t *testing.T) {
}

func TestStaticUrlFnAnnotator(t *testing.T) {
a := NewStaticURLFnAnnotator("http://foo.bar.com/somewhere")
a := NewStaticURLFnAnnotator("http://foo.bar.com/somewhere", DefaultInvokeGroup, DefaultInvokeTemplate)

app := &models.App{
ID: "app_id",
Expand Down
29 changes: 20 additions & 9 deletions api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -1159,17 +1171,16 @@ 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)
lbTriggerGroup.Any("/:app_name/*trigger_source", s.handleHTTPTriggerCall)
}

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)
}
}

Expand Down
2 changes: 1 addition & 1 deletion api/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func testServer(ds models.Datastore, mq models.MessageQueue, logDB models.LogSto
WithAgent(rnr),
WithType(nodeType),
WithTriggerAnnotator(NewRequestBasedTriggerAnnotator()),
WithFnAnnotator(NewRequestBasedFnAnnotator()),
WithFnAnnotator(NewRequestBasedFnAnnotator(DefaultInvokeGroup, DefaultInvokeTemplate)),
)...)
}

Expand Down
2 changes: 1 addition & 1 deletion test/fn-system-tests/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ func SetUpAPINode(ctx context.Context) (*server.Server, error) {
opts = append(opts, server.WithLogURL(""))
opts = append(opts, server.WithLogstoreFromDatastore())
opts = append(opts, server.WithTriggerAnnotator(server.NewStaticURLTriggerAnnotator(LBAddress)))
opts = append(opts, server.WithFnAnnotator(server.NewStaticURLFnAnnotator(LBAddress)))
opts = append(opts, server.WithFnAnnotator(server.NewStaticURLFnAnnotator(LBAddress, server.DefaultInvokeGroup, server.DefaultInvokeTemplate)))
opts = append(opts, server.EnableShutdownEndpoint(ctx, func() {})) // TODO: do it properly
return server.New(ctx, opts...), nil
}
Expand Down