Custom improvements for OpenShift#825
Conversation
|
@salaboy @shinigambit would you be OK with this? |
|
Just draft for now. |
Codecov Report
@@ Coverage Diff @@
## main #825 +/- ##
==========================================
- Coverage 43.36% 42.88% -0.49%
==========================================
Files 48 49 +1
Lines 4690 4783 +93
==========================================
+ Hits 2034 2051 +17
- Misses 2367 2445 +78
+ Partials 289 287 -2
Continue to review full report at Codecov.
|
|
@lance @lkingland with this we could just patch tags in Makefile in midstream. |
|
Would it make sense to contribute this to https://github.com/google/go-containerregistry/tree/main/pkg/authn, and leverage that library? That library seems to be used by a lot of components, including the |
|
In particular, there's a credential helper protocol that would allow you to specify an external binary helper and authorization config for {
"credHelpers": {
"image-registry.openshift-image-registry.svc": "os",
}
}This would also work with other commands like |
|
@evankanderson I am not sure what you mean specifically. We are using Here I am just adding very specialized loader |
|
I'm suggesting: why not have a |
We are deliberately using |
I see. Interesting idea! I like it. However this would require user to download and put such a helper onto PATH. I wish everything worked automagically here: If cluster is OpenShift then internal registry is used by default without needing any additional steps. |
|
@lance @lkingland @zroubalik If I understand it correctly @salaboy and @evankanderson suggest not to do this by direct integration in binary. Instead this behaviour could be customized trough some local files. What would it mean for us (RH): Such a script might need to:
Also there probably would be different installation scripts for each OS. |
|
I'm not sure what tools users are already using; I see that there's already an I'm not blocking this submit, just trying to suggest ways to make the overall OpenShift experience align with the rest of the ecosystem, which I think helps us all. |
|
Depending on the space in the |
Why not do this in openshift-knative/kn-plugin-func? |
yes we can do it by |
But I strongly prefer not to have custom patches in openshift-knative/kn-plugin-func, in long term it will complicate maintenance. |
I agree with you there. This is the more desirable way for RHT, to be sure. Would other vendor offered clusters benefit from something similar? |
|
@lance I think this will happen for sure.. other vendors will need their own specific hooks and checks, so I will tend to agree with @evankanderson in the sense of let's make sure that we make I wouldn't like it either if you need to do patches to create your specific binaries, so my suggestion would be to try to create the mechanisms to check if you are running on Openshift as generic as possible. All these check can conform a profile, for example if check A, B and C are true, you are in Openshift, if only check A and C are true, you are in another vendor. If we follow the approach implemented in this PR, then each vendor will need to have it's own set of checks and we will not be promoting people to reuse those mechanisms. Just to be clear, these checks can definitely be in the binary, or contributed to the downstream libraries as @evankanderson mentioned. |
|
This is a valid, and useful question. I believe the current core library structure properly handles the situation using a fairly standard mechanism: The core |
cmd/client_vanilla.go
Outdated
| //go:build !openshift | ||
| // +build !openshift |
There was a problem hiding this comment.
I am happy to see that this logic is in the right location: cmd with a reference to an implementation-specific package. This is the same as can be used for all future cases where flavor-specific code is necessary, not just for OpenShift.
My concern with this approach is that it is calculated at build-time and thus results in a binary that is OpenShift specific. This is not, I think, a necessary capitulation, because the core func logic is agnostic if cluster flavor.
Is there not a way we can detect the cluster flavor at runtime?
There was a problem hiding this comment.
+1 here.. I would be more in favour of runtime detection with "standard" mechanisms, that we can reuse for other environments.
|
VMware actually has a slightly more complicated detection logic, because "Tanzu Application Platform" is a layer which can be applied to different types of clusters, including Tanzu Kubernetes Grid (VMware), EKS (Amazon), or even OpenShift on AWS (turtles all the way down). Should this check be conditioned on the cluster, the registry, or some combination? We might be able to use the auth preflight check with the |
If we could use that same request to find out if it is Tanzu Application Platform, OpenShift, or vanilla; that seems like it could work well. The analogy perhaps being this information is a bit like operating system, where Function is to Kubernetes Flavor as Binary is to Operating System. Am I understanding this correctly? By default the "Deployer" used by Using the Server header in the auth preflight is runtime, and done for every cluster connection of course, so it would accomplish the goal of allowing Sounds like a good topic for this week's call. |
| var additionalCredLoaders []creds.CredentialsCallback | ||
|
|
||
| switch { | ||
| case openshift.IsOpenShift(): |
There was a problem hiding this comment.
Just a comment:
I can see a future where we have a set of supported platforms, which are each given the opportunity to self-identify and add to the features offered by the Function Client. This would work a bit like a connection upgrade attempt. This keeps the core library clean of any third-party dependencies, but allows for our Functions library to offer the ability to seamelssly switch between cluster flavors.
There was a problem hiding this comment.
Looking good!
I am sure the exact way that we implement support for various Kubernetes flavors will evolve over time. For now, it is nice to see that a single func will work seamlessly whether it is connected to a vanilla K8S cluster provider or an OpenShift cluster provider; transparently making use of any upgrades/preconfigurations provided by a supported provider.
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: lkingland, matejvasek, zroubalik 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 |
|
This looks like a good first iteration. I do feel that we haven't answered @evankanderson question yet: |
We are conditioning on cluster type (by checking that the cluster contains something that is own to OpenShift). |
|
@lance @lkingland @salaboy @evankanderson are we OK with merging this into main? |
lance
left a comment
There was a problem hiding this comment.
This in general looks good to me, @matejvasek and I am OK merging it. However, since I have not actively been engaged in the dialog I'd like at least @salaboy and @lkingland or @zroubalik to also give the OK. So, I'm not removing hold just yet.
/lgtm
Yes @matejvasek I think this is fine to merge. |
evankanderson
left a comment
There was a problem hiding this comment.
A few code review comments.
I'd like to see somewhat better coverage of the new package, but I understand that we'd like to bake this in rather than fooling around with credential helpers.
| cfgMapName := "service-ca-config-" + rand.String(5) | ||
|
|
||
| cfgMap := &v1.ConfigMap{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: cfgMapName, | ||
| Annotations: map[string]string{"service.beta.openshift.io/inject-cabundle": "true"}, | ||
| }, |
There was a problem hiding this comment.
Why not use generateName here?
This also feels like maybe this function should have a comment explaining what it does and why this is a safe way to get the CA cert.
There was a problem hiding this comment.
(I think you're avoiding generateName because you want to simplify deleting this shortly after creation)
There was a problem hiding this comment.
I am using locally generated name so I can set up Watch before creation. Is that all right @evankanderson ?
| return nil | ||
| } | ||
|
|
||
| var selectCA func(ctx context.Context, serverName string) (*x509.Certificate, error) |
There was a problem hiding this comment.
This seems like it's finding the specific cert, not necessarily the CA for the cert (i.e. if you have a root CA that signs the registry cert, this will find the registry cert, not the root CA). That's okay, but we might prefer to call this registryCert.
There was a problem hiding this comment.
It's CA for multiple services provided by OpenShift, but here for now are are enabling trust only for registry. I don't feel confident enabling the CA for any and all connections.
There was a problem hiding this comment.
There was a problem hiding this comment.
@evankanderson it should find self-signed CA -- authority not just certificate.
| isOpenShift = false | ||
| return | ||
| } | ||
| _, err = client.CoreV1().Services("openshift-image-registry").Get(context.TODO(), "image-registry", metav1.GetOptions{}) |
There was a problem hiding this comment.
Hmm -- this will return false if the user doesn't have services get permission on the openshift-image-registry namespace.
I'm not sure if there's another / better way to detect this, either from server headers or by probing the registry and looking at its header / challenge. I think go-containerregistry uses a GET /v2/ HTTP /1.1 probe of the registry to figure out what and whether auth is required.
There was a problem hiding this comment.
https://github.com/google/go-containerregistry/tree/main/pkg/authn#the-registry suggests looking at the Www-Authenticate header for clues as to the authentication mechanism.
There was a problem hiding this comment.
I would avoid doing HTTP request to internal service here -- it requires some setup I don't want to do here.
There was a problem hiding this comment.
Hmm -- this will return false if the user doesn't have services get permission on the openshift-image-registry namespace.
@evankanderson This does work with non-privileged user. Non-privilieged user will get different errors for non-existent service and for service that is not just permitted (NotFound vs. PermissionDenied).
Signed-off-by: Matej Vasek <mvasek@redhat.com>
eea9ac0 to
5b15436
Compare
Signed-off-by: Matej Vasek <mvasek@redhat.com>
Signed-off-by: Matej Vasek <mvasek@redhat.com>
Unfortunately good integration test here require OpenShift cluster that in not running in GH action. |
|
@lance @lkingland please lgtm |
Signed-off-by: Matej Vasek <mvasek@redhat.com>
|
/lgtm |
|
/unhold |
🎁 add initial framework for cluster flavor detection/actions