Add cluster autoupdate resources with enabled cache#45617
Add cluster autoupdate resources with enabled cache#45617
Conversation
bd8e1d3 to
db12db8
Compare
4e2cd91 to
0e45c8f
Compare
e24daff to
70b7c54
Compare
|
The PR changelog entry failed validation: Changelog entry not found in the PR body. Please add a "no-changelog" label to the PR, or changelog lines starting with |
sclevine
left a comment
There was a problem hiding this comment.
LGTM, may want to double-check with @rosstimothy about whether the cache is configured suitably for serving the /find endpoint
6675c32 to
0184ab6
Compare
Fix interval first duration
0184ab6 to
3b03379
Compare
rosstimothy
left a comment
There was a problem hiding this comment.
There is a lot going on in this PR - many layers of boilerplate all being implemented at once. I'd suggest trying to scope this to just adding the resource, the RPC service and persisting it in the backend and retrieving it from the cache. The tctl commands and webapi changes could probably both be in their own distinct and more focused PRs.
| // GetAutoupdateConfig gets autoupdate configuration. | ||
| func (c *Client) GetAutoupdateConfig(ctx context.Context) (*autoupdate.AutoupdateConfig, error) { | ||
| resp, err := c.AutoupdateServiceClient().GetAutoupdateConfig(ctx, &autoupdate.GetAutoupdateConfigRequest{}) | ||
| if err != nil { | ||
| return nil, trace.Wrap(err) | ||
| } | ||
| return resp, nil | ||
| } | ||
|
|
||
| // GetAutoupdateVersion gets autoupdate version. | ||
| func (c *Client) GetAutoupdateVersion(ctx context.Context) (*autoupdate.AutoupdateVersion, error) { | ||
| resp, err := c.AutoupdateServiceClient().GetAutoupdateVersion(ctx, &autoupdate.GetAutoupdateVersionRequest{}) | ||
| if err != nil { | ||
| return nil, trace.Wrap(err) | ||
| } | ||
| return resp, nil | ||
| } |
There was a problem hiding this comment.
Consider consolidating the API here. If we offer AutoupdateServiceClient then let's have everyone use that instead of creating these helpers.
There was a problem hiding this comment.
after adding get methods for fetching config and version in find endpoint
interface ReadRemoteProxyAccessPoint {
GetAutoupdateConfig(ctx context.Context) (*autoupdate.AutoupdateConfig, error)
GetAutoupdateVersion(ctx context.Context) (*autoupdate.AutoupdateVersion, error)
}cache.Cache and client.ClientI should implement these methods, otherwise if I replace this one to client get method I need to add some wrapper for https://github.com/gravitational/teleport/pull/45617/files#diff-3e237f973a30f7092dc18a706ecd95d8a7e1d99c5c50626b8bb0e7ac6cb7efd1R1899-R1920
| // AutoupdateCommand implements the `tctl autoupdate` command for managing | ||
| // autoupdate process for tools and agents. | ||
| type AutoupdateCommand struct { |
There was a problem hiding this comment.
Should this resource be supported via tctl create and tctl get? Any reason to prefer managing auto update resources via tctl autoupdate instead?
There was a problem hiding this comment.
The autoupdate subcommand was proposed by RJ here: https://github.com/gravitational/teleport/pull/39805/files#diff-8d3c0408dd826f27e9f13cd15f09f4d7e89202862f0b13ce131a2e3072c2a40dR249
Seems reasonable for both the subcommand and tctl create/tctl get to work?
There was a problem hiding this comment.
I believe that might be better from UX, when everything in one place and you able to configure autoupdates without having knowledge about resources responsible for this configuration.
I will additionally add these resources also to tctl create/get resource command
Add resource command for autoupdate config and version Limit to getter interface for client and cache part Add client wrapping
|
@vapopov - this PR will require admin approval to merge due to its size. Consider breaking it up into a series smaller changes. |
Add tests for resources command
083fb77 to
4cceaac
Compare
|
@rosstimothy could you please take another look at the PR? |
rosstimothy
left a comment
There was a problem hiding this comment.
As mentioned before, I think it would be best if this PR was split up into several smaller, more focused PRs. I tend to recommend that for new resources folks try to split each layer of the boilerplate up into PRs in roughly the following order:
- resource and audit events proto and generated code
- backend storage service implementation
- RPC service implementation
- cache support
- tctl support
- audit event support
A good example to follow is the SPIFFEFederation resource that Noah recently added.
| Backend services.AutoupdateService | ||
| // Cache is the cache used to store autoupdate resources. | ||
| Cache services.AutoupdateServiceGetter |
There was a problem hiding this comment.
Suggestion: consider using smaller, more well defined interfaces here for each of these containing only the methods expected to be called on each instead of relying on the services interface.
| // Opting out of forward compatibility, this service must implement all service methods. | ||
| autoupdate.UnsafeAutoupdateServiceServer |
There was a problem hiding this comment.
Any particular reason to go with this instead of the UnimplementedAutoupdateServiceServer?
There was a problem hiding this comment.
this is minimal requirement to be registered as service server, but we have to be sure that all methods implemented not to have nil pointer panic, will replace with UnimplementedAutoupdateServiceServer
| // KindAutoupdateConfig is the resource with autoupdate configuration. | ||
| KindAutoupdateConfig = "autoupdate_config" | ||
|
|
||
| // KindAutoupdateVersion is the resource with autoupdate versions. | ||
| KindAutoupdateVersion = "autoupdate_version" | ||
|
|
||
| // MetaNameAutoupdateConfig is the name of a configuration resource for autoupdate config. | ||
| MetaNameAutoupdateConfig = "autoupdate-config" | ||
|
|
||
| // MetaNameAutoupdateVersion is the name of a resource for autoupdate version. | ||
| MetaNameAutoupdateVersion = "autoupdate-version" |
There was a problem hiding this comment.
Reading through the code I find the naming Autoupdate to look off - should we be using AutoUpdate instead?
There was a problem hiding this comment.
We agreed with @sclevine to use Autoupdate instead camel case, both RFDs was modified to be consistent
There was a problem hiding this comment.
No strong opinion about this. The RFDs had a mixture of autoupdate_ / Autoupdate and auto_update_ / AutoUpdate prefixes, so we went with the former spelling everywhere to be consistent with the resource and command naming in the original Client Tools proposal: https://github.com/gravitational/teleport/pull/39805/files
@rosstimothy if you feel strongly that we should move the other way, or break consistency for identifiers in the codebase, no objections.
| autoupdateConfigPrefix = "autoupdate_config" | ||
| autoupdateVersionPrefix = "autoupdate_version" |
There was a problem hiding this comment.
Same question about the naming of this resource. Is this entity an autoupdate or an auto update?
| autoupdateConfigPrefix = "autoupdate_config" | |
| autoupdateVersionPrefix = "autoupdate_version" | |
| autoUpdateConfigPrefix = "auto_update_config" | |
| autoUpdateVersionPrefix = "auto_update_version" |
| ) | ||
|
|
||
| // Client is an AutoupdateService client that conforms to the following lib/services interfaces: | ||
| // - services.AutoupdateService |
There was a problem hiding this comment.
I don't think we should mention services in the api package since API does not an cannot depend on gravitational/teleport without creating an import cycle.
There was a problem hiding this comment.
ok, will remove this one, we have other 4 clients declaring the same
|
|
||
| // Client is an AutoupdateService client that conforms to the following lib/services interfaces: | ||
| // - services.AutoupdateService | ||
| type Client struct { |
There was a problem hiding this comment.
Do we need a dedicated client? There isn't much going on here besides hiding gRPC requests. Consider following the same approach that Noah took with the SPIFFE resource:
There was a problem hiding this comment.
in codebase there are 3 ways how it is implemented, legacy one with interface in types, methods implementation and this one with wrapping grpc client to be interface compatible to service definition, this PR by iterations implemented all of them.
Last one was added because I was trying to eliminate methods declarations for client (as it was requested previously in this review)
1877695#diff-f5e514e352c12c01eab507e6d9bbdfa697791b35bf914d949b92245a8e950447R2873-R2889
and use only client wrapper:
1877695#diff-3bdff46f360deb2937ae725b5117a2462cf0bcaaff86400d08179c652a2ce2f3R2653
but its not possible right now because if we use cache wrapping, interfaces of the cache.Cache and authclient.ClientI must be compatible
interface ReadRemoteProxyAccessPoint {
GetAutoupdateConfig(ctx context.Context) (*autoupdate.AutoupdateConfig, error)
GetAutoupdateVersion(ctx context.Context) (*autoupdate.AutoupdateVersion, error)
}
type RemoteProxyAccessPoint interface {
ReadRemoteProxyAccessPoint
accessPoint
}
func NewRemoteProxyWrapper(base RemoteProxyAccessPoint, cache ReadRemoteProxyAccessPoint) RemoteProxyAccessPoint {...}
// newLocalCacheForRemoteProxy returns new instance of access point configured for a remote proxy.
func (process *TeleportProcess) newLocalCacheForRemoteProxy(clt authclient.ClientI, cacheName []string) (authclient.RemoteProxyAccessPoint, error) {
// if caching is disabled, return access point
if !process.Config.CachePolicy.Enabled {
return clt, nil
}
cache, err := process.NewLocalCache(clt, cache.ForRemoteProxy, cacheName)
if err != nil {
return nil, trace.Wrap(err)
}
return authclient.NewRemoteProxyWrapper(clt, cache), nil
}|
closed in prior to several PRs described in #45617 (review) |
In this PR implemented new resources for autoupdate configuration and version store with enabled cache on proxy side to be able serve these resources without making requests to auth service.
Also added commands for tctl edit/get/create
Related: #39805
changelog: Added resources for autoupdate (config and version)