From 650c5238fcde3d4f9708d751aec1f534128f505f Mon Sep 17 00:00:00 2001 From: Soumya Ghosh Dastidar Date: Fri, 18 Nov 2022 13:24:17 +0530 Subject: [PATCH] feat: add support for plugin name in cmpV2 Signed-off-by: Soumya Ghosh Dastidar --- reposerver/repository/repository.go | 28 ++++--- util/app/discovery/discovery.go | 113 ++++++++++++++++------------ 2 files changed, 79 insertions(+), 62 deletions(-) diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 8b31f660f78c7..9fe77307f7b3d 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -68,7 +68,6 @@ import ( const ( cachedManifestGenerationPrefix = "Manifest generation error (cached)" - pluginNotSupported = "config management plugin not supported." helmDepUpMarkerFile = ".argocd-helm-dep-up" allowConcurrencyFile = ".argocd-allow-concurrency" repoSourceFile = ".argocd-source.yaml" @@ -1045,15 +1044,25 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, k := kustomize.NewKustomizeApp(appPath, q.Repo.GetGitCreds(gitCredsStore), repoURL, kustomizeBinary) targetObjs, _, err = k.Build(q.ApplicationSource.Kustomize, q.KustomizeOptions, env) case v1alpha1.ApplicationSourceTypePlugin: + var plugin *v1alpha1.ConfigManagementPlugin if q.ApplicationSource.Plugin != nil && q.ApplicationSource.Plugin.Name != "" { + plugin = findPlugin(q.Plugins, q.ApplicationSource.Plugin.Name) + } + if plugin != nil { + // argocd-cm deprecated plugin is being used + targetObjs, err = runConfigManagementPlugin(appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore), plugin) log.WithFields(map[string]interface{}{ "application": q.AppName, "plugin": q.ApplicationSource.Plugin.Name, }).Warnf(common.ConfigMapPluginDeprecationWarning) - - targetObjs, err = runConfigManagementPlugin(appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore)) } else { - targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs) + // if the named plugin was not found in argocd-cm try sidecar plugin + pluginName := "" + if q.ApplicationSource.Plugin != nil { + pluginName = q.ApplicationSource.Plugin.Name + } + // if pluginName is provided it has to be `-` or just `` if plugin version is empty + targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, pluginName, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs) if err != nil { err = fmt.Errorf("plugin sidecar failed. %s", err.Error()) } @@ -1537,12 +1546,7 @@ func findPlugin(plugins []*v1alpha1.ConfigManagementPlugin, name string) *v1alph return nil } -func runConfigManagementPlugin(appPath, repoRoot string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds) ([]*unstructured.Unstructured, error) { - plugin := findPlugin(q.Plugins, q.ApplicationSource.Plugin.Name) - if plugin == nil { - return nil, fmt.Errorf(pluginNotSupported+" plugin name %s", q.ApplicationSource.Plugin.Name) - } - +func runConfigManagementPlugin(appPath, repoRoot string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, plugin *v1alpha1.ConfigManagementPlugin) ([]*unstructured.Unstructured, error) { // Plugins can request to lock the complete repository when they need to // use git client operations. if plugin.LockRepo { @@ -1612,7 +1616,7 @@ func getPluginEnvs(envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds gi return env, nil } -func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool, tarExcludedGlobs []string) ([]*unstructured.Unstructured, error) { +func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, pluginName string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool, tarExcludedGlobs []string) ([]*unstructured.Unstructured, error) { // compute variables. env, err := getPluginEnvs(envVars, q, creds, true) if err != nil { @@ -1620,7 +1624,7 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath st } // detect config management plugin server (sidecar) - conn, cmpClient, err := discovery.DetectConfigManagementPlugin(ctx, appPath, env, tarExcludedGlobs) + conn, cmpClient, err := discovery.DetectConfigManagementPlugin(ctx, appPath, pluginName, env, tarExcludedGlobs) if err != nil { return nil, err } diff --git a/util/app/discovery/discovery.go b/util/app/discovery/discovery.go index 84b4941654b9b..f0c20fecae432 100644 --- a/util/app/discovery/discovery.go +++ b/util/app/discovery/discovery.go @@ -33,7 +33,7 @@ func Discover(ctx context.Context, repoPath string, enableGenerateManifests map[ apps := make(map[string]string) // Check if it is CMP - conn, _, err := DetectConfigManagementPlugin(ctx, repoPath, []string{}, tarExcludedGlobs) + conn, _, err := DetectConfigManagementPlugin(ctx, repoPath, "", []string{}, tarExcludedGlobs) if err == nil { // Found CMP io.Close(conn) @@ -77,14 +77,16 @@ func AppType(ctx context.Context, path string, enableGenerateManifests map[strin return "Directory", nil } -// 1. list all plugins in /plugins folder -// 2. foreach plugin setup connection with respective cmp-server -// 3. check isSupported(path)? -// 4.a if no then close connection -// 4.b if yes then return conn for detected plugin -func DetectConfigManagementPlugin(ctx context.Context, repoPath string, env []string, tarExcludedGlobs []string) (io.Closer, pluginclient.ConfigManagementPluginServiceClient, error) { +// if pluginName is provided setup connection to that cmp-server +// else +// list all plugins in /plugins folder and foreach plugin +// check cmpSupports() +// if supported return conn for the cmp-server + +func DetectConfigManagementPlugin(ctx context.Context, repoPath, pluginName string, env []string, tarExcludedGlobs []string) (io.Closer, pluginclient.ConfigManagementPluginServiceClient, error) { var conn io.Closer var cmpClient pluginclient.ConfigManagementPluginServiceClient + var connFound bool pluginSockFilePath := common.GetPluginSockFilePath() log.WithFields(log.Fields{ @@ -92,52 +94,30 @@ func DetectConfigManagementPlugin(ctx context.Context, repoPath string, env []st common.SecurityCWEField: 775, }).Debugf("pluginSockFilePath is: %s", pluginSockFilePath) - files, err := os.ReadDir(pluginSockFilePath) - if err != nil { - return nil, nil, err - } - - var connFound bool - for _, file := range files { - if file.Type() == os.ModeSocket { - address := filepath.Join(pluginSockFilePath, file.Name()) - cmpclientset := pluginclient.NewConfigManagementPluginClientSet(address) - - conn, cmpClient, err = cmpclientset.NewConfigManagementPluginClient() - if err != nil { - log.WithFields(log.Fields{ - common.SecurityField: common.SecurityMedium, - common.SecurityCWEField: 775, - }).Errorf("error dialing to cmp-server for plugin %s, %v", file.Name(), err) - continue - } - - isSupported, err := matchRepositoryCMP(ctx, repoPath, cmpClient, env, tarExcludedGlobs) - if err != nil { - log.WithFields(log.Fields{ - common.SecurityField: common.SecurityMedium, - common.SecurityCWEField: 775, - }).Errorf("repository %s is not the match because %v", repoPath, err) - continue - } - - if !isSupported { - log.WithFields(log.Fields{ - common.SecurityField: common.SecurityLow, - common.SecurityCWEField: 775, - }).Debugf("Reponse from socket file %s is not supported", file.Name()) - io.Close(conn) - } else { - connFound = true - break + if pluginName != "" { + // check if the given plugin supports the repo + conn, cmpClient, connFound = cmpSupports(ctx, pluginSockFilePath, repoPath, fmt.Sprintf("%v.sock", pluginName), env, tarExcludedGlobs) + if !connFound { + return nil, nil, fmt.Errorf("Couldn't find cmp-server plugin with name %v supporting repository %s", pluginName, repoPath) + } + } else { + files, err := os.ReadDir(pluginSockFilePath) + if err != nil { + return nil, nil, err + } + for _, file := range files { + if file.Type() == os.ModeSocket { + conn, cmpClient, connFound = cmpSupports(ctx, pluginSockFilePath, repoPath, file.Name(), env, tarExcludedGlobs) + if connFound { + break + } } } + if !connFound { + return nil, nil, fmt.Errorf("Couldn't find cmp-server plugin supporting repository %s", repoPath) + } } - - if !connFound { - return nil, nil, fmt.Errorf("Couldn't find cmp-server plugin supporting repository %s", repoPath) - } - return conn, cmpClient, err + return conn, cmpClient, nil } // matchRepositoryCMP will send the repoPath to the cmp-server. The cmp-server will @@ -159,3 +139,36 @@ func matchRepositoryCMP(ctx context.Context, repoPath string, client pluginclien } return resp.GetIsSupported(), nil } + +func cmpSupports(ctx context.Context, pluginSockFilePath, repoPath, fileName string, env []string, tarExcludedGlobs []string) (io.Closer, pluginclient.ConfigManagementPluginServiceClient, bool) { + address := filepath.Join(pluginSockFilePath, fileName) + cmpclientset := pluginclient.NewConfigManagementPluginClientSet(address) + + conn, cmpClient, err := cmpclientset.NewConfigManagementPluginClient() + if err != nil { + log.WithFields(log.Fields{ + common.SecurityField: common.SecurityMedium, + common.SecurityCWEField: 775, + }).Errorf("error dialing to cmp-server for plugin %s, %v", fileName, err) + return nil, nil, false + } + + isSupported, err := matchRepositoryCMP(ctx, repoPath, cmpClient, env, tarExcludedGlobs) + if err != nil { + log.WithFields(log.Fields{ + common.SecurityField: common.SecurityMedium, + common.SecurityCWEField: 775, + }).Errorf("repository %s is not the match because %v", repoPath, err) + return nil, nil, false + } + + if !isSupported { + log.WithFields(log.Fields{ + common.SecurityField: common.SecurityLow, + common.SecurityCWEField: 775, + }).Debugf("Reponse from socket file %s is not supported", fileName) + io.Close(conn) + return nil, nil, false + } + return conn, cmpClient, true +}