feat(clouddns): API to 0.258.0 with deprecations (#7787)

This commit is contained in:
Ville Vesilehto
2025-12-23 21:47:59 +02:00
committed by GitHub
parent d37f7f7754
commit 4f0368f8bf
5 changed files with 86 additions and 15 deletions

View File

@@ -35,8 +35,10 @@ clouddns [ZONE:PROJECT_ID:HOSTED_ZONE_NAME...] {
* `credentials` is used for reading the credential file from **FILENAME** (normally a .json file).
This field is optional. If this field is not provided then authentication will be done automatically,
e.g., through environmental variable `GOOGLE_APPLICATION_CREDENTIALS`. Please see
Google Cloud's [authentication method](https://cloud.google.com/docs/authentication) for more details.
e.g., through environmental variable `GOOGLE_APPLICATION_CREDENTIALS`. Note that CoreDNS validates that the given
file has a valid credentials type, but does not validate the credentials file for malicious input. Please see
Google Cloud's [authentication method](https://cloud.google.com/docs/authentication) and
[validating credential configurations from external sources](https://docs.cloud.google.com/docs/authentication/client-libraries#external-credentials) for more details.
* `fallthrough` If zone matches and no record can be generated, pass request to the next plugin.
If **[ZONES...]** is omitted, then fallthrough happens for all zones for which the plugin is

View File

@@ -2,6 +2,9 @@ package clouddns
import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"github.com/coredns/caddy"
@@ -67,7 +70,11 @@ func setup(c *caddy.Controller) error {
c.RemainingArgs()
case "credentials":
if c.NextArg() {
opt = option.WithCredentialsFile(c.Val())
credType, err := getCredType(c.Val())
if err != nil {
return plugin.Error("clouddns", c.Errf("invalid credentials file %q: %v", c.Val(), err))
}
opt = option.WithAuthCredentialsFile(credType, c.Val())
} else {
return plugin.Error("clouddns", c.ArgErr())
}
@@ -106,3 +113,30 @@ func setup(c *caddy.Controller) error {
return nil
}
func getCredType(filename string) (option.CredentialsType, error) {
data, err := os.ReadFile(filename)
if err != nil {
return "", err
}
var f struct {
Type string `json:"type"`
}
if err := json.Unmarshal(data, &f); err != nil {
return "", err
}
if f.Type == "" {
return "", fmt.Errorf("missing `type` field in credential")
}
// Check against allowed types
ct := option.CredentialsType(f.Type)
switch ct {
case option.ServiceAccount,
option.AuthorizedUser,
option.ImpersonatedServiceAccount,
option.ExternalAccount:
return ct, nil
}
return "", fmt.Errorf("unknown credential type: %s", f.Type)
}

View File

@@ -2,6 +2,9 @@ package clouddns
import (
"context"
"fmt"
"os"
"path/filepath"
"testing"
"github.com/coredns/caddy"
@@ -14,6 +17,26 @@ func TestSetupCloudDNS(t *testing.T) {
return fakeGCPClient{}, nil
}
validCreds := filepath.Join(t.TempDir(), "valid_creds.json")
if err := os.WriteFile(validCreds, []byte(`{"type": "service_account"}`), 0644); err != nil {
t.Fatalf("Failed to create valid creds: %v", err)
}
invalidTypeCreds := filepath.Join(t.TempDir(), "invalid_type_creds.json")
if err := os.WriteFile(invalidTypeCreds, []byte(`{"type": "bad_type"}`), 0644); err != nil {
t.Fatalf("Failed to create invalid creds: %v", err)
}
emptyCreds := filepath.Join(t.TempDir(), "empty_creds.json")
if err := os.WriteFile(emptyCreds, []byte(`{}`), 0644); err != nil {
t.Fatalf("Failed to create empty creds: %v", err)
}
invalidJSONCreds := filepath.Join(t.TempDir(), "invalid_json_creds.json")
if err := os.WriteFile(invalidJSONCreds, []byte(`{`), 0644); err != nil {
t.Fatalf("Failed to create invalid JSON creds: %v", err)
}
tests := []struct {
body string
expectedError bool
@@ -38,6 +61,18 @@ func TestSetupCloudDNS(t *testing.T) {
{`clouddns example.org {
}`, true},
{fmt.Sprintf(`clouddns example.org.:example-project:zone-name {
credentials %s
}`, validCreds), false},
{fmt.Sprintf(`clouddns example.org.:example-project:zone-name {
credentials %s
}`, invalidTypeCreds), true},
{fmt.Sprintf(`clouddns example.org.:example-project:zone-name {
credentials %s
}`, emptyCreds), true},
{fmt.Sprintf(`clouddns example.org.:example-project:zone-name {
credentials %s
}`, invalidJSONCreds), true},
}
for _, test := range tests {