Skip to content

Commit

Permalink
feat: add support for plugin name in cmpV2
Browse files Browse the repository at this point in the history
Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com>
  • Loading branch information
gdsoumya committed Nov 18, 2022
1 parent 2173b87 commit 650c523
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 62 deletions.
28 changes: 16 additions & 12 deletions reposerver/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 `<metadata.name>-<spec.version>` or just `<metadata.name>` 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())
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -1612,15 +1616,15 @@ 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 {
return nil, err
}

// 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
}
Expand Down
113 changes: 63 additions & 50 deletions util/app/discovery/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -77,67 +77,47 @@ 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{
common.SecurityField: common.SecurityLow,
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
Expand All @@ -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
}

0 comments on commit 650c523

Please sign in to comment.