diff --git a/conf/conf.go b/conf/conf.go index 330d0ab..8f0eda4 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -5,6 +5,7 @@ import "sync" type Config struct { LokiURL string ExecutionID string + Timeout int WorkflowID string } diff --git a/go.mod b/go.mod index 4fcb4b3..e3574e5 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module oc-monitord go 1.22.0 require ( - cloud.o-forge.io/core/oc-lib v0.0.0-20240807134103-0ec80473ccf7 + cloud.o-forge.io/core/oc-lib v0.0.0-20240822081914-4abf59a10d97 github.com/akamensky/argparse v1.4.0 github.com/goraz/onion v0.1.3 github.com/nats-io/nats-server/v2 v2.10.18 @@ -25,6 +25,10 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/montanaflynn/stats v0.7.1 // indirect + github.com/nats-io/nats.go v1.37.0 // indirect + github.com/nats-io/nkeys v0.4.7 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect diff --git a/go.sum b/go.sum index b2a7e93..bacfe41 100644 --- a/go.sum +++ b/go.sum @@ -34,6 +34,8 @@ cloud.o-forge.io/core/oc-lib v0.0.0-20240807131622-6df71bde1d5e h1:LIZ2Mxwd9NQD2 cloud.o-forge.io/core/oc-lib v0.0.0-20240807131622-6df71bde1d5e/go.mod h1:V5EL+NV2s9P1/BcFm3/icfLeBYVVMLl1Z0F0eecJZGo= cloud.o-forge.io/core/oc-lib v0.0.0-20240807134103-0ec80473ccf7 h1:Q9fFnvEf0XzQvnCZ815wTRQ6zP/efU9RUcKXgcDoCng= cloud.o-forge.io/core/oc-lib v0.0.0-20240807134103-0ec80473ccf7/go.mod h1:V5EL+NV2s9P1/BcFm3/icfLeBYVVMLl1Z0F0eecJZGo= +cloud.o-forge.io/core/oc-lib v0.0.0-20240822081914-4abf59a10d97 h1:6tbeTQvRnD0vDUl+5SLMgAh9ukjGxQ9WKjNcvvxN7cQ= +cloud.o-forge.io/core/oc-lib v0.0.0-20240822081914-4abf59a10d97/go.mod h1:1hhYh5QWAbYw9cKplQ0ZD9PMgU8t6gPqiYF8sldv1HU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc= github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA= @@ -97,6 +99,12 @@ github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8 github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/nats-io/nats-server/v2 v2.10.18 h1:tRdZmBuWKVAFYtayqlBB2BuCHNGAQPvoQIXOKwU3WSM= github.com/nats-io/nats-server/v2 v2.10.18/go.mod h1:97Qyg7YydD8blKlR8yBsUlPlWyZKjA7Bp5cl3MUE9K8= +github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE= +github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= +github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= +github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nwtgck/go-fakelish v0.1.3 h1:bA8/xa9hQmzppexIhBvdmztcd/PJ4SPuAUTBdMKZ8G4= github.com/nwtgck/go-fakelish v0.1.3/go.mod h1:2HC44/OwVWwOa/g3+P2jUM3FEHQ0ya4gyCSU19PPd3Y= github.com/ogier/pflag v0.0.1/go.mod h1:zkFki7tvTa0tafRvTBIZTvzYyAu6kQhPZFnshFFPE+g= @@ -104,6 +112,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= diff --git a/main.go b/main.go index 019ff28..0ec5d26 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "regexp" + "strconv" "strings" "sync" @@ -19,6 +20,7 @@ import ( "cloud.o-forge.io/core/oc-lib/logs" "cloud.o-forge.io/core/oc-lib/models/workflow_execution" + "cloud.o-forge.io/core/oc-lib/tools" "github.com/akamensky/argparse" "github.com/google/uuid" @@ -78,7 +80,7 @@ func main() { logger.Error().Msg("Could not retrieve workflow " + conf.GetConfig().WorkflowID + " from oc-catalog API") } - argo_file_path, err := new_wf.ExportToArgo() + argo_file_path, err := new_wf.ExportToArgo(conf.GetConfig().Timeout) if err != nil { logger.Error().Msg("Could not create the Argo file for " + conf.GetConfig().WorkflowID) logger.Error().Msg(err.Error()) @@ -202,23 +204,31 @@ func loadConfig(is_k8s bool, parser *argparse.Parser) { func setConf(is_k8s bool, o *onion.Onion, parser *argparse.Parser) { if is_k8s { conf.GetConfig().LokiURL = o.GetStringDefault("lokiurl", "http://127.0.0.1:3100") + i, err := strconv.Atoi(o.GetString("timeout")) + if err == nil { + conf.GetConfig().Timeout = i + } else { + logger.Error().Msg("Could not parse timeout, using default value") + } conf.GetConfig().ExecutionID = o.GetString("workflow") mongo := o.GetStringDefault("mongourl", "mongodb://127.0.0.1:27017") db := o.GetStringDefault("database", "DC_myDC") - oclib.SetConfig(mongo, db) + tools.SetConfig(mongo, db, "") } else { url := parser.String("u", "url", &argparse.Options{Required: true, Default: "http://127.0.0.1:3100", Help: "Url to the Loki database logs will be sent to"}) workflow := parser.String("w", "workflow", &argparse.Options{Required: true, Help: "Execution ID of the workflow to request from oc-catalog API"}) mongo := parser.String("m", "mongo", &argparse.Options{Required: true, Default: "mongodb://127.0.0.1:27017", Help: "URL to reach the MongoDB"}) db := parser.String("d", "database", &argparse.Options{Required: true, Default: "DC_myDC", Help: "Name of the database to query in MongoDB"}) + timeout := parser.Int("t", "timeout", &argparse.Options{Required: false, Default: -1, Help: "Timeout for the execution of the workflow"}) err := parser.Parse(os.Args) if err != nil { fmt.Println(parser.Usage(err)) os.Exit(1) } conf.GetConfig().LokiURL = *url + conf.GetConfig().Timeout = *timeout conf.GetConfig().ExecutionID = *workflow - oclib.SetConfig(*mongo, *db) + tools.SetConfig(*mongo, *db, "") } } diff --git a/oc-monitord b/oc-monitord index 1e861ac..a75bb34 100755 Binary files a/oc-monitord and b/oc-monitord differ diff --git a/workflow_builder/argo_builder.go b/workflow_builder/argo_builder.go index 850375e..8abf13e 100644 --- a/workflow_builder/argo_builder.go +++ b/workflow_builder/argo_builder.go @@ -20,6 +20,7 @@ import ( type ArgoBuilder struct { graph graph.Graph Workflow Workflow + Timeout int } type Workflow struct { @@ -36,13 +37,16 @@ type Spec struct { Arguments []Parameter `yaml:"arguments,omitempty"` Volumes []VolumeClaimTemplate `yaml:"volumeClaimTemplates,omitempty"` Templates []Template `yaml:"templates"` + Timeout int `yaml:"activeDeadlineSeconds,omitempty"` } func (b *ArgoBuilder) CreateDAG() (string, error) { - b.createTemplates() b.createDAGstep() b.createVolumes() + if b.Timeout > 0 { + b.Workflow.Spec.Timeout = b.Timeout + } b.Workflow.Spec.Entrypoint = "dag" b.Workflow.ApiVersion = "argoproj.io/v1alpha1" b.Workflow.Kind = "Workflow" diff --git a/workflow_builder/graph.go b/workflow_builder/graph.go index b33bff1..0beb9e2 100644 --- a/workflow_builder/graph.go +++ b/workflow_builder/graph.go @@ -39,14 +39,14 @@ func (w *WorflowDB) getWorkflow(workflow_id string) (workflow *workflow.Workflow return new_wf, nil } -func (w *WorflowDB) ExportToArgo() (string, error) { +func (w *WorflowDB) ExportToArgo(timeout int) (string, error) { logger := oclib.GetLogger() if len(w.Workflow.Name) == 0 || w.Workflow.Graph == nil { return "", fmt.Errorf("can't export a graph that has not been loaded yet") } - argo_builder := ArgoBuilder{graph: *w.Workflow.Graph} + argo_builder := ArgoBuilder{graph: *w.Workflow.Graph, Timeout: timeout} filename, err := argo_builder.CreateDAG() if err != nil { logger.Error().Msg("Could not create the argo file for " + w.Workflow.Name)