-
Notifications
You must be signed in to change notification settings - Fork 29
NLB-7285: Add dataplane_api_key as an optional #1012
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,6 +2,7 @@ package main | |||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "context" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "encoding/base64" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "flag" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "io" | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -21,7 +22,10 @@ var ( | |||||||||||||||||||||||||||||||||||||||||||||||||
| version string | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const connTimeoutInSecs = 10 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const ( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| connTimeoutInSecs = 10 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| maxHeaders = 100 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| func main() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| flag.Parse() | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -63,7 +67,7 @@ func main() { | |||||||||||||||||||||||||||||||||||||||||||||||||
| os.Exit(10) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| httpClient := &http.Client{Timeout: connTimeoutInSecs * time.Second} | ||||||||||||||||||||||||||||||||||||||||||||||||||
| httpClient := NewHTTPClient(commonConfig) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| nginxClient, err := nginx.NewNginxClient(commonConfig.APIEndpoint, nginx.WithHTTPClient(httpClient)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| log.Printf("Couldn't create NGINX client: %v", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -189,3 +193,57 @@ func getStreamUpstreamServerAddresses(server []nginx.StreamUpstreamServer) []str | |||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return streamUpstreamServerAddr | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| // headerTransport wraps an http.RoundTripper and adds custom headers to all requests. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| type headerTransport struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| headers http.Header | ||||||||||||||||||||||||||||||||||||||||||||||||||
| transport http.RoundTripper | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| func (t *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| clonedReq := req.Clone(req.Context()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| for key, values := range t.headers { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, value := range values { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| clonedReq.Header.Add(key, value) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(clonedReq.Header) > maxHeaders { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, fmt.Errorf("number of headers in request exceeds the maximum allowed (%d)", maxHeaders) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+203
to
+214
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's nice to have these sanity checks at the top of function to conserve CPU. If we have too many headers, we've wasted some time cloning and adding. I think we can tweak the condition and prevent some doomed allocations. Something like (untested):
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| resp, err := t.transport.RoundTrip(clonedReq) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, fmt.Errorf("headerTransport RoundTrip failed: %w", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return resp, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| func NewHTTPClient(cfg *commonConfig) *http.Client { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| headers := NewHeaders(cfg) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| baseTransport := &http.Transport{} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return &http.Client{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Transport: &headerTransport{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| headers: headers, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| transport: baseTransport, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Timeout: connTimeoutInSecs * time.Second, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+224
to
+235
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't want to add a performance penalty if a customer is not using As written, all requests are going to jump through Maybe something like (untested):
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| func NewHeaders(cfg *commonConfig) http.Header { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| headers := http.Header{} | ||||||||||||||||||||||||||||||||||||||||||||||||||
| headers.Set("Content-Type", "application/json") | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if cfg.DataplaneAPIKey != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| authValue := "ApiKey " + base64.StdEncoding.EncodeToString([]byte(cfg.DataplaneAPIKey)) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| headers.Set("Authorization", authValue) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| log.Printf("[optional] DataplaneAPIKey not configured") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+244
to
+246
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this log message doesn't seem that useful
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return headers | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alternate design idea:
What if instead of
dataplane_api_keywe kept it very generic, likeadditional_headers?So for NGINXaaS integration the user would add:
That'd keep the open source codebase very decoupled from our cloud offering, but put a little more work onto the user to get the headers right.
What do y'all think?