aboutsummaryrefslogtreecommitdiffstats
path: root/client/go/cmd/clusterstate/model_config.go
diff options
context:
space:
mode:
Diffstat (limited to 'client/go/cmd/clusterstate/model_config.go')
-rw-r--r--client/go/cmd/clusterstate/model_config.go124
1 files changed, 124 insertions, 0 deletions
diff --git a/client/go/cmd/clusterstate/model_config.go b/client/go/cmd/clusterstate/model_config.go
new file mode 100644
index 00000000000..ce9aa556c8a
--- /dev/null
+++ b/client/go/cmd/clusterstate/model_config.go
@@ -0,0 +1,124 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+// Author: arnej
+
+// utilities to get and manipulate node states in a storage cluster
+package clusterstate
+
+import (
+ "encoding/json"
+ "sort"
+ "strings"
+)
+
+type VespaModelConfig struct {
+ VespaVersion string `json:"vespaVersion"`
+ Hosts []struct {
+ Name string `json:"name"`
+ Services []struct {
+ Name string `json:"name"`
+ Type string `json:"type"`
+ Configid string `json:"configid"`
+ Clustertype string `json:"clustertype"`
+ Clustername string `json:"clustername"`
+ Index int `json:"index"`
+ Ports []struct {
+ Number int `json:"number"`
+ Tags string `json:"tags"`
+ } `json:"ports"`
+ } `json:"services"`
+ } `json:"hosts"`
+}
+
+func (m *VespaModelConfig) String() string {
+ if m == nil {
+ return "nil"
+ }
+ var buf strings.Builder
+ buf.WriteString("vespa version: ")
+ buf.WriteString(m.VespaVersion)
+ for _, h := range m.Hosts {
+ buf.WriteString("\n host: ")
+ buf.WriteString(h.Name)
+ for _, s := range h.Services {
+ buf.WriteString("\n service: ")
+ buf.WriteString(s.Name)
+ buf.WriteString(" type: ")
+ buf.WriteString(s.Type)
+ buf.WriteString(" cluster: ")
+ buf.WriteString(s.Clustername)
+ }
+ buf.WriteString("\n")
+ }
+ buf.WriteString("\n")
+ return buf.String()
+}
+
+type ClusterControllerSpec struct {
+ host string
+ port int
+}
+
+func parseModelConfig(input string) *VespaModelConfig {
+ codec := json.NewDecoder(strings.NewReader(input))
+ var parsedJson VespaModelConfig
+ err := codec.Decode(&parsedJson)
+ if err != nil {
+ PutTrace("could not decode JSON >>>", input, "<<< error:", err)
+ return nil
+ }
+ return &parsedJson
+}
+
+func (m *VespaModelConfig) findClusterControllers() []ClusterControllerSpec {
+ res := make([]ClusterControllerSpec, 0, 1)
+ for _, h := range m.Hosts {
+ for _, s := range h.Services {
+ if s.Type == "container-clustercontroller" {
+ for _, p := range s.Ports {
+ if strings.Contains(p.Tags, "state") {
+ res = append(res, ClusterControllerSpec{
+ host: h.Name, port: p.Number,
+ })
+ }
+ }
+ }
+ }
+ }
+ return res
+}
+
+func (m *VespaModelConfig) findSelectedServices(opts *Options) []serviceSpec {
+ res := make([]serviceSpec, 0, 5)
+ for _, h := range m.Hosts {
+ for _, s := range h.Services {
+ spec := serviceSpec{
+ cluster: s.Clustername,
+ serviceType: s.Type,
+ index: s.Index,
+ host: h.Name,
+ }
+ if s.Type == "storagenode" {
+ // simplify:
+ spec.serviceType = "storage"
+ }
+ if opts.wantService(spec) {
+ res = append(res, spec)
+ }
+ }
+ }
+ sort.Slice(res, func(i, j int) bool {
+ a := res[i]
+ b := res[j]
+ if a.cluster != b.cluster {
+ return a.cluster < b.cluster
+ }
+ if a.serviceType != b.serviceType {
+ return a.serviceType < b.serviceType
+ }
+ if a.index != b.index {
+ return a.index < b.index
+ }
+ return a.host < b.host
+ })
+ return res
+}