diff --git a/association/stackconfig.go b/association/stackconfig.go index ad0b7ed..3a6db54 100644 --- a/association/stackconfig.go +++ b/association/stackconfig.go @@ -8,9 +8,11 @@ import ( "jtso/logger" "jtso/sqlite" "os" + "regexp" "strconv" "strings" "text/template" + "unicode" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" @@ -22,6 +24,54 @@ const PATH_PTX string = "/var/shared//telegraf/ptx/telegraf.d/" const PATH_ACX string = "/var/shared//telegraf/acx/telegraf.d/" const PATH_GRAFANA string = "/var/shared/grafana/dashboards/" +func CheckVersion(searchVersion string, routerVersion string) bool { + var operator string + + if len(searchVersion) > 2 { + // Search operator + if unicode.IsDigit(rune(searchVersion[0])) && unicode.IsDigit(rune(searchVersion[1])) { + operator = "==" + } else { + operator = searchVersion[0:2] + searchVersion = searchVersion[2:] + } + // Find out if routerVersion can be reduced + r, _ := regexp.Compile(searchVersion + "*") + result := r.FindString(routerVersion) + if result != "" { + routerVersion = result + } + switch operator { + case "==": + if strings.Compare(routerVersion, searchVersion) == 0 { + return true + } + + case ">>": + if strings.Compare(routerVersion, searchVersion) > 0 { + return true + } + case "<<": + if strings.Compare(routerVersion, searchVersion) < 0 { + return true + + } + case ">=": + if strings.Compare(routerVersion, searchVersion) >= 0 { + return true + } + case "<=": + if strings.Compare(routerVersion, searchVersion) <= 0 { + return true + } + default: + return false + } + } + return false + +} + func ConfigueStack(cfg *config.ConfigContainer, family string) error { logger.Log.Infof("Time to reconfigure JTS components for family %s", family) @@ -103,8 +153,7 @@ func ConfigueStack(cfg *config.ConfigContainer, family string) error { for p, rtrs := range cfgHierarchy[f] { var filenames []Config - var perVersion map[string][]*sqlite.RtrEntry - perVersion = make(map[string][]*sqlite.RtrEntry) + perVersion := make(map[string][]*sqlite.RtrEntry) // extract definition of the profile switch f { @@ -132,28 +181,30 @@ func ConfigueStack(cfg *config.ConfigContainer, family string) error { // Create the map - per version > routers for _, r := range rtrs { - keep_version := "all" - save_conf := "" + confToApply := "" + defaultConfig := "" + for _, c := range filenames { - if c.Version != "all" { - comp := strings.Compare(r.Version, c.Version) - if comp == -1 { - if keep_version != "all" { - comp := strings.Compare(c.Version, keep_version) - if comp == -1 { - keep_version = c.Version - save_conf = c.Config - } - } else { - keep_version = c.Version - save_conf = c.Config - } - } + // Save all config if present as a fallback solution if specific version not found + if c.Version == "all" { + defaultConfig = c.Config } else { - save_conf = c.Config + result := CheckVersion(c.Version, r.Version) + if result && (confToApply == "") { + confToApply = c.Config + } + } + } + + if confToApply != "" { + perVersion[confToApply] = append(perVersion[confToApply], r) + logger.Log.Infof("Router %s version %s will use configuration %s", r.Shortname, r.Version, confToApply) + } else { + if defaultConfig != "" { + perVersion[defaultConfig] = append(perVersion[defaultConfig], r) + logger.Log.Infof("Router %s version %s will use configuration %s", r.Shortname, r.Version, defaultConfig) } } - perVersion[save_conf] = append(perVersion[save_conf], r) } for filename, v := range perVersion { diff --git a/config/config.go b/config/config.go index 07a99e5..87f708d 100644 --- a/config/config.go +++ b/config/config.go @@ -10,6 +10,8 @@ import ( "github.com/spf13/viper" ) +const JTSO_VERSION string = "1.0.1" + type PortalConfig struct { Https bool ServerCrt string diff --git a/html/templates/index.html b/html/templates/index.html index edca2bb..7ca619c 100644 --- a/html/templates/index.html +++ b/html/templates/index.html @@ -550,13 +550,13 @@

Stack Overview


+

JTS Version - {{.JTS_VERS}} - JTSO Version {{.JTSO_VERS}} - JTS Telegraf {{.JTS_TELE_VERS}}

- \ No newline at end of file diff --git a/portal/webapp.go b/portal/webapp.go index 01c415e..a055bbe 100644 --- a/portal/webapp.go +++ b/portal/webapp.go @@ -1,6 +1,7 @@ package portal import ( + "bufio" "context" "encoding/json" "fmt" @@ -15,6 +16,7 @@ import ( "jtso/sqlite" "jtso/worker" "net/http" + "os" "strconv" "strings" "time" @@ -27,6 +29,8 @@ import ( ) const PATH_CERT string = "/var/cert/" +const PATH_JTS_VERS string = "/etc/jtso/openjts.version" +const PATH_TELE_VERS string = "/var/metadata/telegraf.version" type WebApp struct { listen string @@ -186,7 +190,46 @@ func routeIndex(c echo.Context) error { } } - return c.Render(http.StatusOK, "index.html", map[string]interface{}{"TeleVmx": teleVmx, "TeleMx": teleMx, "TelePtx": telePtx, "TeleAcx": teleAcx, "Grafana": grafana, "Kapacitor": kapacitor, "Influx": influx, "Jtso": jtso, "NumVMX": numVMX, "NumMX": numMX, "NumPTX": numPTX, "NumACX": numACX, "GrafanaPort": grafanaPort}) + // Retrieve module's version + jtsoVersion := config.JTSO_VERSION + jtsVersion := "N/A" + teleVersion := "N/A" + + // Open the OpenJTS version's file + file_jts, err := os.Open(PATH_JTS_VERS) + if err != nil { + logger.Log.Errorf("Unable to open %s file: %v", PATH_JTS_VERS, err) + } else { + defer file_jts.Close() + scanner := bufio.NewScanner(file_jts) + if scanner.Scan() { + jtsVersion = scanner.Text() + } + // Check for any errors during scanning + if err := scanner.Err(); err != nil { + logger.Log.Errorf("Unable to parse %s file: %v", PATH_JTS_VERS, err) + } + } + + // Open the Telegraf version's file + file_tele, err := os.Open(PATH_TELE_VERS) + if err != nil { + logger.Log.Errorf("Unable to open %s file: %v", PATH_TELE_VERS, err) + } else { + defer file_tele.Close() + scanner := bufio.NewScanner(file_tele) + if scanner.Scan() { + teleVersion = scanner.Text() + } + // Check for any errors during scanning + if err := scanner.Err(); err != nil { + logger.Log.Errorf("Unable to parse %s file: %v", PATH_TELE_VERS, err) + } + } + + return c.Render(http.StatusOK, "index.html", map[string]interface{}{"TeleVmx": teleVmx, "TeleMx": teleMx, "TelePtx": telePtx, "TeleAcx": teleAcx, + "Grafana": grafana, "Kapacitor": kapacitor, "Influx": influx, "Jtso": jtso, "NumVMX": numVMX, "NumMX": numMX, "NumPTX": numPTX, "NumACX": numACX, + "GrafanaPort": grafanaPort, "JTS_VERS": jtsVersion, "JTSO_VERS": jtsoVersion, "JTS_TELE_VERS": teleVersion}) } func routeRouters(c echo.Context) error { @@ -348,6 +391,26 @@ func routeDelRouter(c echo.Context) error { return c.JSON(http.StatusOK, Reply{Status: "OK", Msg: "Router deleted"}) } +func checkRouterSupport(filenames []association.Config, routerVersion string) bool { + confToApply := "" + defaultConfig := "" + for _, c := range filenames { + // Save all config if present as a fallback solution if specific version not found + if c.Version == "all" { + defaultConfig = c.Config + } else { + result := association.CheckVersion(c.Version, routerVersion) + if result && (confToApply == "") { + return true + } + } + } + if defaultConfig != "" { + return true + } + return false +} + func routeAddProfile(c echo.Context) error { var err error var f bool @@ -370,39 +433,63 @@ func routeAddProfile(c echo.Context) error { } // Check if a profile can be attached to a router // find out the family of the router - fam := "all" + fam := "" + version := "" for _, i := range sqlite.RtrList { if i.Shortname == r.Shortname { fam = i.Family + version = i.Version break } } // Now check for each profile there is a given Telegraf config - valid := true + valid := false errString := "" for _, i := range r.Profiles { allTele := association.ActiveProfiles[i].Definition.TelCfg switch fam { case "vmx": if len(allTele.VmxCfg) == 0 { - valid = false errString += "There is no Telegraf config for profile " + i + " for the VMX platform.
" + } else { + if checkRouterSupport(allTele.VmxCfg, version) { + valid = true + } else { + errString += "There is no Telegraf config for profile " + i + " for this VMX version.
" + } } case "mx": if len(allTele.MxCfg) == 0 { - valid = false errString += "There is no Telegraf config for profile " + i + " for the MX platform.
" + } else { + if checkRouterSupport(allTele.MxCfg, version) { + valid = true + } else { + errString += "There is no Telegraf config for profile " + i + " for this MX version.
" + } } case "ptx": if len(allTele.PtxCfg) == 0 { - valid = false errString += "There is no Telegraf config for profile " + i + " for the PTX platform.
" + } else { + if checkRouterSupport(allTele.PtxCfg, version) { + valid = true + } else { + errString += "There is no Telegraf config for profile " + i + " for this PTX version.
" + } } case "acx": if len(allTele.AcxCfg) == 0 { - valid = false errString += "There is no Telegraf config for profile " + i + " for the ACX platform.
" + } else { + if checkRouterSupport(allTele.AcxCfg, version) { + valid = true + } else { + errString += "There is no Telegraf config for profile " + i + " for this ACX version.
" + } } + default: + errString += "There is no Telegraf config for profile " + i + " for the unknown platform.
" } }