|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Kubernetes secrets, base64, and newline" |
| 4 | +date: 2022-11-17 00:48:38 +00:00 |
| 5 | +comments: true |
| 6 | +categories: |
| 7 | +--- |
| 8 | + |
| 9 | +When creating a k8s secret manually, using command like this you need to provide `base64` encoded secret. Never forget to use `-w 0` when encoding the string. |
| 10 | + |
| 11 | +``` |
| 12 | +kubectl apply -f - <<EOF |
| 13 | +apiVersion: v1 |
| 14 | +kind: Secret |
| 15 | +metadata: |
| 16 | + name: github |
| 17 | +type: Opaque |
| 18 | +data: |
| 19 | + access_token: ACCESS_TOKEN |
| 20 | +EOF |
| 21 | +``` |
| 22 | + |
| 23 | +Recently I forgot the `-w 0` in `base64` command and spent too much time troubleshooting it. It seems to be a common issue: |
| 24 | +https://superuser.com/questions/1225134/why-does-the-base64-of-a-string-contain-n |
| 25 | + |
| 26 | +Yes, I logged the access token from the app to validate it. I used `%v` qualifier to do it and access token was the last argument. Looking back I should have used `%q` instead or have it in the middle of the log string. But I didn't. So I resolved it a hard way. |
| 27 | + |
| 28 | +I ended up logging the headers of http requests. Here is how I did it. |
| 29 | + |
| 30 | +First, implement the logging round tripper: |
| 31 | + |
| 32 | +``` |
| 33 | +// This type implements the http.RoundTripper interface |
| 34 | +type LoggingRoundTripper struct { |
| 35 | + Proxy http.RoundTripper |
| 36 | +} |
| 37 | +
|
| 38 | +func (lrt LoggingRoundTripper) RoundTrip(req *http.Request) (res *http.Response, e error) { |
| 39 | + fmt.Printf("Sending request to: %v\n", req.URL) |
| 40 | + fmt.Printf("With headers: %+v\n", req.Header) |
| 41 | +
|
| 42 | + return lrt.Proxy.RoundTrip(req) |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +Then use the http client configured with the above round tripper with `oauth2` client: |
| 47 | + |
| 48 | +``` |
| 49 | +// Use the custom HTTP client when requesting a token. |
| 50 | +httpClient := &http.Client{ |
| 51 | + Transport: LoggingRoundTripper{http.DefaultTransport}, |
| 52 | +} |
| 53 | +
|
| 54 | +ctx := context.Background() |
| 55 | +
|
| 56 | +ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient) |
| 57 | +
|
| 58 | +ts := oauth2.StaticTokenSource( |
| 59 | + &oauth2.Token{AccessToken: access_token}, |
| 60 | +) |
| 61 | +tc := oauth2.NewClient(ctx, ts) |
| 62 | +
|
| 63 | +client := github.NewClient(tc) |
| 64 | +``` |
| 65 | + |
| 66 | +Interestingly, the fact that this is working may not be aligned with the documentation: https://pkg.go.dev/golang.org/x/oauth2#NewClient. Docs says: |
| 67 | + |
| 68 | +> Note that if a custom *http.Client is provided via the Context it is used only for token acquisition and is not used to configure the *http.Client returned from NewClient. |
| 69 | +
|
| 70 | +Apparently it is already reported: https://github.com/golang/oauth2/issues/324. Maybe this post will be irrelevant soon. But it is working now. |
0 commit comments