()
| 231 | } |
| 232 | |
| 233 | func getCredentials() (*http.Client, string) { |
| 234 | getCredentialsOnce.Do(func() { |
| 235 | apiKeyEnv, ok := os.LookupEnv("TS_API_KEY") |
| 236 | oauthId, oiok := os.LookupEnv("TS_OAUTH_ID") |
| 237 | oauthSecret, osok := os.LookupEnv("TS_OAUTH_SECRET") |
| 238 | idToken, idok := os.LookupEnv("TS_ID_TOKEN") |
| 239 | |
| 240 | if !ok && (!oiok || (!osok && !idok)) { |
| 241 | log.Fatal("set envvar TS_API_KEY to your Tailscale API key, TS_OAUTH_ID and TS_OAUTH_SECRET to a Tailscale OAuth ID and Secret, or TS_OAUTH_ID and TS_ID_TOKEN to a Tailscale federated identity Client ID and OIDC identity token") |
| 242 | } |
| 243 | if apiKeyEnv != "" && (oauthId != "" || (oauthSecret != "" && idToken != "")) { |
| 244 | log.Fatal("set either the envvar TS_API_KEY, TS_OAUTH_ID and TS_OAUTH_SECRET, or TS_OAUTH_ID and TS_ID_TOKEN") |
| 245 | } |
| 246 | if oiok && ((oauthId != "" && !idok) || oauthSecret != "") { |
| 247 | // Both should ideally be set, but if either are non-empty it means the user had an intent |
| 248 | // to set _something_, so they should receive the oauth error flow. |
| 249 | oauthConfig := &clientcredentials.Config{ |
| 250 | ClientID: oauthId, |
| 251 | ClientSecret: oauthSecret, |
| 252 | TokenURL: fmt.Sprintf("https://%s/api/v2/oauth/token", *apiServer), |
| 253 | } |
| 254 | client = oauthConfig.Client(context.Background()) |
| 255 | } else if idok && idToken != "" && oiok && oauthId != "" { |
| 256 | if exchangeJWTForToken, ok := tailscale.HookExchangeJWTForTokenViaWIF.GetOk(); ok { |
| 257 | var err error |
| 258 | apiKeyEnv, err = exchangeJWTForToken(context.Background(), fmt.Sprintf("https://%s", *apiServer), oauthId, idToken) |
| 259 | if err != nil { |
| 260 | log.Fatal(err) |
| 261 | } |
| 262 | } |
| 263 | client = http.DefaultClient |
| 264 | } else { |
| 265 | client = http.DefaultClient |
| 266 | } |
| 267 | |
| 268 | apiKey = apiKeyEnv |
| 269 | }) |
| 270 | |
| 271 | return client, apiKey |
| 272 | } |
| 273 | |
| 274 | func sumFile(fname string) (string, error) { |
| 275 | data, err := os.ReadFile(fname) |
no test coverage detected
searching dependent graphs…