-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for AWS shared VPC in another account
Add support for configuring DNS records in AWS Route 53 using a separate account for the private hosted zone. This commit resolves NE-1294. https://issues.redhat.com/browse/NE-1294 * pkg/dns/aws/dns.go (Config): Add a RoleARN field. (NewProvider): If config.RoleARN is set, use it to configure the AWS client using the specified role. * pkg/dns/split/dns.go: New file. Define a DNS provider implementation that wraps two other DNS providers, using one of them to publish records to the public zone and the other to publish records to the private zone. (Provider): New type. Store the private and public DNS providers, as well as the private zone so that the Ensure, Delete, and Replace methods can use it to determine whether they are publishing to the public zone or to the private zone. (NewProvider): New function. Return a split DNS provider. (Ensure, Delete, Replace): New methods. Implement the dns.Provider interface by calling the respective methods on the wrapped private and public DNS providers. * pkg/dns/split/dns_test.go (TestSplitDNSProvider): Verify that the split DNS provider correctly dispatches to the private or public DNS provider as appropriate, using fakeProvider. (fakeProvider): New type. Define a fake named DNS provider that records its name when invoked. (Ensure, Delete, Replace): New methods for fakeProvider to record invocations and implement the dns.Provider interface. (newFakeProvider): New function. Return a fake provider. * pkg/operator/controller/dns/controller.go (Config): Add "PrivateHostedZoneAWSEnabled" field to indicate whether the "PrivateHostedZoneAWS" feature gate is enabled. (createDNSProvider): Use the new split DNS provider and the AWS DNS provider's new RoleARN configuration option to configure separate DNS providers for public and private zones when a role ARN for the private zone is specified in the cluster infrastructure config if the "PrivateHostedZoneAWS" feature gate is enabled. * pkg/operator/operator.go (New): Check the "PrivateHostedZoneAWS" feature gate and specify it in the DNS controller config.
- Loading branch information
Showing
5 changed files
with
214 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters