-
Notifications
You must be signed in to change notification settings - Fork 584
config/v1: add public and private zones to DNSSpec #202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
config/v1: add public and private zones to DNSSpec #202
Conversation
|
|
||
| // DNSZone is used to define a DNS hosted zone. | ||
| // A zone can be identified by an ID or tags. | ||
| type DNSZone struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So is this meant to be a platform specific, opaque struct that will be able to address the zone on any supported platform? Will ID+Tags cover all those or do we need a union type that allows for a more strongly typed config object per supported platform?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will ID+Tags
ID or Tags, I don't think you need both...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ID should cover it. @openshift/sig-network-edge WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either should work for us. What's more convenient for the user? Are we going to respond to updates to this config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is an ID string AWS-specific or cross-platform? Will other providers need additional information to discover/update the zones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think an unique identifier or set of tags should be enough to find the zone across platforms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... it seems like this value becomes an opaque platform-specific value that would require the consumer to use the Infrastructure.Status.Platform to infer how to decode...
Are we supporting cross-platform DNS providers (e.g. an AWS cluster with Route 53 for internal DNS and... some other DNS provider for the public zone)? I think AWS load balancers may require Route 53? If we aren't worried about per-platform zone entries, then we can get the platform information from the infrastructure config.
While a string might be sufficient for all platforms, using:
type DNSZone struct {
ID *string `json:"id"`
}gives us room to add more properties if we end up needing them later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While a string might be sufficient for all platforms, using:
type DNSZone struct { ID *string `json:"id"` }gives us room to add more properties if we end up needing them later.
The installer currently cannot use ID for the pricate r53 zone as it is created by the terraform.. so id is not known when DNS object is created. We certainly know the tags that will exist on that private zone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... so id is not known when
DNSobject is created...
Ah, that makes sense. I guess the ingress operator could perform the tag -> ID lookup in its first round and then push its own update to the config to get more efficient lookups later, if we're concerned about API quotas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we need an ID for the public zone and tags for the private zone? If so it seems like AWS implies details leaking into this API, but maybe I'm misunderstanding?
If tags are sufficient to address the private zone, should the be sufficient to address the public zone?
| // | ||
| // For example, given the base domain `openshift.example.com`, an API server | ||
| // DNS record may be created for `cluster-api.openshift.example.com`. | ||
| BaseDomain string `json:"baseDomain"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the zone info, ingress operator doesn't even need this field... and if it's immutable, it could be on status? I can't remember who else might consume this field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the zone info, ingress operator doesn't even need this field...
👍 Let's drop it in favor of a Domain property, which everyone adds their own special subdomains to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 Let's drop it in favor of a
Domainproperty...
Oh, @ironcladlou was saying you could pull this from the cloud too. I'm a bit more nervous about it DNSSpec being portable between platform without it, but we can always add it back if we hit a platform that needs it.
config/v1/types_dns.go
Outdated
| PublicZone *DNSZone `json:"publicZone,omitempty"` | ||
| // privateZone is the location where all the DNS records that are only available internally | ||
| // to the cluster exist. | ||
| PrivateZone DNSZone `json:"privateZone"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Public vs. private can come out of the AWS API (e.g. here). Can we just have a slice of zone IDs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the configuration should be specifying, go create public records here and private records here. not the other way around...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the configuration should be specifying, go create public records here and private records here. not the other way around...
Are you concerned that sometimes this information would not be available from the AWS API? Or are you concerned about the ingress operator getting the check wrong and accidentally pushing private records to a public zone? I don't see why bugs on this front would be more likely in ingress code than in installer code.
On the other hand, I don't see a need for multiple public or private zones either, so having separate properties isn't a big change. If the ingress operator wants to structure it's handler in a loop and we get separate entries here, it can use []*DNSZone{&spec.PrivateZone, spec.PublicZone} with a guard for nil inside the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to be infrastructure independent for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be a pointer too (or use a zone slice), so we have a way to tell ingress not to worry about DNS in the libvirt/BYOI cases?
| // id is the identifier that can be used to find the DNS hosted zone. | ||
| // +optional | ||
| ID *string `json:"id"` | ||
| // tags can be used to query the DNS hosted zone. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tags is dangerous, that's not going to be identical across platforms. What is this actually capturing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this isn't truly platform independent you need to make this specific to the platform, or make the details opaque (i.e. have a string defined as opaque that no one except the person who wrote it is allowed to read).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The installer currently cannot use ID to define the private r53 zone as it is created by the private zone is created by terraform.. so ID is not known when DNS object is created by installer. We certainly know the tags that will exist on that private zone.
Therefore DNSZone has ID and Tags, where one of them is going to be set to find the zone.
And I thought finding a resource using ID or Tags is something all platforms support?
AWS ID: id Tags: tags
Azure ID: name
GCP ID: name/id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the docs for a human setting this would have to explain it, then it should probably be multiple fields which cannot all be set together (union type) like AWSID, AWSTags, AzureName, GCPName etc.
We intend for end users to set this? What happens when a human changes this? Which operator(s) react and make it valid? If we think that this is set once at install time, and we don't envision a human changing (now, a human could override it maybe later) then status may be more appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... like
AWSID,AWSTags,AzureName,GCPNameetc.
If "ID strings" are a cross-platform concept (and they are, right?), then I don't see a need for platform-specific versions of ID property. Same for tags, although from @abhinavdahiya's comment above it sounds like tags may not be cross-platform, with some platforms supporting tags and some supporting creator supplied names.
We intend for end users to set this?
I don't see a problem with users setting tags, but I don't think users will need that functionality either. And while it's theoretically possible to suck Route 53 zone creation up into the asset graph so we could fill in the ID here, that would break the current, useful separation between "create all the assets locally" and "push them up to the target cloud" that BYOH and similar rely on (I think?).
What happens when a human changes this? Which operator(s) react and make it valid?
I don't think this is different from the ID. In both cases, the ingress operator is pulling fresh values from the config and using them to look up the zones under management.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when a human changes this? Which operator(s) react and make it valid?
I don't think this is different from the ID. In both cases, the ingress operator is pulling fresh values from the config and using them to look up the zones under management.
The operator can use a watch on the config object to react when ID or Tags changes in the config object, but it would be trickier to detect changes when an administrator modifies tags on the hosted zones—AFAICT, that would involve polling. If the operator is supposed to react to this sort of configuration change, then using ID will make the implementation more reactive and less burdensome in terms of AWS API requests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So treating ID and Tags as the basis of a platform-agnostic union type seems to cover all of the providers mentioned so far. Is the fear that we'll discover another case later that doesn't fit the model, forcing us to walk it back into platform-specific types anyway? What other concerns are there with ID+Tags?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should move with ID/Tags for now. since it can cover most cloud platforms with programmable DNS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add slightly more godoc here capturing this discussion and how it should be used.
config/v1/types_dns.go
Outdated
| type DNSZone struct { | ||
| // id is the identifier that can be used to find the DNS hosted zone. | ||
| // +optional | ||
| ID *string `json:"id"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be ID string if default value empty means "not set". Pointer strings are only for special cases where empty string means something (and is usually a bad api design anyway because it's hard to reason about).
| // the internet exist. | ||
| // If this field is nil, no public records should be created. | ||
| // +optional | ||
| PublicZone *DNSZone `json:"publicZone,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this allowed to be changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically no.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically no.
Why not? "I don't want public DNS anymore" and "actually, I want it back" seem like reasonable admin decisions, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically no.
Why not? "I don't want public DNS anymore" and "actually, I want it back" seem like reasonable admin decisions, right?
Oh Yeah, true
647c0b2 to
7bce3ad
Compare
|
Provided comments on |
config/v1/types_dns.go
Outdated
| } | ||
|
|
||
| // DNSZone is used to define a DNS hosted zone. | ||
| // A zone is be identified by an ID or tags. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "is" -> "can"
a535f47 to
0e38866
Compare
config/v1/types_dns.go
Outdated
| // A zone can be identified by an ID or tags. | ||
| // | ||
| // For example, | ||
| // on AWS zone can be fetched using `ID` as [id][1] or using [resourcegroupstaggingapi][2] to fetch zone with filertags from `Tags`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: gofmt has fairly minimal markup, so probably [id][1] -> id [1] and similar. Run godoc -html ./your/package to check.
config/v1/types_dns.go
Outdated
| PublicZone *DNSZone `json:"publicZone,omitempty"` | ||
| // privateZone is the location where all the DNS records that are only available internally | ||
| // to the cluster exist. | ||
| PrivateZone DNSZone `json:"privateZone"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be a pointer too (or use a zone slice), so we have a way to tell ingress not to worry about DNS in the libvirt/BYOI cases?
0e38866 to
4b860b6
Compare
config/v1/types_dns.go
Outdated
| // A zone can be identified by an ID or tags. | ||
| // | ||
| // For example, | ||
| // on AWS zone can be fetched using `ID` as id in [1] or using resourcegroupstaggingapi [2] to fetch zone with filertags from `Tags`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/filertags/tags
4b860b6 to
baae572
Compare
config/v1/types_dns.go
Outdated
| type DNSZone struct { | ||
| // id is the identifier that can be used to find the DNS hosted zone. | ||
| // +optional | ||
| ID string `json:"id"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add slightly more godoc
|
Looks fine, add slightly more godoc to the fields in DNSZone describing use in cloud environments and then I'll approve and merge |
baae572 to
2236be3
Compare
moved the cloud specefic docs from |
Based on [1] `DNS` should be the source of truth for operators that manage DNS for their components. `DNS` currently specifies the `BaseDomain` that should be used to make aure all the records after subdomains to `BaseDomain`. A missing piece for operators that need to create DNS records is where should these records be created. For example, the `cluster-ingress-operator` creates DNS records in public and private r53 zones on AWS by listing all zones that match `BaseDomain` [2]. The ingress operator is currently making an assumption that the public zone matching the `BaseDomain` is *probably* the correct zone. With changes in installer [3] of creating private r53 zone `cluster_name.base_domain` and using public zone `base_domain`. The `BaseDomain` in `DNSSpec` will be set to the `cluster_domain` (`cluster_name.base_domain`) as all records must be subdomain of the `cluster_domain`. This breaks the previous assumption for the `cluster-ingress-operator` or any other operator. Clearly there is a gap to be filled regarding where the DNS records should be created. The installer knows which public and private zones should be used and can provide that information for the operators. `DNSSpec` is extended to include a required `PrivateZone` field and an optional `PublicZone` field to provide operators location of where the corresponding records should be created. `DNSZone` struct is also added to allow defining the DNS zone either using an `ID` or a string to string map `Tags`. `ID` allows installer to specify the public zone as it is predetermined, while `Tags` allow installer to point to a private DNS zone that will be created for the cluster. [1]: https://github.com/openshift/api/blob/d67473e7f1907b74d1f27706260eecf0bc9f2a52/config/v1/types_dns.go#L9 [2]: https://github.com/openshift/cluster-ingress-operator/blob/e7517023201c485428b3cdb3a86612230cf49e0a/pkg/dns/aws/dns.go#L111 [3]: openshift/installer#1169
generated using `make generate` ```console $ protoc --version libprotoc 3.0.0 $ go version go version go1.10.3 linux/amd64 ```
2236be3 to
2d43621
Compare
|
ping @smarterclayton |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: abhinavdahiya, smarterclayton The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
To get openshift/api#202 ```console $ dep ensure -update github.com/openshift/api github.com/openshift/client-go ``` ```console $ dep version dep: version : v0.5.0 build date : 2018-07-26 git hash : 224a564 go version : go1.10.3 go compiler : gc platform : linux/amd64 features : ImportDuringSolve=false ```
stemmed from conversation in openshift/installer#1169 (comment)
Based on doc
DNSshould be the source of truth for operators that manage DNS for their components.DNScurrently specifies theBaseDomainthat should be used to make aure all the records after subdomains toBaseDomain.A missing piece for operators that need to create DNS records is where should these records be created. For example, the
cluster-ingress-operatorcreates DNS records in public and private r53 zones on AWS by listing all zones that match
BaseDomainbase-domain. The ingress operator is currently making anassumption that the public zone matching the
BaseDomainis probably the correct zone.With changes in installer PR of creating private r53 zone
cluster_name.base_domainand using public zonebase_domain. TheBaseDomaininDNSSpecwillbe set to the
cluster_domain(cluster_name.base_domain) as all records must be subdomain of thecluster_domain. This breaks the previous assumption for thecluster-ingress-operatoror any other operator.
Clearly there is a gap to be filled regarding where the DNS records should be created. The installer knows which public and private zones should be used and can provide that information for the operators.
DNSSpecis extended to include a requiredPrivateZonefield and an optionalPublicZonefield to provide operators location of where the corresponding records should be created.DNSZonestruct is also added to allow defining the DNS zone either using anIDor a string to string mapTags.IDallows installer to specify the public zone as it is predetermined, whileTagsallowinstaller to point to a private DNS zone that will be created for the cluster.
Open questions:
/cc @ironcladlou @smarterclayton @wking @crawford