Skip to content

Commit

Permalink
add nodejs and python providers
Browse files Browse the repository at this point in the history
Signed-off-by: Emily McMullan <[email protected]>
  • Loading branch information
eemcmullan committed May 1, 2024
1 parent b497577 commit ab80bc1
Showing 1 changed file with 113 additions and 8 deletions.
121 changes: 113 additions & 8 deletions cmd/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ var (
)

const (
javaProvider = "java"
goProvider = "go"
javaProvider = "java"
goProvider = "go"
pythonProvider = "python"
nodeJSProvider = "javascript"
)

// kantra analyze flags
Expand All @@ -76,6 +78,7 @@ type analyzeCommand struct {
noProxy string
contextLines int
incidentSelector string
depFolders []string

// tempDirs list of temporary dirs created, used for cleanup
tempDirs []string
Expand Down Expand Up @@ -213,6 +216,7 @@ func NewAnalyzeCmd(log logr.Logger) *cobra.Command {
analyzeCommand.Flags().StringVar(&analyzeCmd.noProxy, "no-proxy", loadEnvInsensitive("no_proxy"), "proxy excluded URLs (relevant only with proxy)")
analyzeCommand.Flags().IntVar(&analyzeCmd.contextLines, "context-lines", 100, "number of lines of source code to include in the output for each incident")
analyzeCommand.Flags().StringVar(&analyzeCmd.incidentSelector, "incident-selector", "", "an expression to select incidents based on custom variables. ex: (!package=io.konveyor.demo.config-utils)")
analyzeCommand.Flags().StringArrayVar(&analyzeCmd.depFolders, "dependency-folders", []string{}, "directory for dependencies")

return analyzeCommand
}
Expand Down Expand Up @@ -267,6 +271,17 @@ func (a *analyzeCommand) Validate() error {
SourceMountPath = path.Join(SourceMountPath, filepath.Base(a.input))
a.isFileInput = true
}
if len(a.depFolders) != 0 {
for i := range a.depFolders {
stat, err := os.Stat(a.depFolders[i])
if err != nil {
return fmt.Errorf("%w failed to stat dependency folder %v", err, a.depFolders[i])
}
if stat != nil && !stat.IsDir() {
return fmt.Errorf("depdendecy folder %v is not a directory", a.depFolders[i])
}
}
}
if a.mode != string(provider.FullAnalysisMode) &&
a.mode != string(provider.SourceOnlyAnalysisMode) {
return fmt.Errorf("mode must be one of 'full' or 'source-only'")
Expand Down Expand Up @@ -446,6 +461,21 @@ func listOptionsFromLabels(sl []string, label string) {
}
}

func (a *analyzeCommand) getDepsFolders() (map[string]string, []string) {
vols := map[string]string{}
dependencyFolders := []string{}
if len(a.depFolders) != 0 {
for i := range a.depFolders {
newDepPath := path.Join(InputPath, fmt.Sprintf("deps%v", i))
vols[a.depFolders[i]] = newDepPath
dependencyFolders = append(dependencyFolders, newDepPath)
}
return vols, dependencyFolders
}

return nil, nil
}

func (a *analyzeCommand) getConfigVolumes(providers []string, ports map[string]int) (map[string]string, error) {
tempDir, err := os.MkdirTemp("", "analyze-config-")
if err != nil {
Expand All @@ -457,13 +487,21 @@ func (a *analyzeCommand) getConfigVolumes(providers []string, ports map[string]i

var foundJava bool
var foundGolang bool
var foundPython bool
var foundNode bool
for _, p := range providers {
if p == javaProvider {
foundJava = true
}
if p == goProvider {
foundGolang = true
}
if p == pythonProvider {
foundPython = true
}
if p == nodeJSProvider {
foundNode = true
}
}
// TODO (pgaikwad): binaries don't work with alizer right now, we need to revisit this
if !foundJava && a.isFileInput {
Expand Down Expand Up @@ -522,6 +560,46 @@ func (a *analyzeCommand) getConfigVolumes(providers []string, ports map[string]i
},
}

pythonConfig := provider.Config{
Name: pythonProvider,
Address: fmt.Sprintf("0.0.0.0:%v", ports[pythonProvider]),
InitConfig: []provider.InitConfig{
{
AnalysisMode: provider.SourceOnlyAnalysisMode,
ProviderSpecificConfig: map[string]interface{}{
"lspServerName": "generic",
"workspaceFolders": []string{fmt.Sprintf("file://%s", otherProvsMountPath)},
provider.LspServerPathConfigKey: "/usr/local/bin/pylsp",
},
},
},
}

nodeJSConfig := provider.Config{
Name: nodeJSProvider,
Address: fmt.Sprintf("0.0.0.0:%v", ports[nodeJSProvider]),
InitConfig: []provider.InitConfig{
{
AnalysisMode: provider.SourceOnlyAnalysisMode,
ProviderSpecificConfig: map[string]interface{}{
"lspServerName": "nodejs",
"workspaceFolders": []string{fmt.Sprintf("file://%s", otherProvsMountPath)},
provider.LspServerPathConfigKey: "/usr/local/bin/typescript-language-server",
},
},
},
}

vols, dependencyFolders := a.getDepsFolders()
if len(dependencyFolders) != 0 {
if providers[0] == pythonProvider {
pythonConfig.InitConfig[0].ProviderSpecificConfig["dependencyFolders"] = dependencyFolders
}
if providers[0] == nodeJSProvider {
nodeJSConfig.InitConfig[0].ProviderSpecificConfig["dependencyFolders"] = dependencyFolders
}
}

provConfig := []provider.Config{
{
Name: "builtin",
Expand All @@ -539,6 +617,12 @@ func (a *analyzeCommand) getConfigVolumes(providers []string, ports map[string]i
if foundGolang && a.mode == string(provider.FullAnalysisMode) {
provConfig = append(provConfig, goConfig)
}
if foundPython {
provConfig = append(provConfig, pythonConfig)
}
if foundNode {
provConfig = append(provConfig, nodeJSConfig)
}

// Set proxy to providers
if a.httpProxy != "" || a.httpsProxy != "" {
Expand All @@ -564,9 +648,12 @@ func (a *analyzeCommand) getConfigVolumes(providers []string, ports map[string]i
return nil, err
}

vols := map[string]string{
settingsVols := map[string]string{
tempDir: ConfigMountPath,
}
if len(vols) != 0 {
maps.Copy(settingsVols, vols)
}

// attempt to create a .m2 directory we can use to speed things a bit
// this will be shared between analyze and dep command containers
Expand All @@ -582,7 +669,7 @@ func (a *analyzeCommand) getConfigVolumes(providers []string, ports map[string]i
}
}

return vols, nil
return settingsVols, nil
}

func (a *analyzeCommand) getRulesVolumes() (map[string]string, error) {
Expand Down Expand Up @@ -794,7 +881,11 @@ func (a *analyzeCommand) RunProviders(ctx context.Context, networkName string, v
// application source code
volName: SourceMountPath,
}
// this will make more sense when we have more than 2 supported providers
vols, _ := a.getDepsFolders()
if len(vols) != 0 {
maps.Copy(volumes, vols)
}

var providerImage string
switch providers[0] {
case javaProvider:
Expand All @@ -803,6 +894,12 @@ func (a *analyzeCommand) RunProviders(ctx context.Context, networkName string, v
case goProvider:
providerImage = Settings.GenericProviderImage
providerPorts[goProvider] = port
case pythonProvider:
providerImage = Settings.GenericProviderImage
providerPorts[pythonProvider] = port
case nodeJSProvider:
providerImage = Settings.GenericProviderImage
providerPorts[nodeJSProvider] = port
default:
return nil, fmt.Errorf("unable to run unsupported provider %v", providers[0])
}
Expand Down Expand Up @@ -876,6 +973,7 @@ func (a *analyzeCommand) RunAnalysis(ctx context.Context, xmlOutputDir string, v
if providers[0] != javaProvider {
a.enableDefaultRulesets = false
}

if a.enableDefaultRulesets {
args = append(args,
fmt.Sprintf("--rules=%s/", RulesetPath))
Expand All @@ -896,7 +994,9 @@ func (a *analyzeCommand) RunAnalysis(ctx context.Context, xmlOutputDir string, v
args = append(args, "--jaeger-endpoint")
args = append(args, a.jaegerEndpoint)
}
if !a.analyzeKnownLibraries {

// python and node providers do not yet support dep analysis
if !a.analyzeKnownLibraries && (providers[0] != pythonProvider && providers[0] != nodeJSProvider) {
args = append(args,
fmt.Sprintf("--dep-label-selector=(!%s=open-source)", provider.DepSourceLabel))
}
Expand All @@ -907,9 +1007,14 @@ func (a *analyzeCommand) RunAnalysis(ctx context.Context, xmlOutputDir string, v
if labelSelector != "" {
args = append(args, fmt.Sprintf("--label-selector=%s", labelSelector))
}

if a.mode == string(provider.FullAnalysisMode) {
a.log.Info("running dependency retrieval during analysis")
args = append(args, fmt.Sprintf("--dep-output-file=%s", DepsOutputMountPath))
if providers[0] == pythonProvider || providers[0] == nodeJSProvider {
a.mode = string(provider.SourceOnlyAnalysisMode)
} else {
a.log.Info("running dependency retrieval during analysis")
args = append(args, fmt.Sprintf("--dep-output-file=%s", DepsOutputMountPath))
}
}

analysisLogFilePath := filepath.Join(a.output, "analysis.log")
Expand Down

0 comments on commit ab80bc1

Please sign in to comment.