Skip to content

Commit d987f4b

Browse files
committed
feat: provider generic annotations
Signed-off-by: Jan Jansen <[email protected]>
1 parent 23f8d40 commit d987f4b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+374
-79
lines changed

internal/testutils/mock_source.go

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"context"
2121
"time"
2222

23+
"sigs.k8s.io/external-dns/pkg/apis"
24+
2325
"github.com/stretchr/testify/mock"
2426

2527
"sigs.k8s.io/external-dns/endpoint"
@@ -58,3 +60,10 @@ func (m *MockSource) AddEventHandler(ctx context.Context, handler func()) {
5860
}
5961
}()
6062
}
63+
64+
func (b *MockSource) SetProviderSpecificConfig(_ apis.ProviderSpecificConfig) {
65+
}
66+
67+
func (b *MockSource) GetProviderSpecificAnnotations(_ map[string]string) (endpoint.ProviderSpecific, string) {
68+
return nil, ""
69+
}

main.go

+6
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,12 @@ func main() {
431431
os.Exit(0)
432432
}
433433

434+
ps, err := p.GetProviderSpecific(ctx)
435+
if err != nil {
436+
log.Fatal(err)
437+
}
438+
endpointsSource.SetProviderSpecificConfig(ps)
439+
434440
var r registry.Registry
435441
switch cfg.Registry {
436442
case "dynamodb":

pkg/apis/types.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package apis
18+
19+
type ProviderSpecificConfig struct {
20+
Translation map[string]string `json:"translation"`
21+
PrefixTranslation map[string]string `json:"prefixTranslation"`
22+
}

provider/aws/aws.go

+10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"strings"
2525
"time"
2626

27+
"sigs.k8s.io/external-dns/pkg/apis"
28+
2729
"github.com/aws/aws-sdk-go/aws"
2830
"github.com/aws/aws-sdk-go/aws/request"
2931
"github.com/aws/aws-sdk-go/service/route53"
@@ -293,6 +295,14 @@ func NewAWSProvider(awsConfig AWSConfig, client Route53API) (*AWSProvider, error
293295
return provider, nil
294296
}
295297

298+
func (p *AWSProvider) GetProviderSpecific(_ context.Context) (apis.ProviderSpecificConfig, error) {
299+
return apis.ProviderSpecificConfig{
300+
PrefixTranslation: map[string]string{
301+
"external-dns.alpha.kubernetes.io/aws-": "aws/",
302+
},
303+
}, nil
304+
}
305+
296306
// Zones returns the list of hosted zones.
297307
func (p *AWSProvider) Zones(ctx context.Context) (map[string]*route53.HostedZone, error) {
298308
if p.zonesCache.zones != nil && time.Since(p.zonesCache.age) < p.zonesCache.duration {

provider/cloudflare/cloudflare.go

+17-6
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ import (
2424
"strconv"
2525
"strings"
2626

27+
"sigs.k8s.io/external-dns/pkg/apis"
28+
2729
cloudflare "github.com/cloudflare/cloudflare-go"
2830
log "github.com/sirupsen/logrus"
2931

3032
"sigs.k8s.io/external-dns/endpoint"
3133
"sigs.k8s.io/external-dns/plan"
3234
"sigs.k8s.io/external-dns/provider"
33-
"sigs.k8s.io/external-dns/source"
3435
)
3536

3637
const (
@@ -42,6 +43,8 @@ const (
4243
cloudFlareUpdate = "UPDATE"
4344
// defaultCloudFlareRecordTTL 1 = automatic
4445
defaultCloudFlareRecordTTL = 1
46+
// The annotation used for determining if traffic will go through Cloudflare
47+
CloudflareProxiedKey = "external-dns.alpha.kubernetes.io/cloudflare-proxied"
4548
)
4649

4750
// We have to use pointers to bools now, as the upstream cloudflare-go library requires them
@@ -162,7 +165,7 @@ func getCreateDNSRecordParam(cfc cloudFlareChange) cloudflare.CreateDNSRecordPar
162165
}
163166

164167
// NewCloudFlareProvider initializes a new CloudFlare DNS based Provider.
165-
func NewCloudFlareProvider(domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, proxiedByDefault bool, dryRun bool, dnsRecordsPerPage int) (*CloudFlareProvider, error) {
168+
func NewCloudFlareProvider(domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, proxiedByDefault bool, dryRun bool, dnsRecordsPerPage int) (provider.Provider, error) {
166169
// initialize via chosen auth method and returns new API object
167170
var (
168171
config *cloudflare.API
@@ -196,6 +199,14 @@ func NewCloudFlareProvider(domainFilter endpoint.DomainFilter, zoneIDFilter prov
196199
return provider, nil
197200
}
198201

202+
func (p *CloudFlareProvider) GetProviderSpecific(_ context.Context) (apis.ProviderSpecificConfig, error) {
203+
return apis.ProviderSpecificConfig{
204+
Translation: map[string]string{
205+
CloudflareProxiedKey: CloudflareProxiedKey,
206+
},
207+
}, nil
208+
}
209+
199210
// Zones returns the list of hosted zones.
200211
func (p *CloudFlareProvider) Zones(ctx context.Context) ([]cloudflare.Zone, error) {
201212
result := []cloudflare.Zone{}
@@ -398,7 +409,7 @@ func (p *CloudFlareProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]
398409
if proxied {
399410
e.RecordTTL = 0
400411
}
401-
e.SetProviderSpecificProperty(source.CloudflareProxiedKey, strconv.FormatBool(proxied))
412+
e.SetProviderSpecificProperty(CloudflareProxiedKey, strconv.FormatBool(proxied))
402413

403414
adjustedEndpoints = append(adjustedEndpoints, e)
404415
}
@@ -487,10 +498,10 @@ func shouldBeProxied(endpoint *endpoint.Endpoint, proxiedByDefault bool) bool {
487498
proxied := proxiedByDefault
488499

489500
for _, v := range endpoint.ProviderSpecific {
490-
if v.Name == source.CloudflareProxiedKey {
501+
if v.Name == CloudflareProxiedKey {
491502
b, err := strconv.ParseBool(v.Value)
492503
if err != nil {
493-
log.Errorf("Failed to parse annotation [%s]: %v", source.CloudflareProxiedKey, err)
504+
log.Errorf("Failed to parse annotation [%s]: %v", CloudflareProxiedKey, err)
494505
} else {
495506
proxied = b
496507
}
@@ -535,7 +546,7 @@ func groupByNameAndType(records []cloudflare.DNSRecord) []*endpoint.Endpoint {
535546
records[0].Type,
536547
endpoint.TTL(records[0].TTL),
537548
targets...).
538-
WithProviderSpecific(source.CloudflareProxiedKey, strconv.FormatBool(*records[0].Proxied)),
549+
WithProviderSpecific(CloudflareProxiedKey, strconv.FormatBool(*records[0].Proxied)),
539550
)
540551
}
541552

provider/dyn/soap/services.go

+2-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

provider/google/google_test.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ func TestGoogleZonesVisibilityFilterPrivatePeering(t *testing.T) {
242242

243243
zones, err := provider.Zones(context.Background())
244244
require.NoError(t, err)
245-
245+
246246
validateZones(t, zones, map[string]*dns.ManagedZone{
247247
"svc-local": {Name: "svc-local", DnsName: "svc.local.", Id: 1005, Visibility: "private"},
248248
})
@@ -694,7 +694,6 @@ func newGoogleProviderZoneOverlap(t *testing.T, domainFilter endpoint.DomainFilt
694694
Visibility: "private",
695695
})
696696

697-
698697
createZone(t, provider, &dns.ManagedZone{
699698
Name: "svc-local",
700699
DnsName: "svc.local.",
@@ -703,13 +702,13 @@ func newGoogleProviderZoneOverlap(t *testing.T, domainFilter endpoint.DomainFilt
703702
})
704703

705704
createZone(t, provider, &dns.ManagedZone{
706-
Name: "svc-local-peer",
707-
DnsName: "svc.local.",
708-
Id: 10006,
709-
Visibility: "private",
705+
Name: "svc-local-peer",
706+
DnsName: "svc.local.",
707+
Id: 10006,
708+
Visibility: "private",
710709
PeeringConfig: &dns.ManagedZonePeeringConfig{TargetNetwork: nil},
711710
})
712-
711+
713712
provider.dryRun = dryRun
714713

715714
return provider

provider/ibmcloud/ibmcloud.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"strconv"
2525
"strings"
2626

27+
"sigs.k8s.io/external-dns/pkg/apis"
28+
2729
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/crn"
2830
"github.com/IBM/go-sdk-core/v5/core"
2931
"github.com/IBM/networking-go-sdk/dnsrecordsv1"
@@ -301,7 +303,7 @@ func (c *ibmcloudConfig) Validate(authenticator core.Authenticator, domainFilter
301303
// NewIBMCloudProvider creates a new IBMCloud provider.
302304
//
303305
// Returns the provider or an error if a provider could not be created.
304-
func NewIBMCloudProvider(configFile string, domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, source source.Source, proxiedByDefault bool, dryRun bool) (*IBMCloudProvider, error) {
306+
func NewIBMCloudProvider(configFile string, domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, source source.Source, proxiedByDefault bool, dryRun bool) (provider.Provider, error) {
305307
cfg, err := getConfig(configFile)
306308
if err != nil {
307309
return nil, err
@@ -335,6 +337,14 @@ func NewIBMCloudProvider(configFile string, domainFilter endpoint.DomainFilter,
335337
return provider, nil
336338
}
337339

340+
func (p *IBMCloudProvider) GetProviderSpecific(_ context.Context) (apis.ProviderSpecificConfig, error) {
341+
return apis.ProviderSpecificConfig{
342+
PrefixTranslation: map[string]string{
343+
"external-dns.alpha.kubernetes.io/ibmcloud-": "ibmcloud/",
344+
},
345+
}, nil
346+
}
347+
338348
// Records gets the current records.
339349
//
340350
// Returns the current records or an error if the operation failed.

provider/oci/cache_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ limitations under the License.
1717
package oci
1818

1919
import (
20-
"github.com/oracle/oci-go-sdk/v65/dns"
21-
"github.com/stretchr/testify/assert"
2220
"testing"
2321
"time"
22+
23+
"github.com/oracle/oci-go-sdk/v65/dns"
24+
"github.com/stretchr/testify/assert"
2425
)
2526

2627
func TestZoneCache(t *testing.T) {

provider/provider.go

+7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"net"
2323
"strings"
2424

25+
"sigs.k8s.io/external-dns/pkg/apis"
26+
2527
"sigs.k8s.io/external-dns/endpoint"
2628
"sigs.k8s.io/external-dns/plan"
2729
)
@@ -49,6 +51,7 @@ type Provider interface {
4951
// Endpoints. It is permitted to modify the supplied endpoints.
5052
AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoint.Endpoint, error)
5153
GetDomainFilter() endpoint.DomainFilter
54+
GetProviderSpecific(ctx context.Context) (apis.ProviderSpecificConfig, error)
5255
}
5356

5457
type BaseProvider struct{}
@@ -61,6 +64,10 @@ func (b BaseProvider) GetDomainFilter() endpoint.DomainFilter {
6164
return endpoint.DomainFilter{}
6265
}
6366

67+
func (b BaseProvider) GetProviderSpecific(_ context.Context) (apis.ProviderSpecificConfig, error) {
68+
return apis.ProviderSpecificConfig{}, nil
69+
}
70+
6471
type contextKey struct {
6572
name string
6673
}

provider/scaleway/scaleway.go

+10
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import (
2323
"strconv"
2424
"strings"
2525

26+
"sigs.k8s.io/external-dns/pkg/apis"
27+
2628
domain "github.com/scaleway/scaleway-sdk-go/api/domain/v2beta1"
2729
"github.com/scaleway/scaleway-sdk-go/scw"
2830
log "github.com/sirupsen/logrus"
@@ -104,6 +106,14 @@ func NewScalewayProvider(ctx context.Context, domainFilter endpoint.DomainFilter
104106
}, nil
105107
}
106108

109+
func (p *ScalewayProvider) GetProviderSpecific(_ context.Context) (apis.ProviderSpecificConfig, error) {
110+
return apis.ProviderSpecificConfig{
111+
PrefixTranslation: map[string]string{
112+
"external-dns.alpha.kubernetes.io/scw-": "scw/",
113+
},
114+
}, nil
115+
}
116+
107117
// AdjustEndpoints is used to normalize the endoints
108118
func (p *ScalewayProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoint.Endpoint, error) {
109119
eps := make([]*endpoint.Endpoint, len(endpoints))

provider/webhook/api/httpapi.go

+20
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,24 @@ func (p *WebhookServer) RecordsHandler(w http.ResponseWriter, req *http.Request)
7474
w.WriteHeader(http.StatusBadRequest)
7575
}
7676
}
77+
func (p *WebhookServer) ProvideSpecificHandler(w http.ResponseWriter, req *http.Request) {
78+
if req.Method != http.MethodGet {
79+
log.Errorf("Unsupported method %s", req.Method)
80+
w.WriteHeader(http.StatusBadRequest)
81+
}
82+
83+
records, err := p.Provider.GetProviderSpecific(context.Background())
84+
if err != nil {
85+
log.Errorf("Failed to get Provide-Specific: %v", err)
86+
w.WriteHeader(http.StatusInternalServerError)
87+
return
88+
}
89+
w.Header().Set(ContentTypeHeader, MediaTypeFormatAndVersion)
90+
w.WriteHeader(http.StatusOK)
91+
if err := json.NewEncoder(w).Encode(records); err != nil {
92+
log.Errorf("Failed to encode records: %v", err)
93+
}
94+
}
7795

7896
func (p *WebhookServer) AdjustEndpointsHandler(w http.ResponseWriter, req *http.Request) {
7997
if req.Method != http.MethodPost {
@@ -114,6 +132,7 @@ func (p *WebhookServer) NegotiateHandler(w http.ResponseWriter, req *http.Reques
114132
// - /records (GET): returns the current records
115133
// - /records (POST): applies the changes
116134
// - /adjustendpoints (POST): executes the AdjustEndpoints method
135+
// - /provider-specific (GET): init provider specific stuff
117136
func StartHTTPApi(provider provider.Provider, startedChan chan struct{}, readTimeout, writeTimeout time.Duration, providerPort string) {
118137
p := WebhookServer{
119138
Provider: provider,
@@ -123,6 +142,7 @@ func StartHTTPApi(provider provider.Provider, startedChan chan struct{}, readTim
123142
m.HandleFunc("/", p.NegotiateHandler)
124143
m.HandleFunc("/records", p.RecordsHandler)
125144
m.HandleFunc("/adjustendpoints", p.AdjustEndpointsHandler)
145+
m.HandleFunc("/provider-specific", p.ProvideSpecificHandler)
126146

127147
s := &http.Server{
128148
Addr: providerPort,

provider/webhook/api/httpapi_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727
"testing"
2828
"time"
2929

30+
"sigs.k8s.io/external-dns/pkg/apis"
31+
3032
"github.com/stretchr/testify/require"
3133
"sigs.k8s.io/external-dns/endpoint"
3234
"sigs.k8s.io/external-dns/plan"
@@ -39,6 +41,11 @@ type FakeWebhookProvider struct {
3941
domainFilter endpoint.DomainFilter
4042
}
4143

44+
func (p FakeWebhookProvider) GetProviderSpecific(ctx context.Context) (apis.ProviderSpecificConfig, error) {
45+
//TODO implement me
46+
panic("implement me")
47+
}
48+
4249
func (p FakeWebhookProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, error) {
4350
if p.err != nil {
4451
return nil, p.err

0 commit comments

Comments
 (0)