-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
chore(cmp): refactor and test plugin discovery #20217
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
🔴 Preview Environment stopped on BunnyshellSee: Environment Details | Pipeline Logs Available commands (reply to this comment):
|
✅ Preview Environment created on Bunnyshell but will not be auto-deployedSee: Environment Details Available commands (reply to this comment):
|
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #20217 +/- ##
=========================================
Coverage ? 55.98%
=========================================
Files ? 322
Lines ? 44569
Branches ? 0
=========================================
Hits ? 24951
Misses ? 17047
Partials ? 2571 ☔ View full report in Codecov by Sentry. |
@CodiumAI-Agent /review |
PR Reviewer Guide 🔍(Review updated until commit cf553e6)Here are some key observations to aid the review process:
|
// check if the given plugin supports the repo | ||
conn, cmpClient, connFound = cmpSupports(ctx, pluginSockFilePath, appPath, repoPath, fmt.Sprintf("%v.sock", pluginName), env, tarExcludedGlobs, true) | ||
if !connFound { | ||
c := newSocketCMPClientConstructorForPluginName(pluginSockFilePath, pluginName) |
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 if I am understanding it correctly but this PR introduces the new CMPClientConstructor
interface however it seems that it is impossible to use a different implementation than the socketCMPClientConstructor
. Not sure if this was intentional, but it would be great if we could enable the flexibility to use different CMPClientConstructor
implementations. This could help simplifying the CMP as a Service PR.
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 that it is impossible to use a different implementation
The only other implementation is the mock implementation used for testing.
The other option would have been to have (un)namedCMPSupports
accept a getClient
function, but the code just looked ickier. I could go either way.
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 wonder if the e2e test include plugin by default?
@@ -297,11 +297,11 @@ func (s *Service) matchRepositoryGeneric(stream MatchRepositoryStream) error { | |||
return fmt.Errorf("match repository error receiving stream: %w", err) | |||
} | |||
|
|||
isSupported, isDiscoveryEnabled, err := s.matchRepository(bufferedCtx, workDir, metadata.GetEnv(), metadata.GetAppRelPath()) |
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 is nice! I felt isDiscoveryEnabled
and cfg.IsDiscoveryConfigured
were redundant upon reading these code the first time.
// If discovery isn't configured, assume the CMP supports the plugin since it was explicitly named. | ||
return cmpClient, closer | ||
} | ||
usePlugin := cmpSupportsForClient(ctx, cmpClient, appPath, repoPath, env, tarExcludedGlobs) |
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.
For named plugin, do you think we should still invoke matchRepositoryCMP
? For efficiency, should we just invoke matchRepositoryCMP
for unnamed plugin that has discovery functionality configured?
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 to. Even if a plugin is named, if it failed any configured discovery rule, we'll refuse to use it. We did this when introducing plugin.name
because some people may have used discovery rules as a security mechanism, and we wouldn't want to allow users to bypass that check.
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.
Noted!
matchRepoStream, err := client.MatchRepository(ctx, grpc_retry.Disable()) | ||
// namedCMPSupports will return a client for the named plugin if it supports the given repository. It will also return | ||
// a closer for the connection. | ||
func namedCMPSupports(ctx context.Context, c CMPClientConstructor, appPath, repoPath string, env, tarExcludedGlobs []string) (pluginclient.ConfigManagementPluginServiceClient, io.Closer) { |
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.
nitpick on the consistency of return types ordering, DetectConfigManagementPlugin
return io.Closer, pluginclient.ConfigManagementPluginServiceClient
but the newly introduced functions (namedCMPSupports
, unnamedCMPSupports
, and getClientForFilepath
) return pluginclient.ConfigManagementPluginServiceClient, io.Closer
.
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.
Updated DetectConfigManagementPlugin
. I think client, closer
is the more common convention in the code base.
util/app/discovery/discovery.go
Outdated
|
||
isSupported, isDiscoveryEnabled, err := matchRepositoryCMP(ctx, appPath, repoPath, cmpClient, env, tarExcludedGlobs) | ||
// matchRepositoryCMP will send the repoPath to the cmp-server. The cmp-server will |
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 this docs is for matchRepositoryCMP
function
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
LGTM |
Persistent review updated to latest commit cf553e6 |
// Deprecated: Use the IsDiscoveryConfigured field from the CheckPluginConfigurationResponse instead. Argo CD no | ||
// longer uses an expensive MatchRepository service to determine if discovery is enabled. Instead, we | ||
// make a relatively cheap pre-flight request to the CheckPluginConfiguration service. We'll leave this | ||
// field here to avoid errors on mismatched repo-server and cmp-server versions. | ||
bool isDiscoveryEnabled = 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.
Do we use a strict parsing mode for protobuf where unrecognized fields would trigger error?
Plugin discovery logic is complicated and has resulted in difficult to diagnose bugs.
This PR makes a few changes:
RepositoryResponse.IsDiscoveryEnabled
field. No code actually uses that field anymore since we do a pre-flight CMP request to determine whether it has discovery enabled.cmpSupports
intonamedCMPSupports
andunnamedCMPSupports
. ReadingcmpSupports
was difficult, because thenamedPlugin
parameter implied more than the name suggested. Specifically, whennamedPlugin == false
, we could assume that the app spec did not contain a plugin.name. By using two different functions with two different names, we make it very clear that one is for use when the plugin name is specified, and the other is used when the plugin name is not specified.unnamedCMPSupports
andnamedCMPSupports
. I'd love to test all the way up toDetectConfigManagementPlugin
, but I think that would require more mock logic than I'm comfortable with.