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

8
go.mod
View File

@@ -40,7 +40,7 @@ require (
go.uber.org/automaxprocs v1.6.0 go.uber.org/automaxprocs v1.6.0
golang.org/x/crypto v0.46.0 golang.org/x/crypto v0.46.0
golang.org/x/sys v0.39.0 golang.org/x/sys v0.39.0
google.golang.org/api v0.257.0 google.golang.org/api v0.258.0
google.golang.org/grpc v1.77.0 google.golang.org/grpc v1.77.0
google.golang.org/protobuf v1.36.11 google.golang.org/protobuf v1.36.11
k8s.io/api v0.34.3 k8s.io/api v0.34.3
@@ -50,7 +50,7 @@ require (
sigs.k8s.io/mcs-api v0.3.0 sigs.k8s.io/mcs-api v0.3.0
) )
require golang.org/x/net v0.47.0 require golang.org/x/net v0.48.0
require ( require (
cloud.google.com/go/auth v0.17.0 // indirect cloud.google.com/go/auth v0.17.0 // indirect
@@ -182,7 +182,7 @@ require (
go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
golang.org/x/mod v0.30.0 // indirect golang.org/x/mod v0.30.0 // indirect
golang.org/x/oauth2 v0.33.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sync v0.19.0 // indirect golang.org/x/sync v0.19.0 // indirect
golang.org/x/term v0.38.0 // indirect golang.org/x/term v0.38.0 // indirect
golang.org/x/text v0.32.0 // indirect golang.org/x/text v0.32.0 // indirect
@@ -190,7 +190,7 @@ require (
golang.org/x/tools v0.39.0 // indirect golang.org/x/tools v0.39.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect

16
go.sum
View File

@@ -481,10 +481,10 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -553,16 +553,16 @@ golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSm
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/api v0.257.0 h1:8Y0lzvHlZps53PEaw+G29SsQIkuKrumGWs9puiexNAA= google.golang.org/api v0.258.0 h1:IKo1j5FBlN74fe5isA2PVozN3Y5pwNKriEgAXPOkDAc=
google.golang.org/api v0.257.0/go.mod h1:4eJrr+vbVaZSqs7vovFd1Jb/A6ml6iw2e6FBYf3GAO4= google.golang.org/api v0.258.0/go.mod h1:qhOMTQEZ6lUps63ZNq9jhODswwjkjYYguA7fA3TBFww=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4=
google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 h1:Wgl1rcDNThT+Zn47YyCXOXyX/COgMTIdhJ717F0l4xk= google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=

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). * `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, 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 e.g., through environmental variable `GOOGLE_APPLICATION_CREDENTIALS`. Note that CoreDNS validates that the given
Google Cloud's [authentication method](https://cloud.google.com/docs/authentication) for more details. 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. * `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 If **[ZONES...]** is omitted, then fallthrough happens for all zones for which the plugin is

View File

@@ -2,6 +2,9 @@ package clouddns
import ( import (
"context" "context"
"encoding/json"
"fmt"
"os"
"strings" "strings"
"github.com/coredns/caddy" "github.com/coredns/caddy"
@@ -67,7 +70,11 @@ func setup(c *caddy.Controller) error {
c.RemainingArgs() c.RemainingArgs()
case "credentials": case "credentials":
if c.NextArg() { 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 { } else {
return plugin.Error("clouddns", c.ArgErr()) return plugin.Error("clouddns", c.ArgErr())
} }
@@ -106,3 +113,30 @@ func setup(c *caddy.Controller) error {
return nil 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 ( import (
"context" "context"
"fmt"
"os"
"path/filepath"
"testing" "testing"
"github.com/coredns/caddy" "github.com/coredns/caddy"
@@ -14,6 +17,26 @@ func TestSetupCloudDNS(t *testing.T) {
return fakeGCPClient{}, nil 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 { tests := []struct {
body string body string
expectedError bool expectedError bool
@@ -38,6 +61,18 @@ func TestSetupCloudDNS(t *testing.T) {
{`clouddns example.org { {`clouddns example.org {
}`, true}, }`, 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 { for _, test := range tests {