-
Notifications
You must be signed in to change notification settings - Fork 584
Add Route for consoles custom hostname #594
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
Conversation
config/v1/types_console.go
Outdated
| Host string `json:host:omitempty` | ||
| // servingCert references to ConfigMap in the openshift-config namespace that | ||
| // contains custom certificate. | ||
| ServingCert ConfigMapNameReference `json:servingCert: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.
Wasn't really sure about this name, but didn't want to duplicate the custom* prefix in every 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.
given it also needs to contain the private key (you can't serve a cert without a private key) shouldn't this reference a secret?
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.
Just update the PR with the SecretReference. Thanks !
config/v1/types_console.go
Outdated
| // customization is used to optionally provide a small set of | ||
| // customization options to the web console. | ||
| // +optional | ||
| Customization ConsoleCustomization `json:"customization,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.
I don't see this as customization really. Maybe route? Something like
spec:
route:
hostname: my-hostname
servingCert: my-secretThere 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.
We spoke with @benjaminapetersen that it might be good to follow the patter that we have in our operator 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.
I don't mean to bikeshed, but this isn't customization imo. It's basic serving info. I wouldn't think to look there to set these values.
(Technically, any config is a customization I guess, but then it starts to lose meaning.)
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.
To be honest I like both approaches. Since there already is a Authentication field on the ConsoleSpec I kinda incline to go with:
...
Route ConsoleRoute `json:"route,omitempty"`
...
@benjaminapetersen thoughts ?
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 can roll with this. We have Customization on the operator config which contains a URL, but its an override to a default. Agree, this is a different kind of thing.
I'm good with Route { URL, ServingCert } type of 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.
https://github.com/openshift/api/blob/master/config/v1/types_infrastructure.go#L58 for an example of documentation verbiage.
URL is a valid URI with scheme(http/https)....
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.
We want just hostname here, not URL. That matches what Route API, and we don't want the user to set a scheme, port, or path.
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.
hostname is good, I've been meaning to look up what would be consistent, was thinkging URL isn't quite right.
config/v1/types_console.go
Outdated
| CustomURL `json:customURL,omitempty` | ||
| } | ||
|
|
||
| // CustomURL replaces the default console URL under which console will be available. |
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.
We need to make sure we're documenting the default behavior when these values aren't specified.
config/v1/types_console.go
Outdated
| Host string `json:host:omitempty` | ||
| // servingCert references to Secret in the openshift-config namespace that | ||
| // contains custom certificate and key. | ||
| ServingCert corev1.SecretReference `json:servingCert: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.
This probably doesn't need to be required. If you pick a hostname that uses the default routing suffix, you shouldn't need to specify a certificate and key.
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.
Makes sense 👍
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 we document that that's a reasonable thing to do?
config/v1/types_console.go
Outdated
| // host is the desired custom URL under which console will be available. | ||
| Host string `json:host:omitempty` | ||
| // servingCert references to Secret in the openshift-config namespace that | ||
| // contains custom certificate and key. |
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.
We need to document the fields in the referenced secret that contain the certificate and key.
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.
@spadgett you mean the fields on the Secret itself - tls.crtand tls.key
Or the Name and the Namespace and where they should point 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.
I mean the keys in the secret, tls.crt and tls.key. That needs to be documented somewhere, otherwise the user has no way to know.
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.
Yeah as the Operator will have to pluck them out by this. Unless we let the user configure the keys, but that seems unnecessary.
|
/cc @bparees |
|
@spadgett @benjaminapetersen I've update the PR based on your comments |
config/v1/types_console.go
Outdated
| // CustomRoute replaces the default console hostname under which console will be available. | ||
| type CustomRoute struct { | ||
| // hostname is the desired custom address under which console will be available. | ||
| Hostname string `json:hostname` |
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.
Here I wasn't sure if we dont wanna follow the Route naming, which would be Host
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 probably create ConsoleConfigRoute and do the same as https://github.com/openshift/api/blob/master/imageregistry/v1/types.go#L302. Three fields, include Name. Consistency is good.
Provided we don't go the central config route that is currently being discussed.
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.
// ConsoleConfigRoute holds information on external route access to console
type ConsoleConfigRoute struct {
// name of the route to be created.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// hostname for the route.
// +optional
Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"`
// secretName points to secret containing the certificates to be used
// by the route.
// +optional
SecretName string `json:"secretName,omitempty" protobuf:"bytes,3,opt,name=secretName"`
}
config/v1/types_console.go
Outdated
| Authentication ConsoleAuthentication `json:"authentication"` | ||
| // route contains hostname and serving certificate for replacing the default hostname, | ||
| // under which is console available. | ||
| // If not specified, default route will be created by the console-operator. |
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.
@spadgett @benjaminapetersen would be good to align on the default behaviour, that means if we wanna keep the default route or not, when the custom hostname will be specified.
Not sure if it makes sense to have two urls for console, if the custom one is defined.
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 do want to keep it, for the squatting reason stated before.
It probably doesn't affect this PR, aside from documentation.
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.
Could update to something like:
If a custom route is specified, a new route will be created with the provided URL. The default route will be maintained but will no longer access the console.
|
/hold This approach doesn't seem to address the larger issue of needing to provide custom certificates for all of our components exposed via routes. How about placing this in the ingress config and using an API similar to api/config/v1/types_apiserver.go Line 63 in d3d78e0
We could even rename the struct type for inclusion. The kube-apiserver configuration remains separate because it is externally managed and not necessarily exposed via route. @ironcladlou I was hoping that network-edge would produce something that could be re-used across all exposed routes, like authentication, console, metrics, etc. Does the approach I sketched sound reasonable? |
|
@deads2k wasnt aware the other components are trying to solve this issue. Which component (besides the apiserver) is dealing with this issue ?
To solve it uniformly would make sense, but not sure how that would fit into our story where besides the @benjaminapetersen @spadgett thoughts ? |
Everything we expose today with a route has this issue and knows what name its looking for. A solution should resolve certs for these route based endpoints in a unified way. Removing wildcard certs requires resolving all of these. |
|
@deads2k are you suggesting a central location for all external certs, mapped to hostnames, which ingress would automatically configure matching routes to use? |
I think it would go in the other direction. Ingress cannot rewrite the operands, but providing hostname/certificate tuples in a central spot in ingresses.config.openshift.io|spec makes sense since it's a general ingress problem. From there, each individual operand has sufficient information to configure the routes. |
|
followed up with @deads2k on slack. what he's proposing is a central config api for "map these hostnames to these certs". individual operators would be responsible for looking at that config and deciding what cert, if any, they needed to configure their operand's routes to use. I think there's a usability/obviousness/risk-of-breakage tradeoff between central config for this vs having an operator fully own the config in its own resource, but i guess fundamentally i'm ok either way. But i'm also worried about the console team getting blocked on this if the central store api isn't finalized+introduced rapidly. |
|
It seems like the central list approach is an advantage if components need to share, having them all in one place ensures a uniform API, helps an admin do the right thing. Would this config have to be named keys, or can it be in a list form? IE, for authentication, console, downloads, alertmanager, grafana, prometheus, and thanos... and foo,bar,baz, can additional items be added w/o PRs to add new keys? |
i would have guessed it would be a hostname/cert pairing and anyone who wants to create a route for a given hostname could look at the config to see if a cert existed for that hostname, and use it. Though that seems to present another problem w/ the central config (if i understand the idea correctly) which is that all components are going to have to be able to read all the certs for everything. Just getting the cert isn't sufficient to MITM something, but it's a big step. |
In that case, should the Also other question is, who will be responsible for the API changes ? Since this change would have bigger impact, than the one the story Im working on is about. |
Yes.
Good APIs can originate from anyone. You probably want to talk with @openshift/sig-network-edge and the other impacted teams |
makes sense Are there any guesses where the hostname and servingCert will be located ? since I doubt that we will read those from console config (as the current PR suggests) |
|
I must be misunderstanding the proposal because I'm not clear how it impacts ingress operator or the router. It sounds like you're talking about centralizing cert data and making changes to (non-ingress) operators to drive how they create routes and inject cert config into the routes they create. What specific impact would that have to the ingress operator or ingress controller (router)? |
i think none, other than you'd own the CRD that contained the central config that @deads2k is proposing. So your operator would probably include the resource yaml for that CRD. but i'm still interested in the answer to this, also:
|
It doesn't have to be all certs, a cluster-admin could choose to limit the access and operators could watch a named item (server supports this), but at least a couple of these components an already read secret content from openshift-config since it is the canonical source. My one reservation would be a future move to OLM, but I think that migration would be straightforward |
|
/test verify |
config/v1/types_console.go
Outdated
| type ConsoleSpec struct { | ||
| // +optional | ||
| Authentication ConsoleAuthentication `json:"authentication"` | ||
| // route contains hostname and serving certificate for replacing the default hostname, |
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.
Minor tweaks, I'll just inline in your original text:
// route contains hostname and serving certificate for replacing the default route for the console.
// If a custom route is specified, a new route will be created with the provided hostname.
// The default console route will be maintained to reserve the default hostname for console if the custom route is removed.
config/v1/types_console.go
Outdated
| // If hostname that uses default routing suffix of the given cluster, the | ||
| // servignCert specification will not be needed. | ||
| // +optional | ||
| SecretName string `json:"secretName,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.
Guessing this should really be a SecretNameReference rather than a string.
Not a lot to it:
// SecretNameReference references a secret in a specific namespace.
// The namespace must be specified at the point of use.
type SecretNameReference struct {
// name is the metadata.name of the referenced secret
// +kubebuilder:validation:Required
// +required
Name string `json:"name"`
}
config/v1/types_console.go
Outdated
| // The default console route will be maintained to reserve the default hostname for console if the custom route is removed. | ||
| // If not specified, default route will be used. | ||
| // +optional | ||
| Route ConsoleConfigRoute `json:"route,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.
not in this group. Put it on your operator resource.
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 there a reason why it can live on the console 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.
it's more that it shouldn't. this is config that's only consumed by your operator, it's not global config that's consumed by others. (the console operator publishes the public route hostname back to this resource under status, which is global information that's consumed by others, or can be)
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.
Our logic has been a custom route is a normal thing a cluster-admin may configure, thus it should exist on the top-level config.
That said, we can move it.
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.
How "normal" it is is not the right deciding factor for where it should go, the things l listed above are
config/v1/types_console.go
Outdated
| // ConsoleConfigRoute holds information on external route access to console. | ||
| type ConsoleConfigRoute struct { | ||
| // name of the route to be created. | ||
| Name string `json:"name"` |
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.
why is this configurable
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.
we have been pointed to https://github.com/openshift/api/blob/master/imageregistry/v1/types.go#L304-L314 so wanted to align with what we already use
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.
feel free to improve on what was done in imageregistry. I don't think we had a good reason to make the route name configurable.
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.
We can drop the name.
@jhadvig since we likely want to keep the default route (squat on it) in case the custom route is removed, we can just hard code console-custom as name for the new route.
config/v1/types_console.go
Outdated
| Name string `json:"name"` | ||
| // hostname is the desired custom address under which console will be available. | ||
| // +optional | ||
| Hostname string `json:"hostname,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.
given a different hostname, couldn't they simply point to your service today and configure an unmanaged route as they wish. This could make your API contract on the service name, but nothing else. No new API and no conflict with resources you manage. What is the value of you having them program this API to program a route instead of simply creating the route?
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.
We need to update our OAuth client with the console callback URL. Also the OAuth server whitelists console URL for kubeadmin logout.
We also use cookies and localStorage. Multiple routes for console could be problematic since the cookies won't be shared.
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.
Console also needs to know its own public URL for various reasons (for instance, to build the OAuth callback URL). Maybe we can read the host from the HTTP request, but I'm not sure that's always reliable.
|
@spadgett @benjaminapetersen PR updated. PTAL |
operator/v1/types_console.go
Outdated
| // Referenced Secret is required to contain following key value pairs: | ||
| // - "tls.crt" - to specifies custom certificate | ||
| // - "tls.key" - to specifies private key of the custom certificate | ||
| // If hostname that uses default routing suffix of the given cluster, the servignCert specification will not be needed. |
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.
Minor tweak:
If the custom hostname uses the default routing suffix of the cluster, the Secret specification for a serving cert will not be needed.
e573d14 to
fb1e57d
Compare
operator/v1/types_console.go
Outdated
| // ConsoleConfigRoute holds information on external route access to console. | ||
| type ConsoleConfigRoute struct { | ||
| // hostname is the desired custom address under which console will be available. | ||
| Hostname string `json:"hostname,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.
If this hostname is not a subdomain of the default ingress domain, seems like the admin would have to manually configure DNS to point at the ingress controller. Maybe I'm misunderstanding something.
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.
Just update the PR adding notification regarding that case
operator/v1/types_console.go
Outdated
| // for console if the custom route is removed. | ||
| // If not specified, default route will be used. | ||
| // +optional | ||
| Route *ConsoleConfigRoute `json:"route,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.
if empty strings in this struct are the same as not present (I would expect them to be), then this doesn't need to be a pointer
|
@deads2k update the PR. Removed the |
|
/lgtm |
|
/hold cancel |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bparees, jhadvig 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 |
Story: https://issues.redhat.com/browse/CONSOLE-2036
Will run the generator script by the end of the review.
/assign @benjaminapetersen @spadgett