Newer
Older
"forge.tedomum.net/kludge/leviathan/libs"
"forge.tedomum.net/kludge/leviathan/utils"
Target string
Workspace string
Workflow libs.Workflow
Options *libs.Options
Reports []string
DSL map[string]interface{}
func InitRunner(target string, options *libs.Options) (*Runner, error) {
runner.Workspace = path.Join(options.Environment.Workspaces, utils.CleanPath(target))
if _, err := os.Stat(runner.Workspace); os.IsNotExist(err) {
utils.Logger.Debug().Str("workspace", runner.Workspace).Msg("Create workspace folder")
if err = os.MkdirAll(runner.Workspace, 0700); err != nil {
// Init dsl with variables
runner.initDSL()
runner.initParams()
// Create .tmp directory in workspace
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
utils.Logger.Debug().Str("workspace", runner.Workspace).Msg("Create TMP folder")
if err = os.MkdirAll(tmpDir, 0700); err != nil {
return &runner, err
}
}
// Create reports directory in workspace
if _, err := os.Stat(reportsDir); os.IsNotExist(err) {
utils.Logger.Debug().Str("workspace", runner.Workspace).Msg("Create reports folder")
if err = os.MkdirAll(reportsDir, 0700); err != nil {
return &runner, err
}
}
// Add reports directory to whitelist
runner.Reports = append(runner.Reports, runner.Params["ReportsDir"])
// Try to import workflow
if !runner.importWorkflow() {
utils.Logger.Fatal().Str("workflow", runner.Options.Scan.Flow).Msg("Unable to import workflow")
// Check modules
for _, routine := range runner.Workflow.Routines {
for _, module := range routine.Modules {
if !utils.IsYamlValid(module, runner.Options.Environment.Modules) {
utils.Logger.Fatal().Str("module", module).Msg("Module invalid")
utils.Logger.Info().
Str("runner", r.Target).
Str("workflow", r.Workflow.Name).
Msg("Start runner")
for _, routine := range r.Workflow.Routines {
// Check for params in module
for _, param := range routine.Params {
for k, v := range param {
// Routine params do not override workflow and user params
if r.Params[k] == "" {
r.setParam(k, v)
}
}
}
// Start each modules
var wg sync.WaitGroup
p, _ := ants.NewPoolWithFunc(r.Options.Scan.Threads*10, func(m interface{}) {
wg.Done()
}, ants.WithPreAlloc(true))
defer p.Release()
if err := p.Invoke(module); err != nil {
utils.Logger.Error().Msg(err.Error())
}
if !r.Options.Scan.NoClean {
utils.Logger.Info().Str("workspace", r.Workspace).Msg("Clean workspace")
func (r *Runner) importWorkflow() bool {
fullPath := utils.CheckExistence(r.Options.Scan.Flow, r.Options.Environment.Workflows)
content, err := r.ParseTemplate(fullPath)
if err != nil {
utils.Logger.Error().Msg(err.Error())
return false
}
if err = yaml.Unmarshal(content, &r.Workflow); err != nil {
utils.Logger.Error().Str("workflow", fullPath).Msg(err.Error())
// Check validator
if !r.ValidateInputType() {
return false
}
// re-init params to handle Workflow params
r.initParams()
return true
}
func (r *Runner) startModule(moduleName string) {
utils.Logger.Info().Str("module", moduleName).Msg("Run module")
// Import module before executing it
m := libs.Module{}
fullPath := utils.CheckExistence(moduleName, r.Options.Environment.Modules)
content, _ := os.ReadFile(fullPath)
if err := yaml.Unmarshal(content, &m); err != nil {
utils.Logger.Error().Msg(err.Error())
return
}
for _, param := range m.Params {
for k, v := range param {
// Module params do not override workflow, routine and user params
if r.Params[k] == "" {
r.setParam(k, v)
}
for _, report := range m.Reports {
utils.Logger.Debug().Str("module", m.Name).Str("report", reportPath).Msg("Add report to the list")
r.Reports = append(r.Reports, utils.NormalizePath(reportPath))
if r.Options.Scan.Resume && len(m.Reports) != 0 {
skipModule := true
for _, report := range m.Reports {
if !utils.FileExists(r.ParseString(report)) {
skipModule = false
}
}
if skipModule {
utils.Logger.Info().Str("module", m.Name).Msg("skip module (--resume flag used)")
return
}
}
// Execute pre_run scripts
utils.Logger.Debug().Str("module", m.Name).Msg("Execute Pre_run scripts")
r.runScripts(m.PreRun)
}
utils.Logger.Debug().Str("module", m.Name).Msg("Execute step")
utils.Logger.Debug().Str("module", m.Name).Msg("Execute post_run scripts")
r.runScripts(m.PostRun)
}
}