diff --git a/ctrlz/topics/assets/assets.gen.go b/ctrlz/topics/assets/assets.gen.go
index 9fcdc67c..0b7d76eb 100644
--- a/ctrlz/topics/assets/assets.gen.go
+++ b/ctrlz/topics/assets/assets.gen.go
@@ -239,6 +239,8 @@ var _templatesEnvHtml = []byte(`{{ define "content" }}
Name |
Value |
+ Default |
+ Status |
@@ -247,6 +249,8 @@ var _templatesEnvHtml = []byte(`{{ define "content" }}
{{.Name}} |
{{.Value}} |
+ {{.DefaultValue}} |
+ {{.FeatureStatus}} |
{{ end }}
diff --git a/ctrlz/topics/assets/templates/env.html b/ctrlz/topics/assets/templates/env.html
index 4569d3dc..e96a4dbe 100644
--- a/ctrlz/topics/assets/templates/env.html
+++ b/ctrlz/topics/assets/templates/env.html
@@ -9,6 +9,8 @@
Name |
Value |
+ Default |
+ Status |
@@ -17,6 +19,8 @@
{{.Name}} |
{{.Value}} |
+ {{.DefaultValue}} |
+ {{.FeatureStatus}} |
{{ end }}
diff --git a/ctrlz/topics/env.go b/ctrlz/topics/env.go
index 8f73bdb8..72161080 100644
--- a/ctrlz/topics/env.go
+++ b/ctrlz/topics/env.go
@@ -1,4 +1,4 @@
-// Copyright 2018 Istio Authors
+/// Copyright 2018 Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import (
"istio.io/pkg/ctrlz/fw"
"istio.io/pkg/ctrlz/topics/assets"
+ "istio.io/pkg/env"
)
type envTopic struct {
@@ -42,20 +43,30 @@ func (envTopic) Prefix() string {
}
type envVar struct {
- Name string `json:"name"`
- Value string `json:"value"`
+ Name string `json:"name"`
+ Value string `json:"value"`
+ DefaultValue string `json:"defaultvalue"`
+ FeatureStatus string `json:"featurestatus"`
}
func getVars() []envVar {
- env := os.Environ()
- sort.Strings(env)
+ regEnv := env.VarDescriptions()
+ otherEnv := os.Environ()
+ sort.Strings(otherEnv)
result := []envVar{}
- for _, v := range env {
+ visited := make(map[string]bool, len(regEnv))
+ for _, v := range regEnv {
+ visited[v.Name] = true
+ result = append(result, envVar{Name: v.Name, Value: v.GetGeneric(), DefaultValue: v.DefaultValue, FeatureStatus: v.FeatureStatus.String()})
+ }
+ for _, v := range otherEnv {
var eq = strings.Index(v, "=")
var name = v[:eq]
- var value = v[eq+1:]
- result = append(result, envVar{Name: name, Value: value})
+ if _, ok := visited[name]; !ok {
+ var value = v[eq+1:]
+ result = append(result, envVar{Name: name, Value: value, DefaultValue: "UNKNOWN", FeatureStatus: "UNKNOWN"})
+ }
}
return result
diff --git a/env/var.go b/env/var.go
index dd06caf9..ad1db56a 100644
--- a/env/var.go
+++ b/env/var.go
@@ -17,6 +17,7 @@
package env
import (
+ "fmt"
"os"
"sort"
"strconv"
@@ -42,6 +43,27 @@ const (
DURATION
)
+type FeatureStatus byte
+
+const (
+ Alpha FeatureStatus = iota
+ Beta
+ Stable
+ Unknown
+)
+
+func (s FeatureStatus) String() string {
+ switch s {
+ case Alpha:
+ return "Alpha"
+ case Beta:
+ return "Beta"
+ case Stable:
+ return "Stable"
+ }
+ return "Unknown"
+}
+
// Var describes a single environment variable
type Var struct {
// The name of the environment variable.
@@ -61,6 +83,9 @@ type Var struct {
// The type of the variable's value
Type VarType
+
+ // The support level of the feature controlled by this env var
+ FeatureStatus FeatureStatus
}
// StringVar represents a single string environment variable.
@@ -109,39 +134,49 @@ func VarDescriptions() []Var {
// RegisterStringVar registers a new string environment variable.
func RegisterStringVar(name string, defaultValue string, description string) StringVar {
- v := Var{Name: name, DefaultValue: defaultValue, Description: description, Type: STRING}
+ v := Var{Name: name, DefaultValue: defaultValue, Description: description, Type: STRING, FeatureStatus: Unknown}
RegisterVar(v)
return StringVar{getVar(name)}
}
// RegisterBoolVar registers a new boolean environment variable.
func RegisterBoolVar(name string, defaultValue bool, description string) BoolVar {
- v := Var{Name: name, DefaultValue: strconv.FormatBool(defaultValue), Description: description, Type: BOOL}
+ v := Var{Name: name, DefaultValue: strconv.FormatBool(defaultValue), Description: description, Type: BOOL, FeatureStatus: Unknown}
RegisterVar(v)
return BoolVar{getVar(name)}
}
// RegisterIntVar registers a new integer environment variable.
func RegisterIntVar(name string, defaultValue int, description string) IntVar {
- v := Var{Name: name, DefaultValue: strconv.FormatInt(int64(defaultValue), 10), Description: description, Type: INT}
+ v := Var{Name: name, DefaultValue: strconv.FormatInt(int64(defaultValue), 10), Description: description, Type: INT, FeatureStatus: Unknown}
RegisterVar(v)
return IntVar{getVar(name)}
}
// RegisterFloatVar registers a new floating-point environment variable.
func RegisterFloatVar(name string, defaultValue float64, description string) FloatVar {
- v := Var{Name: name, DefaultValue: strconv.FormatFloat(defaultValue, 'G', -1, 64), Description: description, Type: FLOAT}
+ v := Var{Name: name, DefaultValue: strconv.FormatFloat(defaultValue, 'G', -1, 64), Description: description, Type: FLOAT, FeatureStatus: Unknown}
RegisterVar(v)
return FloatVar{v}
}
// RegisterDurationVar registers a new duration environment variable.
func RegisterDurationVar(name string, defaultValue time.Duration, description string) DurationVar {
- v := Var{Name: name, DefaultValue: defaultValue.String(), Description: description, Type: DURATION}
+ v := Var{Name: name, DefaultValue: defaultValue.String(), Description: description, Type: DURATION, FeatureStatus: Unknown}
RegisterVar(v)
return DurationVar{getVar(name)}
}
+func SetVarStatus(v Var, f FeatureStatus) {
+ if val, ok := allVars[v.Name]; ok {
+ val.FeatureStatus = f
+ allVars[v.Name] = val
+ } else {
+ v.FeatureStatus = f
+ RegisterVar(v)
+ }
+}
+
// RegisterVar registers a generic environment variable.
func RegisterVar(v Var) {
mutex.Lock()
@@ -169,6 +204,32 @@ func getVar(name string) Var {
return result
}
+func (v Var) LookupGeneric() (string, bool) {
+ switch v.Type {
+ case STRING:
+ return StringVar{Var: v}.Lookup()
+ case INT:
+ val, found := IntVar{Var: v}.Lookup()
+ return strconv.Itoa(val), found
+ case BOOL:
+ val, found := BoolVar{Var: v}.Lookup()
+ return strconv.FormatBool(val), found
+ case FLOAT:
+ val, found := FloatVar{Var: v}.Lookup()
+ return strconv.FormatFloat(val, 'f', -1, 64), found
+ case DURATION:
+ val, found := DurationVar{Var: v}.Lookup()
+ return val.String(), found
+ default:
+ return fmt.Sprintf("type %T is not recognized", v), false
+ }
+}
+
+func (v Var) GetGeneric() string {
+ val, _ := v.LookupGeneric()
+ return val
+}
+
// Get retrieves the value of the environment variable.
// It returns the value, which will be the default if the variable is not present.
// To distinguish between an empty value and an unset value, use Lookup.
diff --git a/env/var_test.go b/env/var_test.go
index 5fd993f9..68d3b680 100644
--- a/env/var_test.go
+++ b/env/var_test.go
@@ -329,3 +329,32 @@ func TestDupes(t *testing.T) {
t.Errorf("Expected 'XYZ', got '%s'", v.Description)
}
}
+
+func TestVar_GetGeneric(t *testing.T) {
+ type fields struct {
+ Var Var
+ Value string
+ }
+ tests := []struct {
+ name string
+ fields fields
+ want string
+ }{
+ {
+ name: "first",
+ fields: fields{
+ Var: RegisterStringVar("test", "defaultval", "description").Var,
+ Value: "non-default",
+ },
+ want: "non-default",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ os.Setenv(tt.fields.Var.Name, tt.fields.Value)
+ if got := tt.fields.Var.GetGeneric(); got != tt.want {
+ t.Errorf("GetGeneric() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/ledger/ledger_test.go b/ledger/ledger_test.go
index ec8c0281..cf3c71c3 100644
--- a/ledger/ledger_test.go
+++ b/ledger/ledger_test.go
@@ -22,10 +22,9 @@ import (
"testing"
"time"
- "golang.org/x/sync/errgroup"
-
"github.com/google/uuid"
"github.com/spaolacci/murmur3"
+ "golang.org/x/sync/errgroup"
"gotest.tools/assert"
)
diff --git a/ledger/trie_cache.go b/ledger/trie_cache.go
index f1683533..0a507644 100644
--- a/ledger/trie_cache.go
+++ b/ledger/trie_cache.go
@@ -15,11 +15,10 @@
package ledger
import (
+ "sync"
"time"
"istio.io/pkg/cache"
-
- "sync"
)
type cacheDB struct {
diff --git a/viperconfig/viperconfig.go b/viperconfig/viperconfig.go
index 380bd51e..0ff407d0 100644
--- a/viperconfig/viperconfig.go
+++ b/viperconfig/viperconfig.go
@@ -18,10 +18,9 @@ import (
"fmt"
"os"
- "github.com/spf13/viper"
-
"github.com/spf13/cobra"
"github.com/spf13/pflag"
+ "github.com/spf13/viper"
)
// AddConfigFlag appends a persistent flag for retrieving Viper config, as well as an initializer