-
Notifications
You must be signed in to change notification settings - Fork 706
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
Remove all pending endpoints from Kubeops #5249
Conversation
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
✅ Deploy Preview for kubeapps-dev canceled.
|
- apiGroups: | ||
- packages.operators.coreos.com | ||
resources: | ||
- packagemanifests/icon | ||
verbs: | ||
- get |
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.
Needed for retrieving operators logos
|
||
// TODO(rcastelblanq) Move this endpoint to the Operators plugin when implementing #4920 | ||
// Proxies the operator icon request to K8s | ||
err = gwmux.HandlePath(http.MethodGet, "/operators/namespaces/{namespace}/operator/{name}/logo", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) { |
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.
Operators logos are served now from here. Not the most elegant solution, but it should be something temporary.
@@ -243,5 +245,41 @@ func gatewayMux() (*runtime.ServeMux, error) { | |||
return nil, fmt.Errorf("failed to serve: %v", err) | |||
} | |||
|
|||
svcRestConfig, err := rest.InClusterConfig() |
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.
Using pod's SA to avoid forcing the user's token to have RBAC on operators icons.
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'm not 100% sure, but using such a powerful SA for proxying a k8s API when we are directly injecting unsanitized input from the URL (below), seems like a great attack vector for malicious malformed URLs escalating privileges 😅 .
That said, it is something strictly temporary we should fix near soon, and we clearly discourage enabling operators in production envs, so I'm fine with the change given what you told in the PR comments.
fmt.Sprintf("/apis/packages.operators.coreos.com/v1/namespaces/%s/packagemanifests/%s/icon", namespace, 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.
but using such a powerful SA for proxying a k8s API when we are directly injecting unsanitized input from the URL
Totally agree on this. It seems that net/http
's ServeMux
does some sanitizing of the input (see cleanPath
here), but we are using GRPC's ServeMux
which apparently doesn't.
We could mimic the net/http
behavior using path.Clean
or use an external dependency.
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 as we need to get rid of Kubeops as soon as possible. There are some security concerns as I said, but it's fair enough given the current status of the operators support. Thanks for the changes!
@@ -3565,6 +3565,69 @@ | |||
] | |||
} | |||
}, | |||
"/plugins/resources/v1alpha1/c/{context.cluster}/can-i": { |
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 API docs should also be (manually) copied to the dashboard/src/public/openapi.yaml
file, but we can do it once we remove the kubeapps deployment entirely.
@@ -243,5 +245,41 @@ func gatewayMux() (*runtime.ServeMux, error) { | |||
return nil, fmt.Errorf("failed to serve: %v", err) | |||
} | |||
|
|||
svcRestConfig, err := rest.InClusterConfig() |
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'm not 100% sure, but using such a powerful SA for proxying a k8s API when we are directly injecting unsanitized input from the URL (below), seems like a great attack vector for malicious malformed URLs escalating privileges 😅 .
That said, it is something strictly temporary we should fix near soon, and we clearly discourage enabling operators in production envs, so I'm fine with the change given what you told in the PR comments.
fmt.Sprintf("/apis/packages.operators.coreos.com/v1/namespaces/%s/packagemanifests/%s/icon", namespace, name)
@@ -160,8 +153,8 @@ export const api = { | |||
}, | |||
|
|||
operators: { | |||
operatorIcon: (cluster: string, namespace: string, name: string) => | |||
`api/v1/clusters/${cluster}/namespaces/${namespace}/operator/${name}/logo`, | |||
operatorIcon: (_cluster: string, namespace: string, name: string) => |
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 sure about the current multicluster support for operators, but given the upcoming changes, doesn't really matter I guess.
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.
Yes, in the multicluster scenario we are assuming now that operators logos live in the main (Kubeapps) cluster.
Description of the change
This PR completes the removal of UI calls to Kubeops. It leaves the backend Kubeops
http-handler.go
empty, without any route to be served:Two routes have been moved into valid Kubeapps sections:
can-i
has been added as an endpoint into the resources plugin, being served through GRPC/GRPC-web/REST now. This could be something temporary, creating a new "rbac" plugin into which to copy the endpoint.All the above means that Kubeops can be now removed without users noticing.
Benefits
Kubeops is not needed anymore! Kubeapps will be lighter.
Possible drawbacks
Anyone using kubeops directly for whatever reason might be affected.
Applicable issues
Additional information
It turns out that moving the operators logo away from Kubeops it has been the hardest task.
Initial situation
For retrieving an operator logo, Kubeops only acts as a proxy, relaying the request to K8s API with the kubeops service account.
The endpoint returns an operator logo bytes by name, and then it is used as "src" attribute in HTML images.
First try: Switching the call from UI directly to K8s APIs
Direct communication to K8s APIs is accessible when operators are enabled.
It didn't work, as the request needs authorization. Authorization headers can't be provided to the
src
attribute URL OOB. It needed work in TS/JS to retrieve the data with Axios + authorization, and set the data as base64 in thesrc
attribute. Using the current user token meant also that the user should haveget
RBAC onpackages.operators.coreos.com
/packagemanifests/icon
, something that the Kubeops serviceaccount has defined in our chart. If the user didn't have that RBAC, he/she would see the list of operators without logos.Main problem with this approach is that all requests for the operators summary are triggered at the same time. Hanlding so many base64 data at once made the UI terribly sluggish. I even ended up implementing a lazy loading for the icons, which improved the experience, but adding testing to that was challenging and time consuming.
Second try: Moving the endpoint from Kubeops to Kubeappsapis
Defined the endpoint as something temporary in the Resources plugin (until the Operators plugin is built).
That meant having it defined in protobuf, which doesn't allow to return directly bytes (or Any) to serve for a
src
attribute. Amessage
format must be returned, with at least one field.Lesson learned: we can't serve an image's bytes with GRPC, a protocol that is not resource oriented.
Third try: Leaving the endpoint in kubeapps-apis as REST only
Finally, the approach that worked was having the endpoint as a special case in
kubeapps-apis
, see here.This is something temporary, a new plugin for operators is scheduled and this endpoint should be served from there in the future.