Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ require (
github.com/go-logr/zapr v1.2.3
github.com/google/go-cmp v0.5.8
github.com/kevinburke/go-bindata v3.11.0+incompatible
github.com/openshift/api v0.0.0-20221010164355-920c3651ba3f
github.com/openshift/api v0.0.0-20230817133225-564be9ddb58e
github.com/openshift/client-go v0.0.0-20220831193253-4950ae70c8ea
github.com/openshift/library-go v0.0.0-20220920133651-093893cf326b
github.com/pkg/errors v0.9.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
github.com/openshift/api v0.0.0-20221010164355-920c3651ba3f h1:jatN0nxy0dLfzevDe1NMO2mcb0/PeWKMrI2kXpHgGns=
github.com/openshift/api v0.0.0-20221010164355-920c3651ba3f/go.mod h1:JRz+ZvTqu9u7t6suhhPTacbFl5K65Y6rJbNM7HjWA3g=
github.com/openshift/api v0.0.0-20230817133225-564be9ddb58e h1:Hbw58VzpO9SktwYwXhiiubgvGmNTNeK6mxGtjPQ0uy4=
github.com/openshift/api v0.0.0-20230817133225-564be9ddb58e/go.mod h1:aQ6LDasvHMvHZXqLHnX2GRmnfTWCF/iIwz8EMTTIE9A=
github.com/openshift/client-go v0.0.0-20220831193253-4950ae70c8ea h1:7JbjIzWt3Q75ErY1PAZ+gCA+bErI6HSlpffHFmMMzqM=
github.com/openshift/client-go v0.0.0-20220831193253-4950ae70c8ea/go.mod h1:+J8DqZC60acCdpYkwVy/KH4cudgWiFZRNOBeghCzdGA=
github.com/openshift/library-go v0.0.0-20220920133651-093893cf326b h1:LWwB7uN91G/JsMnZFd0+q6ZzAXlB4/oUOfpZWA585gw=
Expand Down
2,695 changes: 894 additions & 1,801 deletions manifests/00-custom-resource-definition.yaml

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion pkg/dns/aws/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
Expand Down Expand Up @@ -84,6 +85,10 @@ type Config struct {
// that is used by SDK to configure the credentials.
SharedCredentialFile string

// RoleARN is an optional ARN to use for the AWS client session that is
// intended to only provide access to another account's Route 53 service.
RoleARN string

// Region is the AWS region ELBs are created in.
Region string
// ServiceEndpoints is the list of AWS API endpoints to use for
Expand Down Expand Up @@ -137,6 +142,14 @@ func NewProvider(config Config, operatorReleaseVersion string) (*Provider, error
}
}

// When RoleARN is provided, make a copy of the Route 53 session and configure it to use RoleARN.
// RoleARN is intended to only provide access to another account's Route 53 service, not for ELBs.
sessRoute53 := sess
if config.RoleARN != "" {
sessRoute53 = sess.Copy()
sessRoute53.Config.WithCredentials(stscreds.NewCredentials(sessRoute53, config.RoleARN))
}

r53Config := aws.NewConfig()
// elb requires no special region treatment.
elbConfig := aws.NewConfig().WithRegion(region)
Expand Down Expand Up @@ -218,7 +231,7 @@ func NewProvider(config Config, operatorReleaseVersion string) (*Provider, error
// TODO: Add custom endpoint support for elbv2. See the following for details:
// https://docs.aws.amazon.com/general/latest/gr/elb.html
elbv2: elbv2.New(sess, aws.NewConfig().WithRegion(region)),
route53: route53.New(sess, r53Config),
route53: route53.New(sessRoute53, r53Config),
tags: tags,
config: config,
idsToTags: map[string]map[string]string{},
Expand Down
58 changes: 58 additions & 0 deletions pkg/dns/split/dns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package split

import (
"reflect"

iov1 "github.com/openshift/api/operatoringress/v1"
"github.com/openshift/cluster-ingress-operator/pkg/dns"
logf "github.com/openshift/cluster-ingress-operator/pkg/log"

configv1 "github.com/openshift/api/config/v1"
)

var (
_ dns.Provider = &Provider{}
log = logf.Logger.WithName("dns")
)

// Provider is a dns.Provider that wraps two other providers. The first
// provider is used for public hosted zones, and the second provider is used for
// private hosted zones.
type Provider struct {
private, public dns.Provider
privateZone *configv1.DNSZone
}

// NewProvider returns a new Provider that wraps the provided wrappers, using
// the first for the public zone and the second for the private zone.
func NewProvider(public, private dns.Provider, privateZone *configv1.DNSZone) *Provider {
return &Provider{
public: public,
private: private,
privateZone: privateZone,
}
}

// Ensure calls the Ensure method of one of the wrapped DNS providers.
func (p *Provider) Ensure(record *iov1.DNSRecord, zone configv1.DNSZone) error {
if reflect.DeepEqual(zone, *p.privateZone) {
return p.private.Ensure(record, zone)
}
return p.public.Ensure(record, zone)
}

// Delete calls the Delete method of one of the wrapped DNS providers.
func (p *Provider) Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error {
if reflect.DeepEqual(zone, *p.privateZone) {
return p.private.Delete(record, zone)
}
return p.public.Delete(record, zone)
}

// Replace calls the Replace method of one of the wrapped DNS providers.
func (p *Provider) Replace(record *iov1.DNSRecord, zone configv1.DNSZone) error {
if reflect.DeepEqual(zone, *p.privateZone) {
return p.private.Replace(record, zone)
}
return p.public.Replace(record, zone)
}
126 changes: 126 additions & 0 deletions pkg/dns/split/dns_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package split_test

import (
"testing"

"github.com/stretchr/testify/assert"

configv1 "github.com/openshift/api/config/v1"
iov1 "github.com/openshift/api/operatoringress/v1"

"github.com/openshift/cluster-ingress-operator/pkg/dns"
splitdns "github.com/openshift/cluster-ingress-operator/pkg/dns/split"
)

// TestSplitDNSProvider verifies that the split DNS provider dispatches to the
// public or private provider as appropriate for the DNS zone.
func TestSplitDNSProvider(t *testing.T) {
var (
// ch is a channel that is used in the fake public and private
// providers to record which one is called.
ch = make(chan string, 6)
// getResult reads and returns one item from ch, or returns the
// empty string if ch is empty.
getResult = func() string {
var result string
select {
case result = <-ch:
default:
}
return result
}
// publicProvider is a fake dns.Provider for the public zone.
publicProvider = newFakeProvider("public", ch)
// privateProvider is a fake dns.Provider for the private zone.
privateProvider = newFakeProvider("private", ch)
// publicZoneWithID is a public zone that is defined by ID.
publicZoneWithID = configv1.DNSZone{ID: "public_zone"}
// privateZoneWithID is a private zone that is defined by ID.
privateZoneWithID = configv1.DNSZone{ID: "private_zone"}
// publicZoneWithTags is a public zone that is defined by tags.
publicZoneWithTags = configv1.DNSZone{Tags: map[string]string{"zone": "public"}}
// privateZoneWithID is a private zone that is defined by tags.
privateZoneWithTags = configv1.DNSZone{Tags: map[string]string{"zone": "private"}}
)
testCases := []struct {
name string
publicZone configv1.DNSZone
privateZone configv1.DNSZone
publishToZone configv1.DNSZone
expect string
}{
{
name: "publish to public zone specified by id",
publicZone: publicZoneWithID,
privateZone: privateZoneWithID,
publishToZone: publicZoneWithID,
expect: "public",
},
{
name: "publish to private zone specified by id",
publicZone: publicZoneWithID,
privateZone: privateZoneWithID,
publishToZone: privateZoneWithID,
expect: "private",
},
{
name: "publish to public zone specified by tags",
publicZone: publicZoneWithTags,
privateZone: privateZoneWithID,
publishToZone: publicZoneWithTags,
expect: "public",
},
{
name: "publish to private zone specified by tags",
publicZone: publicZoneWithTags,
privateZone: privateZoneWithTags,
publishToZone: privateZoneWithTags,
expect: "private",
},
{
name: "publish to other zone should fall back to the public zone",
publicZone: publicZoneWithID,
privateZone: privateZoneWithID,
publishToZone: configv1.DNSZone{ID: "other_zone"},
expect: "public",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
provider := splitdns.NewProvider(publicProvider, privateProvider, &tc.privateZone)
assert.NoError(t, provider.Ensure(&iov1.DNSRecord{}, tc.publishToZone))
assert.Equal(t, tc.expect, getResult())
assert.NoError(t, provider.Replace(&iov1.DNSRecord{}, tc.publishToZone))
assert.Equal(t, tc.expect, getResult())
assert.NoError(t, provider.Delete(&iov1.DNSRecord{}, tc.publishToZone))
assert.Equal(t, tc.expect, getResult())
assert.Empty(t, ch)
})
}

}

var _ dns.Provider = &fakeProvider{}

type fakeProvider struct {
name string
recorder chan string
}

func (p *fakeProvider) Ensure(record *iov1.DNSRecord, zone configv1.DNSZone) error {
p.recorder <- p.name
return nil
}
func (p *fakeProvider) Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error {
p.recorder <- p.name
return nil
}
func (p *fakeProvider) Replace(record *iov1.DNSRecord, zone configv1.DNSZone) error {
p.recorder <- p.name
return nil
}

// newFakeProvider returns a new dns.Provider that records invocations.
func newFakeProvider(name string, ch chan string) dns.Provider {
return &fakeProvider{name, ch}
}
8 changes: 4 additions & 4 deletions pkg/manifests/bindata.go

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion pkg/operator/controller/dns/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
ibm "github.com/openshift/cluster-ingress-operator/pkg/dns/ibm"
ibmprivatedns "github.com/openshift/cluster-ingress-operator/pkg/dns/ibm/private"
ibmpublicdns "github.com/openshift/cluster-ingress-operator/pkg/dns/ibm/public"
splitdns "github.com/openshift/cluster-ingress-operator/pkg/dns/split"
logf "github.com/openshift/cluster-ingress-operator/pkg/log"
"github.com/openshift/cluster-ingress-operator/pkg/manifests"
"github.com/openshift/cluster-ingress-operator/pkg/operator/controller"
Expand Down Expand Up @@ -670,7 +671,21 @@ func (r *reconciler) createDNSProvider(dnsConfig *configv1.DNS, platformStatus *
if err != nil {
return nil, fmt.Errorf("failed to create AWS DNS manager: %v", err)
}
dnsProvider = provider
var roleARN string
if dnsConfig.Spec.Platform.AWS != nil {
roleARN = dnsConfig.Spec.Platform.AWS.PrivateZoneIAMRole
}
if roleARN != "" {
cfg := cfg
cfg.RoleARN = roleARN
privateProvider, err := awsdns.NewProvider(cfg, r.config.OperatorReleaseVersion)
if err != nil {
return nil, fmt.Errorf("failed to create AWS DNS manager for shared VPC: %v", err)
}
dnsProvider = splitdns.NewProvider(provider, privateProvider, dnsConfig.Spec.PrivateZone)
} else {
dnsProvider = provider
}
case configv1.AzurePlatformType:
environment := platformStatus.Azure.CloudName
if environment == "" {
Expand Down
Loading