-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Teleterm: Add listing kube resources endpoint #46753
base: master
Are you sure you want to change the base?
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
lib/teleterm/api/uri/uri.go
Outdated
// AppendKubeResource appends kube resource segment to the URI. | ||
// Modeled after how access request constructs the resource ID: | ||
// <teleport-cluster-name>/<subresource kind>/<kube_cluster name>/<subresource name> | ||
func (r ResourceURI) AppendKubeResource(kubeResourceKind string, kubeClusterName string, kubeResourceName string) ResourceURI { | ||
r.path = fmt.Sprintf("%v/%v/%v/%v", r.path, kubeResourceKind, kubeClusterName, kubeResourceName) | ||
return r | ||
} | ||
|
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 wasn't entirely sure what this was for, other than perhaps to uniquely identify resources?
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, URIs are used for identifying resources.
fmt.Sprintf("%v/%v/%v/%v", r.path, kubeResourceKind, kubeClusterName, kubeResourceName)
I see some problems with this scheme. kubeResourceKind
is an unknown string, so in theory, it could collide with other URIs. Additionally, we would not be able to identify if a given URI string is a kube resource URI without knowing kubeResourceKind
.
A fix for this would be adding a known prefix in the URI, e.g:
"/clusters/teleport.sh/kube-resources/namespace/kube-cluster-name/namespace-name"
However, perhaps it would make more sense to treat a kube resource as a child of the kube cluster? I mean something like this:
var pathKubes = urlpath.New("/clusters/:cluster/kubes/:kubeName")
var pathKubeResources = urlpath.New("/clusters/:cluster/kubes/:kubeName/:subResourceKind/:subResourceName")
cc @ravicious
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 went ahead and applied your first suggestion instead:
"/clusters/teleport.sh/kube-resources/namespace/kube-cluster-name/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.
If it's correct that kube subresources always belong to a specific kube resource, and I believe it's correct, then I'd definitely go with the second option that Grzegorz proposed.
If we currently support only namespaces within the app, then for now I'd make a definition only for namespaces. That would be:
kubeResourceNamespace:
'/clusters/:rootClusterId/(leaves)?/:leafClusterId?/kubes/:kubeId/namespaces/:kubeNamespaceId',
kubeResourceNamespaceLeaf:
'/clusters/:rootClusterId/leaves/:leafClusterId/kubes/:kubeId/namespaces/:kubeNameSpaceId',
This follows the existing conventions that we have while introducing a new one. Nested identifiers are prefixed with "parent's" name, e.g. it's :kubeNamespaceId
, not :namespaceId
.
This is mostly due to how matchPath
works and how we implemented parseUri
. You give it a bunch of possible identifiers and then pluck out what you need. So if we end up having two URIs, I think we'd rather have two different fields prefixed with the parent name, rather than reusing the same field name for two different purposes.
I wouldn't bother with KubeResourceNamespaceParam
for now. If we wanted to have better types around this, we should refactor how routing.parseUri
works and all the helper functions like routing.parseServerUri
.
On the Go side, AppendKubeResourceNamespace
as you have it is fine, we'd only have to change the actual URI it generates.
lib/teleterm/daemon/daemon.go
Outdated
proxyGRPCClient, err := tc.NewKubernetesServiceClient(ctx, cluster.Name) | ||
if err != nil { | ||
return nil, trace.Wrap(err) | ||
} |
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 to me this should be wrapped in clusters.AddMetadataToRetryableError
too.
lib/teleterm/daemon/daemon.go
Outdated
if err != nil { | ||
return trace.Wrap(err) | ||
} | ||
|
||
return nil |
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 err != nil { | |
return trace.Wrap(err) | |
} | |
return nil | |
return trace.Wrap(err) |
lib/teleterm/api/uri/uri.go
Outdated
// AppendKubeResource appends kube resource segment to the URI. | ||
// Modeled after how access request constructs the resource ID: | ||
// <teleport-cluster-name>/<subresource kind>/<kube_cluster name>/<subresource name> | ||
func (r ResourceURI) AppendKubeResource(kubeResourceKind string, kubeClusterName string, kubeResourceName string) ResourceURI { | ||
r.path = fmt.Sprintf("%v/%v/%v/%v", r.path, kubeResourceKind, kubeClusterName, kubeResourceName) | ||
return r | ||
} | ||
|
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, URIs are used for identifying resources.
fmt.Sprintf("%v/%v/%v/%v", r.path, kubeResourceKind, kubeClusterName, kubeResourceName)
I see some problems with this scheme. kubeResourceKind
is an unknown string, so in theory, it could collide with other URIs. Additionally, we would not be able to identify if a given URI string is a kube resource URI without knowing kubeResourceKind
.
A fix for this would be adding a known prefix in the URI, e.g:
"/clusters/teleport.sh/kube-resources/namespace/kube-cluster-name/namespace-name"
However, perhaps it would make more sense to treat a kube resource as a child of the kube cluster? I mean something like this:
var pathKubes = urlpath.New("/clusters/:cluster/kubes/:kubeName")
var pathKubeResources = urlpath.New("/clusters/:cluster/kubes/:kubeName/:subResourceKind/:subResourceName")
cc @ravicious
lib/teleterm/api/uri/uri.go
Outdated
// AppendKubeResource appends kube resource segment to the URI. | ||
// Modeled after how access request constructs the resource ID: | ||
// <teleport-cluster-name>/<subresource kind>/<kube_cluster name>/<subresource name> | ||
func (r ResourceURI) AppendKubeResource(kubeResourceKind string, kubeClusterName string, kubeResourceName string) ResourceURI { | ||
r.path = fmt.Sprintf("%v/%v/%v/%v", r.path, kubeResourceKind, kubeClusterName, kubeResourceName) | ||
return r | ||
} | ||
|
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 it's correct that kube subresources always belong to a specific kube resource, and I believe it's correct, then I'd definitely go with the second option that Grzegorz proposed.
If we currently support only namespaces within the app, then for now I'd make a definition only for namespaces. That would be:
kubeResourceNamespace:
'/clusters/:rootClusterId/(leaves)?/:leafClusterId?/kubes/:kubeId/namespaces/:kubeNamespaceId',
kubeResourceNamespaceLeaf:
'/clusters/:rootClusterId/leaves/:leafClusterId/kubes/:kubeId/namespaces/:kubeNameSpaceId',
This follows the existing conventions that we have while introducing a new one. Nested identifiers are prefixed with "parent's" name, e.g. it's :kubeNamespaceId
, not :namespaceId
.
This is mostly due to how matchPath
works and how we implemented parseUri
. You give it a bunch of possible identifiers and then pluck out what you need. So if we end up having two URIs, I think we'd rather have two different fields prefixed with the parent name, rather than reusing the same field name for two different purposes.
I wouldn't bother with KubeResourceNamespaceParam
for now. If we wanted to have better types around this, we should refactor how routing.parseUri
works and all the helper functions like routing.parseServerUri
.
On the Go side, AppendKubeResourceNamespace
as you have it is fine, we'd only have to change the actual URI it generates.
} | ||
|
||
message ListKubernetesResourcesResponse { | ||
repeated KubeResource items = 1; |
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 call it resources
perhaps? That's what ListUnifiedResources
already does. I don't see any other RPC within this service that would use items
as the field name.
|
||
message ListKubernetesResourcesResponse { | ||
repeated KubeResource items = 1; | ||
string start_key = 2; |
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 should probably be next_key
, just to keep the convention started by unified resources.
"github.com/gravitational/teleport/lib/teleterm/clusters" | ||
"github.com/gravitational/teleport/lib/web/ui" |
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'd say let's avoid bringing lib/web into lib/teleterm. Grepping through lib/teleterm, it's not something that we do today.
If we need to reuse some functions between lib/web
and lib/teleterm
, I think a better option would to move them to a third package that can be used by both web and teleterm.
What do you think about creating lib/ui/labels.go
and moving MakeUILabelsWithoutInternalPrefixes
there? Then we could even drop UI
from its name.
var proxyGRPCClient kubeproto.KubeServiceClient | ||
|
||
err = clusters.AddMetadataToRetryableError(ctx, func() error { | ||
proxyGRPCClient, err = tc.NewKubernetesServiceClient(ctx, cluster.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.
Nit: We can put both calls under the same AddMetadataToRetryableError
call, it results in the same behavior and it's slightly shorter.
// note: | ||
// this field will be blank if this resource "kind" is "namespace", | ||
// refer to field "name" for the name of namespace |
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.
// note: | |
// this field will be blank if this resource "kind" is "namespace", | |
// refer to field "name" for the name of namespace | |
// note: this field will be blank if this resource "kind" is "namespace", | |
// refer to field "name" for the name of namespace |
86815ca
to
5ee774f
Compare
part of #46742
easier to review by commit
Adds a new grpc endpoint and related boilerplates for listing kube resources
if confused what is the difference between the other endpoint where we list kubes, kube resources refers to kube_cluster's sub resources:
teleport/api/types/constants.go
Line 1233 in 110b23a