Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ coverage
test/fixtures/**/*/.build
test/fixtures/**/*/Package.resolved
scripts/Brewfile.lock.json
test/fixtures/**/go.sum
test/fixtures/**/go.sum
cliv2/labsPlugins/*.so
4 changes: 4 additions & 0 deletions cliv2/cmd/cliv2/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ import (

cli_errors "github.com/snyk/cli/cliv2/internal/errors"
"github.com/snyk/cli/cliv2/pkg/basic_workflows"

// labsWorkflow "github.com/snyk/labs-cli-extension/pkg/labs"
labsWorkflow "github.com/snyk/cli/cliv2/pkg/labs"
)

var internalOS string
Expand Down Expand Up @@ -570,6 +573,7 @@ func MainWithErrorCode() (int, []error) {
globalEngine.AddExtensionInitializer(workflows.InitConnectivityCheckWorkflow)
globalEngine.AddExtensionInitializer(localworkflows.InitCodeWorkflow)
globalEngine.AddExtensionInitializer(ignoreworkflow.InitIgnoreWorkflows)
globalEngine.AddExtensionInitializer(labsWorkflow.InitLabsWorkflow)

// init engine
err = globalEngine.Init()
Expand Down
94 changes: 94 additions & 0 deletions cliv2/labsPlugins/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

import (
"encoding/json"
"strings"

"github.com/rs/zerolog"
"github.com/snyk/go-application-framework/pkg/configuration"
"github.com/snyk/go-application-framework/pkg/workflow"
"github.com/spf13/pflag"
)

const (
pluginPath = "plugin-path"
pluginArgument = "plugin-args"
pluginWorkflowName = "plugin-workflow"
)


type MyObject struct {
TestField string `json:"test"`
TestBoolField bool `json:"bool"`
DepGraphPayload `json:"data"`
}
type DepGraphPayload map[string]any


var WORKFLOWID_PLUGIN workflow.Identifier = workflow.NewWorkflowIdentifier(pluginWorkflowName)
var depGraphWorkflowID workflow.Identifier = workflow.NewWorkflowIdentifier("depgraph")
func PluginWorkflowEntryPoint(invocationCtx workflow.InvocationContext, data []workflow.Data) (output []workflow.Data, err error) {
config := invocationCtx.GetConfiguration()
logger := invocationCtx.GetEnhancedLogger()
engine := invocationCtx.GetEngine()
// fmt.Printf("In plugin workflow entry point with context %s", config.GetString(pluginPath))
// fmt.Println("")
// fmt.Println("plugin args:", config.GetString(pluginArgument))
pluginConfig := pflag.NewFlagSet(pluginWorkflowName, pflag.ExitOnError)
pluginConfig.Bool("args", false, "testing a bool")
pluginConfig.String("test", "whatever", "testing a string arg")

pluginConfig.Parse(strings.Split(config.GetString(pluginArgument), " "))
value, err := pluginConfig.GetString("test")
if err != nil {
logger.Err(err)
}

depgraphData, depGraphError := engine.InvokeWithConfig(depGraphWorkflowID, config)
if depGraphError != nil {
logger.Err(depGraphError).Msg("depgraph workflow failed.")
}

depGraphOutput, _ := depgraphData[0].GetPayload().([]byte)


jsonObject := MyObject{TestField: value}
boolValue,err := pluginConfig.GetBool("args")
if err != nil {
logger.Err(err)
}
jsonObject.TestBoolField = boolValue

var test DepGraphPayload
errors := json.Unmarshal(depGraphOutput, &test)
if errors != nil {
logger.Err(err).Msg("Error unmarshaling JSON")
}


jsonObject.DepGraphPayload = test
if err != nil {
logger.Err(err)
}

jsonData, err := json.Marshal(jsonObject)
if err != nil {
logger.Err(err)
}


pluginData := createWorkflowData(jsonData, "application/json", logger, config)

return []workflow.Data{pluginData}, nil
}

func createWorkflowData(data interface{}, contentType string, logger *zerolog.Logger, config configuration.Configuration) workflow.Data {
return workflow.NewData(
// use new type identifier when creating new data
workflow.NewTypeIdentifier(WORKFLOWID_PLUGIN, pluginWorkflowName),
contentType,
data,
workflow.WithLogger(logger),
workflow.WithConfiguration(config),
)
}
56 changes: 56 additions & 0 deletions cliv2/pkg/labs/labs_workflow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package labs

import (
"plugin"

"github.com/snyk/go-application-framework/pkg/workflow"
"github.com/spf13/pflag"
)

const (
labsWorkflowName = "labs"
jsonFlag = "json"
pluginPath = "plugin-path"
pluginArgs = "plugin-args"
)

var WORKFLOWID_LABS workflow.Identifier = workflow.NewWorkflowIdentifier(labsWorkflowName)

func InitLabsWorkflow(engine workflow.Engine) error {
// initialise workflow configuration
labsConfig := pflag.NewFlagSet(labsWorkflowName, pflag.ExitOnError)
labsConfig.String(pluginPath, "anypath", "Path to plugin file.")
labsConfig.Bool(jsonFlag, false, "output in json format")
labsConfig.String(pluginArgs, "", "Args for the plugin")
// register workflow with engine
_, err := engine.Register(WORKFLOWID_LABS, workflow.ConfigurationOptionsFromFlagset(labsConfig), labsWorkflowEntryPoint)

return err
}

func labsWorkflowEntryPoint(invocationCtx workflow.InvocationContext, data []workflow.Data) (output []workflow.Data, err error) {
config := invocationCtx.GetConfiguration()
logger := invocationCtx.GetEnhancedLogger()

pluginPath := config.GetString(pluginPath)

// 1. Load the precompiled .so file
p, err := plugin.Open(pluginPath)
if err != nil {
logger.Err(err).Msg("could not open plugin")
}

// 2. Look up a function ("symbol") in the plugin
pluginWorkflowEntryPoint, err := p.Lookup("PluginWorkflowEntryPoint")
if err != nil {
logger.Err(err).Msg("symbol is not the correct function type")
}
// 3. Call the function from the plugin
pluginOutput, err := pluginWorkflowEntryPoint.(func(workflow.InvocationContext, []workflow.Data) (output []workflow.Data, err error))(invocationCtx, data)
if err != nil {
logger.Err(err).Msg("Plugin workflow entry point failed")
}

return pluginOutput, err

}