1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

Enable ADC for Gcloud provider (#1583)

Fallback to using Application Default Credentials if no
private_key is available in the creds.json-file.

This allows usage with various short lived credentials, for example
GCE-instances, gcloud auth application-default login, OIDC Workload
Identity etc

Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
This commit is contained in:
Markus Enander
2022-07-05 21:53:51 +02:00
committed by GitHub
parent 053bd5adf6
commit 0f04639891
2 changed files with 42 additions and 14 deletions

View File

@ -9,10 +9,12 @@ jsId: GCLOUD
## Configuration ## Configuration
To use this provider, add an entry to `creds.json` with `TYPE` set to `GCLOUD` To use this provider, add an entry to `creds.json` with `TYPE` set to `GCLOUD`.
along with Google Cloud authentication values.
The provider requires a "Service Account Key" for your project. Newlines in the private key need to be replaced with `\n`. Copy the full JSON object into your `creds.json` like so: For authentication you can either include a Service Account Key in the file or use Application Default Credentials (ADC)
### Using a Service Account Key
Copy the full JSON object into your `creds.json`. Newlines in the private key need to be replaced with `\n`.
Example: Example:
@ -41,6 +43,22 @@ Example:
See [the Activation section](#activation) for some tips on obtaining these credentials. See [the Activation section](#activation) for some tips on obtaining these credentials.
### Using Application Default Credentials
If you prefer to authenticate using ADC you only need to specify `project_id` in your creds.json file.
Example:
```json
{
"gcloud": {
"TYPE": "GCLOUD",
"project_id": "mydnsproject"
}
}
```
**Note:** To use ADC, make sure to not add any `private_key` value to your configuration as that will prevent dnscontrol from attempting to use ADC.
## Metadata ## Metadata
This provider does not recognize any special metadata fields unique to google cloud dns. This provider does not recognize any special metadata fields unique to google cloud dns.

View File

@ -4,11 +4,13 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/StackExchange/dnscontrol/v3/pkg/printer"
"log" "log"
"net/http"
"strings" "strings"
"time" "time"
"github.com/StackExchange/dnscontrol/v3/pkg/printer"
"google.golang.org/api/googleapi" "google.golang.org/api/googleapi"
"google.golang.org/api/option" "google.golang.org/api/option"
@ -66,19 +68,27 @@ func New(cfg map[string]string, metadata json.RawMessage) (providers.DNSServiceP
// the key as downloaded is json encoded with literal "\n" instead of newlines. // the key as downloaded is json encoded with literal "\n" instead of newlines.
// in some cases (round-tripping through env vars) this tends to get messed up. // in some cases (round-tripping through env vars) this tends to get messed up.
// fix it if we find that. // fix it if we find that.
ctx := context.Background()
var hc *http.Client
if key, ok := cfg["private_key"]; ok { if key, ok := cfg["private_key"]; ok {
cfg["private_key"] = strings.Replace(key, "\\n", "\n", -1) cfg["private_key"] = strings.Replace(key, "\\n", "\n", -1)
raw, err := json.Marshal(cfg)
if err != nil {
return nil, err
}
config, err := gauth.JWTConfigFromJSON(raw, "https://www.googleapis.com/auth/ndev.clouddns.readwrite")
if err != nil {
return nil, err
}
hc = config.Client(ctx)
} else {
var err error
hc, err = gauth.DefaultClient(ctx, "https://www.googleapis.com/auth/ndev.clouddns.readwrite")
if err != nil {
return nil, fmt.Errorf("No creds.json private_key found and ADC failed with:\n%s", err)
}
} }
raw, err := json.Marshal(cfg)
if err != nil {
return nil, err
}
config, err := gauth.JWTConfigFromJSON(raw, "https://www.googleapis.com/auth/ndev.clouddns.readwrite")
if err != nil {
return nil, err
}
ctx := context.Background()
hc := config.Client(ctx)
// FIXME(tlim): Is it a problem that ctx is included with hc and in // FIXME(tlim): Is it a problem that ctx is included with hc and in
// the call to NewService? Seems redundant. // the call to NewService? Seems redundant.
dcli, err := gdns.NewService(ctx, option.WithHTTPClient(hc)) dcli, err := gdns.NewService(ctx, option.WithHTTPClient(hc))