From c7ed2e717832c017aef9e0679eb41d079f544865 Mon Sep 17 00:00:00 2001 From: Sebastian Tiedtke Date: Wed, 31 Jul 2024 13:38:16 -0700 Subject: [PATCH] Owl more validation (#583) This is in a good state for runner v1. Let's merge and work from smaller feature branches rather than continually rebasing this branch. - Introduce complex specs (working title; impeding renaming) - Introduce tag and dburl validation - Propagate execution info via context Unfinished. --- .pre-commit-config.yaml | 2 +- go.mod | 3 + go.sum | 2 + internal/cmd/common.go | 5 +- internal/command/exec_info.go | 17 + internal/owl/graph.go | 230 ++++++++++++-- internal/owl/graph_test.go | 2 +- internal/owl/parse.go | 12 +- internal/owl/parse_test.go | 3 + internal/owl/query.go | 285 +++++++++++++---- internal/owl/required.go | 63 ++++ internal/owl/store.go | 143 +++++++-- internal/owl/store_test.go | 11 +- internal/owl/testdata/project/.env | 2 + internal/owl/testdata/project/.env.local | 2 + internal/owl/validate.go | 298 +++++++++++++++++- internal/owl/validate_test.go | 151 +++++++++ internal/runner/command.go | 12 +- internal/runner/command_test.go | 16 + internal/runner/service.go | 23 +- internal/runner/session.go | 42 +-- internal/runner/shell.go | 1 + internal/runner/shellraw.go | 1 + internal/runner/tempfile.go | 1 + internal/version/version.go | 4 + main.go | 2 +- .../gen/proto/go/runme/runner/v1/runner.pb.go | 214 +++++++------ .../go/runme/runner/v2alpha1/runner.pb.go | 264 ++++++++-------- .../proto/ts/runme/runner/v1/runner_pb.d.ts | 4 + .../gen/proto/ts/runme/runner/v1/runner_pb.js | 3 +- .../ts/runme/runner/v2alpha1/runner_pb.d.ts | 16 +- .../ts/runme/runner/v2alpha1/runner_pb.js | 13 +- pkg/api/proto/runme/runner/v1/runner.proto | 2 + .../proto/runme/runner/v2alpha1/runner.proto | 14 +- 34 files changed, 1433 insertions(+), 430 deletions(-) create mode 100644 internal/command/exec_info.go create mode 100644 internal/owl/required.go create mode 100644 internal/owl/testdata/project/.env create mode 100644 internal/owl/testdata/project/.env.local create mode 100644 internal/owl/validate_test.go diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 90f8e1157..931657c94 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: hooks: - id: typos args: ["--diff", "--force-exclude"] - exclude: "^.vscode/|go.mod" + exclude: "^.vscode/|go.mod|_test.go" - repo: local hooks: - id: go-mod-tidy diff --git a/go.mod b/go.mod index c71e80acf..167955e19 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/stateful/runme/v3 go 1.22 +// replace github.com/stateful/godotenv => ../godotenv + require ( buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.2-20240717164558-a6c49f84cc0f.2 github.com/Masterminds/semver/v3 v3.2.1 @@ -36,6 +38,7 @@ require ( github.com/rwtodd/Go.Sed v0.0.0-20240405174034-bb8ed5da0fd0 github.com/stateful/godotenv v0.0.0-20240309032207-c7bc0b812915 github.com/vektah/gqlparser/v2 v2.5.16 + github.com/xo/dburl v0.23.2 github.com/yuin/goldmark v1.7.4 go.uber.org/dig v1.17.1 go.uber.org/multierr v1.11.0 diff --git a/go.sum b/go.sum index e22122a77..5ab14bc40 100644 --- a/go.sum +++ b/go.sum @@ -284,6 +284,8 @@ github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +github.com/xo/dburl v0.23.2 h1:Fl88cvayrgE56JA/sqhNMLljCW/b7RmG1mMkKMZUFgA= +github.com/xo/dburl v0.23.2/go.mod h1:uazlaAQxj4gkshhfuuYyvwCBouOmNnG2aDxTCFZpmL4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= diff --git a/internal/cmd/common.go b/internal/cmd/common.go index 5dedbaeb7..e0f2ee26f 100644 --- a/internal/cmd/common.go +++ b/internal/cmd/common.go @@ -19,6 +19,7 @@ import ( "github.com/stateful/runme/v3/internal/runner/client" "github.com/stateful/runme/v3/internal/tui" "github.com/stateful/runme/v3/internal/tui/prompt" + "github.com/stateful/runme/v3/internal/version" runnerv1 "github.com/stateful/runme/v3/pkg/api/gen/proto/go/runme/runner/v1" "github.com/stateful/runme/v3/pkg/document" "github.com/stateful/runme/v3/pkg/document/identity" @@ -187,7 +188,9 @@ func getLogger(devMode bool, aiLogs bool) (*zap.Logger, error) { // Record the caller of the log message newLogger = newLogger.WithOptions(zap.AddCaller()) - newLogger.Info("Logger initialized", zap.Bool("devMode", devMode), zap.Bool("aiLogs", aiLogs), zap.String("aiLogFile", aiLogFile)) + versionInfo := version.BaseVersionInfo() + + newLogger.Info("Logger initialized", zap.String("versionInfo", versionInfo), zap.Bool("devMode", devMode), zap.Bool("aiLogs", aiLogs), zap.String("aiLogFile", aiLogFile)) return newLogger, nil } diff --git a/internal/command/exec_info.go b/internal/command/exec_info.go new file mode 100644 index 000000000..55b064ffb --- /dev/null +++ b/internal/command/exec_info.go @@ -0,0 +1,17 @@ +package command + +import "context" + +type runnerContextKey struct{} + +var ExecutionInfoKey = &runnerContextKey{} + +type ExecutionInfo struct { + RunID string + KnownName string + KnownID string +} + +func ContextWithExecutionInfo(ctx context.Context, execInfo *ExecutionInfo) context.Context { + return context.WithValue(ctx, ExecutionInfoKey, execInfo) +} diff --git a/internal/owl/graph.go b/internal/owl/graph.go index 5deecf4c6..eb2f5f60d 100644 --- a/internal/owl/graph.go +++ b/internal/owl/graph.go @@ -8,17 +8,28 @@ import ( "strings" "github.com/graphql-go/graphql" - "github.com/graphql-go/graphql/language/ast" +) + +// Constants representing different spec names. +// These constants are of type SpecName and are assigned string values. +const ( + SpecNameOpaque string = "Opaque" // SpecNameOpaque specifies an opaque specification. + SpecNamePlain string = "Plain" // SpecNamePlain specifies a plain specification. + SpecNameSecret string = "Secret" // SpecNameSecret specifies a secret specification. + SpecNamePassword string = "Password" // SpecNamePassword specifies a password specification. + SpecNameDefault = SpecNameOpaque ) type specType struct { - typ *graphql.Object - resolve graphql.FieldResolveFn + typeName string + typeObject *graphql.Object + resolveFn graphql.FieldResolveFn } var ( - Schema graphql.Schema - SpecTypes map[string]*specType + Schema graphql.Schema + SpecTypes map[string]*specType + ComplexType *specType ) var EnvironmentType, @@ -26,14 +37,12 @@ var EnvironmentType, RenderType, SpecTypeErrorsType *graphql.Object -type QueryNodeReducer func(*ast.OperationDefinition, *ast.SelectionSet) (*ast.SelectionSet, error) - // todo(sebastian): use gql interface? func registerSpecFields(fields graphql.Fields) { - for k, v := range SpecTypes { - fields[k] = &graphql.Field{ - Type: v.typ, - Resolve: v.resolve, + for _, t := range SpecTypes { + fields[t.typeName] = &graphql.Field{ + Type: t.typeObject, + Resolve: t.resolveFn, Args: graphql.FieldConfigArgument{ "keys": &graphql.ArgumentConfig{ Type: graphql.NewList(graphql.String), @@ -45,6 +54,22 @@ func registerSpecFields(fields graphql.Fields) { }, } } + + fields[ComplexType.typeName] = &graphql.Field{ + Type: ComplexType.typeObject, + Resolve: ComplexType.resolveFn, + Args: graphql.FieldConfigArgument{ + "name": &graphql.ArgumentConfig{ + Type: graphql.NewNonNull(graphql.String), + }, + "namespace": &graphql.ArgumentConfig{ + Type: graphql.NewNonNull(graphql.String), + }, + "keys": &graphql.ArgumentConfig{ + Type: graphql.NewList(graphql.String), + }, + }, + } } func registerSpec(name string, sensitive, mask bool, resolver graphql.FieldResolveFn) *specType { @@ -73,9 +98,80 @@ func registerSpec(name string, sensitive, mask bool, resolver graphql.FieldResol "errors": &graphql.Field{ Type: graphql.NewList(SpecTypeErrorsType), Resolve: func(p graphql.ResolveParams) (interface{}, error) { - opSet, ok := p.Source.(*OperationSet) - if !ok { - return nil, errors.New("source is not an OperationSet") + var opSet *OperationSet + + switch p.Source.(type) { + case *OperationSet: + opSet = p.Source.(*OperationSet) + case *ComplexOperationSet: + opSet = p.Source.(*ComplexOperationSet).OperationSet + default: + return nil, errors.New("source does not contain an OperationSet") + } + + // todo(sebastian): move into interface? + var verrs []*SetVarError + for _, spec := range opSet.specs { + if spec.Spec.Error == nil { + continue + } + + code := spec.Spec.Error.Code() + verr := &SetVarError{ + Code: int(code), + Message: spec.Spec.Error.Message(), + } + verrs = append(verrs, verr) + } + + return verrs, nil + }, + }, + "done": &graphql.Field{ + Type: EnvironmentType, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + return p.Source, nil + }, + }, + } + + registerSpecFields(fields) + + return fields + }), + }) + + return &specType{ + typeName: name, + typeObject: typ, + resolveFn: resolver, + } +} + +func registerComplexType(resolver graphql.FieldResolveFn) *specType { + name := ComplexSpecType + typ := graphql.NewObject(graphql.ObjectConfig{ + Name: fmt.Sprintf("SpecType%s", name), + Fields: (graphql.FieldsThunk)(func() graphql.Fields { + fields := graphql.Fields{ + "name": &graphql.Field{ + Type: graphql.String, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + return name, nil + }, + }, + "errors": &graphql.Field{ + Type: graphql.NewList(SpecTypeErrorsType), + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + var opSet *OperationSet + + switch p.Source.(type) { + case *OperationSet: + opSet = p.Source.(*OperationSet) + case *ComplexOperationSet: + opSet = p.Source.(*ComplexOperationSet).OperationSet + default: + return nil, errors.New("source does not contain an OperationSet") } // todo(sebastian): move into interface? @@ -111,8 +207,9 @@ func registerSpec(name string, sensitive, mask bool, resolver graphql.FieldResol }) return &specType{ - typ: typ, - resolve: resolver, + typeName: name, + typeObject: typ, + resolveFn: resolver, } } @@ -123,7 +220,23 @@ func specResolver(mutator SpecResolverMutator) graphql.FieldResolveFn { insecure := p.Args["insecure"].(bool) keysArg := p.Args["keys"].([]interface{}) - opSet := p.Source.(*OperationSet) + var opSet *OperationSet + complexName := "" + complexNs := "" + + switch p.Source.(type) { + case *OperationSet: + opSet = p.Source.(*OperationSet) + complexName = "" + complexNs = "" + case *ComplexOperationSet: + opSet = p.Source.(*ComplexOperationSet).OperationSet + complexName = p.Source.(*ComplexOperationSet).Name + complexNs = p.Source.(*ComplexOperationSet).Namespace + default: + return nil, errors.New("source does not contain an OperationSet") + } + for _, kArg := range keysArg { k := kArg.(string) val, valOk := opSet.values[k] @@ -133,6 +246,9 @@ func specResolver(mutator SpecResolverMutator) graphql.FieldResolveFn { continue } + spec.Spec.Complex = complexName + spec.Spec.Namespace = complexNs + // skip if last known status was DELETED if valOk && val.Value.Status == "DELETED" { continue @@ -146,7 +262,7 @@ func specResolver(mutator SpecResolverMutator) graphql.FieldResolveFn { } if spec.Spec.Required { - spec.Spec.Error = RequiredError{varItem: &SetVarItem{Var: val.Var, Value: val.Value, Spec: spec.Spec}} + spec.Spec.Error = NewRequiredError(&SetVarItem{Var: val.Var, Value: val.Value, Spec: spec.Spec}) continue } @@ -165,7 +281,7 @@ func specResolver(mutator SpecResolverMutator) graphql.FieldResolveFn { } } -func resolveSensitive() graphql.FieldResolveFn { +func resolveSensitiveKeys() graphql.FieldResolveFn { return func(p graphql.ResolveParams) (interface{}, error) { sensitive := SetVarItems{} var opSet *OperationSet @@ -176,8 +292,10 @@ func resolveSensitive() graphql.FieldResolveFn { return sensitive, nil case *OperationSet: opSet = p.Source.(*OperationSet) + case *ComplexOperationSet: + opSet = p.Source.(*ComplexOperationSet).OperationSet default: - return nil, errors.New("source is not an OperationSet") + return nil, errors.New("source does not contain an OperationSet") } for _, v := range opSet.values { @@ -186,11 +304,6 @@ func resolveSensitive() graphql.FieldResolveFn { return nil, fmt.Errorf("missing spec for %s", v.Var.Key) } - // todo(sebastian): cutting a corner here, really shouldn't key on Specs - if s.Spec.Name != "Secret" && s.Spec.Name != "Password" { - continue - } - item := &SetVarItem{ Var: v.Var, Spec: s.Spec, @@ -217,8 +330,10 @@ func resolveDotEnv() graphql.FieldResolveFn { return dotenv, nil case *OperationSet: opSet = p.Source.(*OperationSet) + case *ComplexOperationSet: + opSet = p.Source.(*ComplexOperationSet).OperationSet default: - return nil, errors.New("source is not an OperationSet") + return nil, errors.New("source does not contain an OperationSet") } var buf bytes.Buffer @@ -257,8 +372,10 @@ func resolveGetter() graphql.FieldResolveFn { return kv, nil case *OperationSet: opSet = p.Source.(*OperationSet) + case *ComplexOperationSet: + opSet = p.Source.(*ComplexOperationSet).OperationSet default: - return nil, errors.New("source is not an OperationSet") + return nil, errors.New("source is does not contain an OperationSet") } val, ok := opSet.values[key] @@ -291,8 +408,10 @@ func resolveSnapshot() graphql.FieldResolveFn { return snapshot, nil case *OperationSet: opSet = p.Source.(*OperationSet) + case *ComplexOperationSet: + opSet = p.Source.(*ComplexOperationSet).OperationSet default: - return nil, errors.New("source is not an OperationSet") + return nil, errors.New("source does not contain an OperationSet") } // todo(sebastian): this should really be up the graph @@ -515,6 +634,53 @@ func init() { }), ) + ComplexType = registerComplexType( + func(p graphql.ResolveParams) (interface{}, error) { + name := p.Args["name"].(string) + ns := p.Args["namespace"].(string) + keys := p.Args["keys"].([]interface{}) + + var complexOpSet *ComplexOperationSet + + switch p.Source.(type) { + case *OperationSet: + complexOpSet = &ComplexOperationSet{ + OperationSet: p.Source.(*OperationSet), + Name: name, + Namespace: ns, + } + case *ComplexOperationSet: + complexOpSet = p.Source.(*ComplexOperationSet) + default: + return nil, errors.New("source does not contain an OperationSet") + } + + var valuekeys []string + for _, k := range keys { + v, ok := k.(string) + if !ok { + continue + } + valuekeys = append(valuekeys, v) + } + + complexOpSet.Name = name + complexOpSet.Namespace = ns + complexOpSet.Keys = valuekeys + + validationErrs, err := complexOpSet.validate() + if err != nil { + return nil, err + } + + for _, verr := range validationErrs { + key := verr.VarItem().Var.Key + complexOpSet.specs[key].Spec.Error = verr + } + + return complexOpSet, nil + }) + SpecTypeErrorsType = graphql.NewObject(graphql.ObjectConfig{ Name: "SpecTypeErrorsType", Fields: graphql.Fields{ @@ -683,7 +849,7 @@ func init() { }, "sensitiveKeys": &graphql.Field{ Type: graphql.NewNonNull(graphql.NewList(VariableType)), - Resolve: resolveSensitive(), + Resolve: resolveSensitiveKeys(), }, } }), @@ -862,8 +1028,8 @@ func init() { }), }) - SpecsType := graphql.NewObject(graphql.ObjectConfig{ - Name: "SpecsType", + SpecsListType := graphql.NewObject(graphql.ObjectConfig{ + Name: "SpecsListType", Fields: (graphql.FieldsThunk)(func() graphql.Fields { return graphql.Fields{ "list": &graphql.Field{ @@ -908,7 +1074,7 @@ func init() { }, }, "specs": &graphql.Field{ - Type: SpecsType, + Type: SpecsListType, Resolve: func(p graphql.ResolveParams) (interface{}, error) { return p.Info.FieldName, nil }, diff --git a/internal/owl/graph_test.go b/internal/owl/graph_test.go index 40b4775a0..3c632f8b2 100644 --- a/internal/owl/graph_test.go +++ b/internal/owl/graph_test.go @@ -220,7 +220,7 @@ func Test_Graph_Reconcile(t *testing.T) { testCases.runAll(t) } -func Test_Graph_Sensitive(t *testing.T) { +func Test_Graph_SensitiveKeys(t *testing.T) { testCases := fileTestCases{ { name: "Sensitive keys", diff --git a/internal/owl/parse.go b/internal/owl/parse.go index 7b5a74d05..240cffa97 100644 --- a/internal/owl/parse.go +++ b/internal/owl/parse.go @@ -6,16 +6,6 @@ import ( "strings" ) -// Constants representing different specification names. -// These constants are of type SpecName and are assigned string values. -const ( - SpecNameOpaque string = "Opaque" // SpecNameOpaque specifies an opaque specification. - SpecNamePlain string = "Plain" // SpecNamePlain specifies a plain specification. - SpecNameSecret string = "Secret" // SpecNameSecret specifies a secret specification. - SpecNamePassword string = "Password" // SpecNamePassword specifies a password specification. - SpecNameDefault = SpecNameOpaque -) - // Spec represents the available configuration options and their flags. type Spec struct { Name string @@ -109,5 +99,5 @@ func upperFirstLetter(s string) string { // Convert the first character to uppercase // Concatenate it with the rest of the string - return strings.ToUpper(string(s[0])) + strings.ToLower((s[1:])) + return strings.ToUpper(string(s[0])) + (s[1:]) } diff --git a/internal/owl/parse_test.go b/internal/owl/parse_test.go index be2ad26a3..ae43e237e 100644 --- a/internal/owl/parse_test.go +++ b/internal/owl/parse_test.go @@ -103,6 +103,7 @@ func TestUnmarshal(t *testing.T) { `quotedEmpty="" # Plain`, `quoted="Foo bar baz" # Plain`, `unquoted=unquoted value # Plain`, + `database=unquoted value # DatabaseUrl`, } expectedValues := map[string]string{ @@ -110,12 +111,14 @@ func TestUnmarshal(t *testing.T) { "quotedEmpty": "", "quoted": "Foo bar baz", "unquoted": "unquoted value", + "database": "unquoted value", } expectedComments := map[string]string{ "naked": "Plain", "quotedEmpty": "Plain", "quoted": "Plain", "unquoted": "Plain", + "database": "DatabaseUrl", } bytes := []byte(strings.Join(lines, "\n")) diff --git a/internal/owl/query.go b/internal/owl/query.go index 32d919cbe..52694828c 100644 --- a/internal/owl/query.go +++ b/internal/owl/query.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "slices" + "strings" "time" "github.com/graphql-go/graphql/language/ast" @@ -13,6 +14,8 @@ import ( "go.uber.org/zap" ) +type QueryNodeReducer func([]*OperationSet, *ast.OperationDefinition, *ast.SelectionSet) (*ast.SelectionSet, error) + func (s *Store) snapshotQuery(query, vars io.StringWriter) error { varDefs := []*ast.VariableDefinition{ ast.NewVariableDefinition(&ast.VariableDefinition{ @@ -49,11 +52,14 @@ func (s *Store) snapshotQuery(query, vars io.StringWriter) error { } s.logger.Debug("snapshot opSets breakdown", zap.Int("loaded", loaded), zap.Int("updated", updated), zap.Int("deleted", deleted), zap.Int("total", len(s.opSets))) - q, err := NewQuery("Snapshot", varDefs, + q, err := s.NewQuery("Snapshot", varDefs, []QueryNodeReducer{ reconcileAsymmetry(s), - reduceSetOperations(s, vars), - reduceSepcs(s), + reduceSetOperations(vars), + reduceWrapValidate(), + reduceSpecsAtomic("", nil), + reduceSepcsComplex(), + reduceWrapDone(), reduceSnapshot(), }, ) @@ -74,7 +80,7 @@ func (s *Store) snapshotQuery(query, vars io.StringWriter) error { return nil } -func (s *Store) sensitiveQuery(query, vars io.StringWriter) error { +func (s *Store) sensitiveKeysQuery(query, vars io.StringWriter) error { varDefs := []*ast.VariableDefinition{ ast.NewVariableDefinition(&ast.VariableDefinition{ Variable: ast.NewVariable(&ast.Variable{ @@ -93,11 +99,14 @@ func (s *Store) sensitiveQuery(query, vars io.StringWriter) error { }), } - q, err := NewQuery("Sensitive", varDefs, + q, err := s.NewQuery("Sensitive", varDefs, []QueryNodeReducer{ reconcileAsymmetry(s), - reduceSetOperations(s, vars), - reduceSepcs(s), + reduceSetOperations(vars), + reduceWrapValidate(), + reduceSpecsAtomic("", nil), + reduceSepcsComplex(), + reduceWrapDone(), reduceSensitive(), }, ) @@ -169,11 +178,14 @@ func (s *Store) getterQuery(query, vars io.StringWriter) error { } s.logger.Debug("getter opSets breakdown", zap.Int("loaded", loaded), zap.Int("updated", updated), zap.Int("deleted", deleted), zap.Int("total", len(s.opSets))) - q, err := NewQuery("Get", varDefs, + q, err := s.NewQuery("Get", varDefs, []QueryNodeReducer{ reconcileAsymmetry(s), - reduceSetOperations(s, vars), - reduceSepcs(s), + reduceSetOperations(vars), + reduceWrapValidate(), + reduceSpecsAtomic("", nil), + reduceSepcsComplex(), + reduceWrapDone(), reduceGetter(), }, ) @@ -194,11 +206,37 @@ func (s *Store) getterQuery(query, vars io.StringWriter) error { return nil } -func reduceSetOperations(store *Store, vars io.StringWriter) QueryNodeReducer { - return func(opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { - opSetData := make(map[string]SetVarItems, len(store.opSets)) +func reduceWrapValidate() QueryNodeReducer { + return func(opSets []*OperationSet, opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { + validateSelSet := ast.NewSelectionSet(&ast.SelectionSet{}) + selSet.Selections = append(selSet.Selections, ast.NewField(&ast.Field{ + Name: ast.NewName(&ast.Name{ + Value: "validate", + }), + SelectionSet: validateSelSet, + })) + return validateSelSet, nil + } +} + +func reduceWrapDone() QueryNodeReducer { + return func(opSets []*OperationSet, opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { + doneSelSet := ast.NewSelectionSet(&ast.SelectionSet{}) + selSet.Selections = append(selSet.Selections, ast.NewField(&ast.Field{ + Name: ast.NewName(&ast.Name{ + Value: "done", + }), + SelectionSet: doneSelSet, + })) + return doneSelSet, nil + } +} + +func reduceSetOperations(vars io.StringWriter) QueryNodeReducer { + return func(opSets []*OperationSet, opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { + opSetData := make(map[string]SetVarItems, len(opSets)) - for i, opSet := range store.opSets { + for i, opSet := range opSets { if len(opSet.values) == 0 && len(opSet.specs) == 0 { continue } @@ -303,7 +341,7 @@ func reduceSetOperations(store *Store, vars io.StringWriter) QueryNodeReducer { } func reduceSensitive() QueryNodeReducer { - return func(opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { + return func(opSets []*OperationSet, opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { nextSelSet := ast.NewSelectionSet(&ast.SelectionSet{ Selections: []ast.Selection{ ast.NewField(&ast.Field{ @@ -408,7 +446,7 @@ func reduceSensitive() QueryNodeReducer { } func reduceGetter() QueryNodeReducer { - return func(opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { + return func(opSets []*OperationSet, opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { nextSelSet := ast.NewSelectionSet(&ast.SelectionSet{ Selections: []ast.Selection{ ast.NewField(&ast.Field{ @@ -559,7 +597,7 @@ func reduceGetter() QueryNodeReducer { } func reduceSnapshot() QueryNodeReducer { - return func(opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { + return func(opSets []*OperationSet, opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { nextSelSet := ast.NewSelectionSet(&ast.SelectionSet{ Selections: []ast.Selection{ ast.NewField(&ast.Field{ @@ -710,7 +748,7 @@ func reduceSnapshot() QueryNodeReducer { } func reconcileAsymmetry(store *Store) QueryNodeReducer { - return func(opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { + return func(opSets []*OperationSet, opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { allSpecs := make(map[string]bool) for _, opSet := range store.opSets { for k := range opSet.specs { @@ -778,18 +816,30 @@ func reconcileAsymmetry(store *Store) QueryNodeReducer { } } -func reduceSepcs(store *Store) QueryNodeReducer { - return func(opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { +func reduceSpecsAtomic(ns string, parent *ComplexDef) QueryNodeReducer { + return func(opSets []*OperationSet, opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { var specKeys []string varSpecs := make(map[string]*SetVarItem) - for _, opSet := range store.opSets { + for _, opSet := range opSets { if len(opSet.specs) == 0 { continue } for _, s := range opSet.specs { + isTransient := opSet.operation.kind == TransientSetOperation + if isTransient && parent != nil { + for k, v := range parent.Items { + if fmt.Sprintf("%s_%s", ns, k) != s.Var.Key { + continue + } + s.Spec = v + } + } + if _, ok := SpecTypes[s.Spec.Name]; !ok { - return nil, fmt.Errorf("unknown spec type: %s on %s", s.Spec.Name, s.Var.Key) + // return nil, fmt.Errorf("unknown spec type: %s on %s", s.Spec.Name, s.Var.Key) + continue } + varSpecs[s.Var.Key] = &SetVarItem{ Var: s.Var, Spec: s.Spec, @@ -798,7 +848,7 @@ func reduceSepcs(store *Store) QueryNodeReducer { } } - nextVarSpecs := func(varSpecs map[string]*SetVarItem, spec string, prevSelSet *ast.SelectionSet) *ast.SelectionSet { + reduceVarSpecs := func(varSpecs map[string]*SetVarItem, spec string, prevSelSet *ast.SelectionSet) *ast.SelectionSet { var keys []string for _, v := range varSpecs { if v.Spec.Name != spec { @@ -871,8 +921,7 @@ func reduceSepcs(store *Store) QueryNodeReducer { return nextSelSet } - topSelSet := ast.NewSelectionSet(&ast.SelectionSet{}) - nextSelSet := topSelSet + nextSelSet := selSet // todo: poor Sebastian's deduplication slices.Sort(specKeys) @@ -882,39 +931,163 @@ func reduceSepcs(store *Store) QueryNodeReducer { continue } prev = specKey - nextSelSet = nextVarSpecs(varSpecs, specKey, nextSelSet) + nextSelSet = reduceVarSpecs(varSpecs, specKey, nextSelSet) } - doneSelSet := ast.NewSelectionSet(&ast.SelectionSet{}) - nextSelSet.Selections = append(nextSelSet.Selections, ast.NewField(&ast.Field{ - Name: ast.NewName(&ast.Name{ - Value: "done", - }), - SelectionSet: doneSelSet, - })) + return nextSelSet, nil + } +} - selSet.Selections = append(selSet.Selections, - ast.NewField(&ast.Field{ - Name: ast.NewName(&ast.Name{ - Value: "validate", - }), - // Arguments: []*ast.Argument{ - // ast.NewArgument(&ast.Argument{ - // Name: ast.NewName(&ast.Name{ - // Value: "insecure", - // }), - // Value: ast.NewVariable(&ast.Variable{ - // Name: ast.NewName(&ast.Name{ - // Value: "insecure", - // }), - // }), - // }), - // }, - SelectionSet: topSelSet, - }), - ) +func reduceSepcsComplex() QueryNodeReducer { + return func(opSets []*OperationSet, opDef *ast.OperationDefinition, selSet *ast.SelectionSet) (*ast.SelectionSet, error) { + var varKeys []string + varSpecs := make(map[string]*SetVarItem) + for _, opSet := range opSets { + if len(opSet.specs) == 0 { + continue + } + for _, s := range opSet.specs { + if _, ok := SpecTypes[s.Spec.Name]; ok { + continue + } + varSpecs[s.Var.Key] = &SetVarItem{ + Var: s.Var, + Spec: s.Spec, + } + varKeys = append(varKeys, s.Var.Key) + } + } - return doneSelSet, nil + reduceNamespacedSpec := func(varSpecs map[string]*SetVarItem, ns string, prevSelSet *ast.SelectionSet) *ast.SelectionSet { + spec := "" + var keys []string + var items SetVarItems + for _, v := range varSpecs { + spec = v.Spec.Name + keys = append(keys, v.Var.Key) + items = append(items, v) + } + if len(keys) == 0 { + return prevSelSet + } + + nextSelSet := ast.NewSelectionSet(&ast.SelectionSet{ + Selections: []ast.Selection{ + ast.NewField(&ast.Field{ + Name: ast.NewName(&ast.Name{ + Value: "name", + }), + }), + // ast.NewField(&ast.Field{ + // Name: ast.NewName(&ast.Name{ + // Value: "sensitive", + // }), + // }), + // ast.NewField(&ast.Field{ + // Name: ast.NewName(&ast.Name{ + // Value: "mask", + // }), + // }), + // ast.NewField(&ast.Field{ + // Name: ast.NewName(&ast.Name{ + // Value: "errors", + // }), + // }), + }, + }) + + valuekeys := ast.NewListValue(&ast.ListValue{}) + for _, name := range keys { + valuekeys.Values = append(valuekeys.Values, ast.NewStringValue(&ast.StringValue{ + Value: name, + })) + } + + prevSelSet.Selections = append(prevSelSet.Selections, + ast.NewField(&ast.Field{ + Name: ast.NewName(&ast.Name{ + Value: ComplexSpecType, + }), + Arguments: []*ast.Argument{ + ast.NewArgument(&ast.Argument{ + Name: ast.NewName(&ast.Name{ + Value: "name", + }), + Value: ast.NewStringValue(&ast.StringValue{ + Value: spec, + }), + }), + ast.NewArgument(&ast.Argument{ + Name: ast.NewName(&ast.Name{ + Value: "namespace", + }), + Value: ast.NewStringValue(&ast.StringValue{ + Value: ns, + }), + }), + ast.NewArgument(&ast.Argument{ + Name: ast.NewName(&ast.Name{ + Value: "keys", + }), + Value: valuekeys, + }), + }, + SelectionSet: nextSelSet, + })) + + specDef := ComplexDefTypes[spec] + + transientOpSet, _ := NewOperationSet(WithOperation(TransientSetOperation), WithItems(items)) + atomicSelSet, err := reduceSpecsAtomic(ns, specDef)([]*OperationSet{transientOpSet}, opDef, nextSelSet) + // todo: handle error + if err == nil { + return atomicSelSet + } + + return nextSelSet + } + + nextSelSet := selSet + + slices.Sort(varKeys) + namespaced := make(map[string]map[string]*SetVarItem) + // todo: generalize + breaker := "" + for _, specKey := range varKeys { + ns := "" + + item := varSpecs[specKey] + specDef, ok := ComplexDefTypes[item.Spec.Name] + if !ok { + return nil, fmt.Errorf("unknown complex spec type: %s on %s", item.Spec.Name, item.Var.Key) + } + + breaker = specDef.Breaker + parts := strings.Split(specKey, "_") + for i, part := range parts { + if part == breaker { + ns = strings.Join(parts[:i+1], "_") + break + } + } + + if namespaced[ns] == nil { + namespaced[ns] = make(map[string]*SetVarItem) + } + + // if item.Spec.Name != prevNs && prevNs != "" { + // return nil, fmt.Errorf("complex spec type mismatch in namespace %q: %s != %s", ns, item.Spec.Name, prevNs) + // } + // prevNs = ns + + namespaced[ns][specKey] = item + } + + for ns, vars := range namespaced { + nextSelSet = reduceNamespacedSpec(vars, ns, nextSelSet) + } + + return nextSelSet, nil } } @@ -922,7 +1095,7 @@ type Query struct { doc *ast.Document } -func NewQuery(name string, varDefs []*ast.VariableDefinition, reducers []QueryNodeReducer) (*Query, error) { +func (s *Store) NewQuery(name string, varDefs []*ast.VariableDefinition, reducers []QueryNodeReducer) (*Query, error) { selSet := ast.NewSelectionSet(&ast.SelectionSet{}) opDef := ast.NewOperationDefinition(&ast.OperationDefinition{ Operation: "query", @@ -947,7 +1120,7 @@ func NewQuery(name string, varDefs []*ast.VariableDefinition, reducers []QueryNo var err error for _, reducer := range reducers { - if selSet, err = reducer(opDef, selSet); err != nil { + if selSet, err = reducer(s.opSets, opDef, selSet); err != nil { return nil, err } } diff --git a/internal/owl/required.go b/internal/owl/required.go new file mode 100644 index 000000000..8f17b1646 --- /dev/null +++ b/internal/owl/required.go @@ -0,0 +1,63 @@ +package owl + +import "fmt" + +type RequiredError struct { + varItem *SetVarItem + code ValidateErrorType +} + +func NewRequiredError(varItem *SetVarItem) *RequiredError { + return &RequiredError{ + varItem: varItem, + code: ValidateErrorVarRequired, + } +} + +func (e RequiredError) VarItem() *SetVarItem { + return e.varItem +} + +func (e RequiredError) Error() string { + return fmt.Sprintf("Error %v: Variable \"%s\" is unresolved but declared as required by \"%s!\" in \"%s\"", + e.Code(), + e.Key(), + e.SpecName(), + e.Source()) +} + +func (e RequiredError) Message() string { + return e.Error() +} + +func (e RequiredError) String() string { + return e.Error() +} + +func (e RequiredError) Code() ValidateErrorType { + return e.code +} + +func (e RequiredError) Key() string { + return e.varItem.Var.Key +} + +func (e RequiredError) SpecName() string { + return e.varItem.Spec.Name +} + +func (e RequiredError) Source() string { + if e.varItem.Spec.Operation == nil { + return "-" + } + if e.varItem.Spec.Operation.Source == "" { + return "-" + } + return e.varItem.Spec.Operation.Source +} + +// make sure interfaces are satisfied +var ( + _ ValidationError = new(RequiredError) + _ error = new(RequiredError) +) diff --git a/internal/owl/store.go b/internal/owl/store.go index 893651bc7..d40806016 100644 --- a/internal/owl/store.go +++ b/internal/owl/store.go @@ -2,16 +2,19 @@ package owl import ( "bytes" + "context" "encoding/json" - "errors" "fmt" "slices" "strings" "sync" "time" + "github.com/pkg/errors" + "github.com/graphql-go/graphql" "github.com/stateful/godotenv" + commandpkg "github.com/stateful/runme/v3/internal/command" "go.uber.org/zap" ) @@ -37,6 +40,13 @@ type OperationSet struct { values map[string]*SetVarValue } +type ComplexOperationSet struct { + *OperationSet + Name string + Namespace string + Keys []string +} + type setVarOperation struct { Order uint `json:"-"` Kind setOperationKind `json:"kind"` @@ -46,7 +56,7 @@ type setVarOperation struct { type varValue struct { Original string `json:"original,omitempty"` Resolved string `json:"resolved,omitempty"` - Status string `json:"status"` + Status string `json:"status,omitempty"` Operation *setVarOperation `json:"operation"` } @@ -54,6 +64,9 @@ type varSpec struct { Name string `json:"name"` Required bool `json:"required"` Description string `json:"description"` + Complex string `json:"-"` + Namespace string `json:"-"` + Rules string `json:"validator,omitempty"` Operation *setVarOperation `json:"operation"` Error ValidationError `json:"-"` Checked bool `json:"checked"` @@ -97,6 +110,54 @@ func (res SetVarItems) sortbyKey() { }) } +func (res SetVarItems) getSensitiveKeys(data interface{}) ([]string, error) { + validate, err := extractDataKey(data, "validate") + if err != nil { + return nil, errors.Wrap(err, "failed to extract validate key") + } + + m, ok := validate.(map[string]interface{}) + if !ok { + return nil, errors.New("not a map") + } + + specsSensitivity := make(map[string]bool) + var recurse func(map[string]interface{}, string) + recurse = func(m map[string]interface{}, parentName string) { + _, found := specsSensitivity[parentName] + if !found && parentName != "" { + specsSensitivity[parentName] = true + } + for k, v := range m { + // truly sensitive secrets require both mask & sensitive to be true + if k == "mask" || k == "sensitive" { + specsSensitivity[parentName] = specsSensitivity[parentName] && v.(bool) + } + + if k == "done" { + break + } + + n, ok := v.(map[string]interface{}) + if !ok { + continue + } + + recurse(n, k) + } + } + recurse(m, "") + + var filtered []string + for _, item := range res { + if specsSensitivity[item.Spec.Name] { + filtered = append(filtered, item.Var.Key) + } + } + + return filtered, nil +} + func (res SetVarItems) sort() { slices.SortFunc(res, func(i, j *SetVarItem) int { if i.Spec == nil { @@ -160,6 +221,20 @@ func WithSpecs(included bool) OperationSetOption { } } +func WithItems(items SetVarItems) OperationSetOption { + return func(opSet *OperationSet) error { + for _, item := range items { + if item.Spec != nil { + opSet.specs[item.Var.Key] = &SetVarSpec{Var: item.Var, Spec: item.Spec} + } + if item.Value != nil { + opSet.values[item.Var.Key] = &SetVarValue{Var: item.Var, Value: item.Value} + } + } + return nil + } +} + func (s *OperationSet) addEnvs(source string, envs ...string) error { for _, env := range envs { parts := strings.Split(env, "=") @@ -363,6 +438,10 @@ func (s *Store) InsecureGet(k string) (string, error) { return "", err } + if res.Value == nil { + return "", nil + } + return res.Value.Resolved, nil } @@ -388,12 +467,12 @@ func (s *Store) SensitiveKeys() ([]string, error) { defer s.mu.RUnlock() var query, vars bytes.Buffer - err := s.sensitiveQuery(&query, &vars) + err := s.sensitiveKeysQuery(&query, &vars) if err != nil { return nil, err } - // s.logger.Debug("snapshot query", zap.String("query", query.String())) + // s.logger.Debug("sensitive keys query", zap.String("query", query.String())) // _, _ = fmt.Println(query.String()) var varValues map[string]interface{} @@ -436,42 +515,55 @@ func (s *Store) SensitiveKeys() ([]string, error) { } keyResults.sortbyKey() - - keys := make([]string, 0, len(keyResults)) - for _, item := range keyResults { - keys = append(keys, item.Var.Key) + keys, err := keyResults.getSensitiveKeys(result.Data) + if err != nil { + return nil, err } return keys, nil } -func (s *Store) Update(newOrUpdated, deleted []string) error { +func (s *Store) Update(context context.Context, newOrUpdated, deleted []string) error { s.mu.Lock() defer s.mu.Unlock() - updateOpSet, err := NewOperationSet(WithOperation(UpdateSetOperation), WithSpecs(false)) - if err != nil { - return err + execInfo, ok := context.Value(commandpkg.ExecutionInfoKey).(*commandpkg.ExecutionInfo) + if !ok { + return errors.New("execution info not found in context") } - err = updateOpSet.addEnvs("[execution]", newOrUpdated...) - if err != nil { - return err + execRef := fmt.Sprintf("#%s", execInfo.KnownID) + if execInfo.KnownName != "" { + execRef = fmt.Sprintf("#%s", execInfo.KnownName) } - s.opSets = append(s.opSets, updateOpSet) + if len(newOrUpdated) > 0 { + updateOpSet, err := NewOperationSet(WithOperation(UpdateSetOperation), WithSpecs(false)) + if err != nil { + return err + } - deleteOpSet, err := NewOperationSet(WithOperation(DeleteSetOperation), WithSpecs(false)) - if err != nil { - return err - } + err = updateOpSet.addEnvs(execRef, newOrUpdated...) + if err != nil { + return err + } - err = deleteOpSet.addEnvs("[execution]", deleted...) - if err != nil { - return err + s.opSets = append(s.opSets, updateOpSet) } - s.opSets = append(s.opSets, deleteOpSet) + if len(deleted) > 0 { + deleteOpSet, err := NewOperationSet(WithOperation(DeleteSetOperation), WithSpecs(false)) + if err != nil { + return err + } + + err = deleteOpSet.addEnvs(execRef, deleted...) + if err != nil { + return err + } + + s.opSets = append(s.opSets, deleteOpSet) + } // s.logger.Debug("opSets size", zap.Int("size", len(s.opSets))) @@ -512,6 +604,9 @@ func (s *Store) snapshot(insecure bool) (SetVarItems, error) { return nil, fmt.Errorf("graphql errors %s", result.Errors) } + // rj, _ := json.MarshalIndent(result.Data, "", " ") + // fmt.Println(string(rj)) + val, err := extractDataKey(result.Data, "snapshot") if err != nil { return nil, err diff --git a/internal/owl/store_test.go b/internal/owl/store_test.go index a2742c7b2..099db3a6c 100644 --- a/internal/owl/store_test.go +++ b/internal/owl/store_test.go @@ -83,7 +83,7 @@ func Test_Store(t *testing.T) { require.NotNil(t, store) var query, vars bytes.Buffer - err = store.sensitiveQuery(&query, &vars) + err = store.sensitiveKeysQuery(&query, &vars) require.NoError(t, err) fmt.Println(query.String()) @@ -147,12 +147,11 @@ HOMEBREW_REPOSITORY=where homebrew lives # Plain`) } func Test_Store_Specless(t *testing.T) { - t.Skip("Restore fixture data") t.Parallel() - rawEnvLocal, err := os.ReadFile("../../pkg/project/test_project/.env.local") + rawEnvLocal, err := os.ReadFile("testdata/project/.env.local") require.NoError(t, err) - rawEnv, err := os.ReadFile("../../pkg/project/test_project/.env") + rawEnv, err := os.ReadFile("testdata/project/.env") require.NoError(t, err) store, err := NewStore( @@ -418,7 +417,7 @@ HOMEBREW_REPOSITORY= # Plain`) require.EqualValues(t, "UNRESOLVED", snapshot2.Value.Status) require.Greater(t, len(snapshot2.Errors), 0) require.EqualValues(t, snapshot2.Errors[0].Code, 0) - require.EqualValues(t, snapshot2.Errors[0], &SetVarError{Code: 0, Message: "Error 0: Variable \"INSTRUMENTATION_KEY\" is unresolved but defined as required by \"Secret!\" in \".env.example\""}) + require.EqualValues(t, snapshot2.Errors[0], &SetVarError{Code: 0, Message: "Error 0: Variable \"INSTRUMENTATION_KEY\" is unresolved but declared as required by \"Secret!\" in \".env.example\""}) snapshot3 := snapshot[3] require.EqualValues(t, "PGPASS", snapshot3.Var.Key) @@ -428,7 +427,7 @@ HOMEBREW_REPOSITORY= # Plain`) require.EqualValues(t, "", snapshot3.Value.Original) require.EqualValues(t, "UNRESOLVED", snapshot3.Value.Status) require.Greater(t, len(snapshot3.Errors), 0) - require.EqualValues(t, snapshot3.Errors[0], &SetVarError{Code: 0, Message: "Error 0: Variable \"PGPASS\" is unresolved but defined as required by \"Password!\" in \".env.example\""}) + require.EqualValues(t, snapshot3.Errors[0], &SetVarError{Code: 0, Message: "Error 0: Variable \"PGPASS\" is unresolved but declared as required by \"Password!\" in \".env.example\""}) }) } diff --git a/internal/owl/testdata/project/.env b/internal/owl/testdata/project/.env new file mode 100644 index 000000000..6a0a72247 --- /dev/null +++ b/internal/owl/testdata/project/.env @@ -0,0 +1,2 @@ +SECRET_1=secret1_overridden +SECRET_2=secret2 diff --git a/internal/owl/testdata/project/.env.local b/internal/owl/testdata/project/.env.local new file mode 100644 index 000000000..e1960b5c4 --- /dev/null +++ b/internal/owl/testdata/project/.env.local @@ -0,0 +1,2 @@ +SECRET_1=secret1 +SECRET_3=secret3 diff --git a/internal/owl/validate.go b/internal/owl/validate.go index 233568d9e..8518ac1e5 100644 --- a/internal/owl/validate.go +++ b/internal/owl/validate.go @@ -1,6 +1,12 @@ package owl -import "fmt" +import ( + "fmt" + "strings" + + valid "github.com/go-playground/validator/v10" + "github.com/xo/dburl" +) type ValidationError interface { fmt.Stringer @@ -17,55 +23,144 @@ type ValidationErrors []ValidationError type ValidateErrorType uint8 +//revive:disable:var-naming const ( ValidateErrorVarRequired ValidateErrorType = iota + ValidateErrorTagFailed + ValidateErrorDatabaseUrl +) + +type DatabaseUrlError struct { + varItem *SetVarItem + code ValidateErrorType + item string + error error +} + +func NewDatabaseUrlError(varItem *SetVarItem, err error, item string) *DatabaseUrlError { + return &DatabaseUrlError{ + varItem: varItem, + code: ValidateErrorDatabaseUrl, + item: item, + error: err, + } +} + +//revive:enable:var-naming + +func (e DatabaseUrlError) VarItem() *SetVarItem { + return e.varItem +} + +func (e DatabaseUrlError) Error() string { + return fmt.Sprintf("Error %v: The value of variable \"%s\" failed DatabaseUrl validation \"%s\" required by \"%s->%s\" declared in \"%s\"", + e.Code(), + e.Key(), + e.error.Error(), + e.SpecName(), + e.Item(), + e.Source()) +} + +func (e DatabaseUrlError) Message() string { + return e.Error() +} + +func (e DatabaseUrlError) String() string { + return e.Error() +} + +func (e DatabaseUrlError) Code() ValidateErrorType { + return e.code +} + +func (e DatabaseUrlError) Key() string { + return e.varItem.Var.Key +} + +func (e DatabaseUrlError) SpecName() string { + return e.varItem.Spec.Name +} + +func (e DatabaseUrlError) Item() string { + return e.item +} + +func (e DatabaseUrlError) Source() string { + if e.varItem.Spec.Operation == nil { + return "-" + } + if e.varItem.Spec.Operation.Source == "" { + return "-" + } + return e.varItem.Spec.Operation.Source +} + +// make sure interfaces are satisfied +var ( + _ ValidationError = new(DatabaseUrlError) + _ error = new(DatabaseUrlError) ) -type RequiredError struct { +type TagFailedError struct { varItem *SetVarItem code ValidateErrorType + tag string + item string } -func NewRequiredError(varItem *SetVarItem) *RequiredError { - return &RequiredError{ +func NewTagFailedError(varItem *SetVarItem, tag string, item string) *TagFailedError { + return &TagFailedError{ varItem: varItem, - code: ValidateErrorVarRequired, + code: ValidateErrorTagFailed, + tag: tag, + item: item, } } -func (e RequiredError) VarItem() *SetVarItem { +func (e TagFailedError) VarItem() *SetVarItem { return e.varItem } -func (e RequiredError) Error() string { - return fmt.Sprintf("Error %v: Variable \"%s\" is unresolved but defined as required by \"%s!\" in \"%s\"", +func (e TagFailedError) Error() string { + return fmt.Sprintf("Error %v: The value of variable \"%s\" failed tag validation \"%s\" required by \"%s->%s\" declared in \"%s\"", e.Code(), e.Key(), + e.Tag(), e.SpecName(), + e.Item(), e.Source()) } -func (e RequiredError) Message() string { +func (e TagFailedError) Message() string { return e.Error() } -func (e RequiredError) String() string { +func (e TagFailedError) String() string { return e.Error() } -func (e RequiredError) Code() ValidateErrorType { +func (e TagFailedError) Code() ValidateErrorType { return e.code } -func (e RequiredError) Key() string { +func (e TagFailedError) Key() string { return e.varItem.Var.Key } -func (e RequiredError) SpecName() string { +func (e TagFailedError) Tag() string { + return e.tag +} + +func (e TagFailedError) SpecName() string { return e.varItem.Spec.Name } -func (e RequiredError) Source() string { +func (e TagFailedError) Item() string { + return e.item +} + +func (e TagFailedError) Source() string { if e.varItem.Spec.Operation == nil { return "-" } @@ -77,6 +172,177 @@ func (e RequiredError) Source() string { // make sure interfaces are satisfied var ( - _ ValidationError = new(RequiredError) - _ error = new(RequiredError) + _ ValidationError = new(TagFailedError) + _ error = new(TagFailedError) ) + +const ComplexSpecType string = "Complex" + +var validator = valid.New() + +type ComplexDef struct { + Name string + Breaker string + Items map[string]*varSpec + Validator func(item *varSpec, itemKey string, varItem *SetVarItem) (ValidationErrors, error) +} + +func (cd *ComplexDef) Validate(itemKey string, varItem *SetVarItem) (ValidationErrors, error) { + complexItem, ok := cd.Items[itemKey] + if !ok { + return nil, fmt.Errorf("complex item not found: %s", itemKey) + } + + if varItem.Value.Resolved == "" && !complexItem.Required { + return nil, nil + } + + return cd.Validator(complexItem, itemKey, varItem) +} + +func TagValidator(item *varSpec, itemKey string, varItem *SetVarItem) (ValidationErrors, error) { + data := make(map[string]interface{}, 1) + rules := make(map[string]interface{}, 1) + + data[varItem.Var.Key] = varItem.Value.Resolved + rules[varItem.Var.Key] = item.Rules + + field := validator.ValidateMap(data, rules) + + var validationErrs ValidationErrors + for _, errs := range field { + verrs, ok := errs.(valid.ValidationErrors) + if !ok { + return nil, fmt.Errorf("unexpected error type: %T", errs) + } + for _, err := range verrs { + validationErrs = append(validationErrs, + NewTagFailedError( + &SetVarItem{ + Var: varItem.Var, + Value: varItem.Value, + Spec: varItem.Spec, + }, + err.Tag(), + itemKey, + ), + ) + } + } + + return validationErrs, nil +} + +func DatabaseValidator(item *varSpec, itemKey string, varItem *SetVarItem) (ValidationErrors, error) { + var validationErrs ValidationErrors + + _, err := dburl.Parse(varItem.Value.Resolved) + if err != nil { + validationErrs = append(validationErrs, + NewDatabaseUrlError( + &SetVarItem{ + Var: varItem.Var, + Value: varItem.Value, + Spec: varItem.Spec, + }, + err, + itemKey, + )) + } + + return validationErrs, nil +} + +var ComplexDefTypes = map[string]*ComplexDef{ + "Redis": { + Name: "Redis", + Breaker: "REDIS", + Items: map[string]*varSpec{ + "HOST": { + Name: SpecNamePlain, + Rules: "ip|hostname", + Required: true, + }, + "PORT": { + Name: SpecNamePlain, + Rules: "number", + Required: true, + }, + "PASSWORD": { + Name: SpecNamePassword, + Rules: "min=18,max=32", + Required: false, + }, + }, + Validator: TagValidator, + }, + "Postgres": { + Name: "Postgres", + Breaker: "POSTGRES", + Items: map[string]*varSpec{ + "HOST": { + Name: SpecNamePlain, + Rules: "required,ip|hostname", + Required: true, + }, + }, + Validator: TagValidator, + }, + "DatabaseUrl": { + Name: "DatabaseUrl", + Breaker: "DATABASE", + Items: map[string]*varSpec{ + "URL": { + Name: SpecNameSecret, + Rules: "url", + Required: true, + }, + }, + Validator: DatabaseValidator, + }, +} + +func (s *ComplexOperationSet) validate() (ValidationErrors, error) { + var validationErrs ValidationErrors + + for _, k := range s.Keys { + spec, ok := s.specs[k] + if !ok { + return nil, fmt.Errorf("spec not found for key: %s", k) + } + + if spec.Var.Key != k { + continue + } + + complexType, ok := ComplexDefTypes[spec.Spec.Name] + if !ok { + return nil, fmt.Errorf("complex type not found: %s", spec.Spec.Name) + } + + val, ok := s.values[spec.Var.Key] + if !ok { + return nil, fmt.Errorf("value not found for key: %s", spec.Var.Key) + } + + varKeyParts := strings.Split(val.Var.Key, complexType.Breaker+"_") + if len(varKeyParts) < 2 { + return nil, fmt.Errorf("invalid key not matching complex item: %s", val.Var.Key) + } + + complexItemKey := (varKeyParts[len(varKeyParts)-1]) + verrs, err := complexType.Validate( + complexItemKey, + &SetVarItem{ + Var: val.Var, + Value: val.Value, + Spec: spec.Spec, + }) + if err != nil { + return nil, err + } + validationErrs = append(validationErrs, verrs...) + } + + return validationErrs, nil +} diff --git a/internal/owl/validate_test.go b/internal/owl/validate_test.go new file mode 100644 index 000000000..39ef11b9a --- /dev/null +++ b/internal/owl/validate_test.go @@ -0,0 +1,151 @@ +//go:build !windows + +package owl + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_Store_ComplexSpecs(t *testing.T) { + fakeNS := []byte(`GOPATH=/Users/sourishkrout/go + INSTRUMENTATION_KEY=05a2cc58-5101-4c69-a0d0-7a126253a972 # Secret! + PGPASS=secret-fake-password # Password! + HOMEBREW_REPOSITORY=/opt/homebrew # Plain + POSTGRES_HOST=127.0.0.1 # Postgres! + QUEUES_REDIS_HOST=127.0.0.2 # Redis! + QUEUES_REDIS_PORT=6379 # Redis! + PUBSUB_REDIS_HOST=127.0.0.3 # Redis! + PUBSUB_REDIS_PORT=6379 # Redis! + RATELIMITER_REDIS_HOST=127.0.0.4 # Redis + GCLOUD_2_REDIS_HOST=127.0.0.5 # Redis + REDIS_PASSWORD=fake-redis-password # Redis! + REDIS_HOST=localhost # Redis! + REDIS_PORT=6379 # Redis!`) + + t.Run("Getter without namespace", func(t *testing.T) { + fake := []byte(`GOPATH=/Users/sourishkrout/go + INSTRUMENTATION_KEY=05a2cc58-5101-4c69-a0d0-7a126253a972 # Secret! + PGPASS=secret-fake-password # Password! + HOMEBREW_REPOSITORY=/opt/homebrew # Plain + REDIS_HOST=localhost # Redis! + REDIS_PORT=6379 # Redis!`) + + store, err := NewStore(withSpecsFile(".env.example", fake, true), WithEnvFile(".env", fake)) + require.NoError(t, err) + require.NotNil(t, store) + + val, err := store.InsecureGet("REDIS_HOST") + require.NoError(t, err) + assert.EqualValues(t, "localhost", val) + }) + + t.Run("Getter with namespaces", func(t *testing.T) { + store, err := NewStore(withSpecsFile(".env.example", fakeNS, true), WithEnvFile(".env", fakeNS)) + require.NoError(t, err) + require.NotNil(t, store) + + val, err := store.InsecureGet("REDIS_HOST") + require.NoError(t, err) + assert.EqualValues(t, "localhost", val) + }) + + t.Run("Snapshot with namespaces", func(t *testing.T) { + store, err := NewStore(withSpecsFile(".env.example", fakeNS, true), WithEnvFile(".env", fakeNS)) + require.NoError(t, err) + require.NotNil(t, store) + + snapshot, err := store.Snapshot() + require.NoError(t, err) + + snapshot.sortbyKey() + assert.EqualValues(t, "GCLOUD_2_REDIS_HOST", snapshot[0].Var.Key) + assert.EqualValues(t, "127.0.0.5", snapshot[0].Value.Resolved) + }) +} + +func Test_Store_ComplexWithTagValidation(t *testing.T) { + t.Run("Invalid env values", func(t *testing.T) { + fake := []byte(`GOPATH=/Users/sourishkrout/go + INSTRUMENTATION_KEY=05a2cc58-5101-4c69-a0d0-7a126253a972 # Secret! + HOMEBREW_REPOSITORY=/opt/homebrew # Plain + REDIS_HOST=12345 # Redis! + REDIS_PORT=invalid-port # Redis!`) + store, err := NewStore(withSpecsFile(".env.example", fake, true), WithEnvFile(".env", fake)) + require.NoError(t, err) + require.NotNil(t, store) + + snapshot, err := store.Snapshot() + require.NoError(t, err) + + snapshot.sortbyKey() + assert.EqualValues(t, "REDIS_HOST", snapshot[3].Var.Key) + assert.EqualValues(t, "12345", snapshot[3].Value.Resolved) + assert.EqualValues(t, + `Error 1: The value of variable "REDIS_HOST" failed tag validation "ip|hostname" required by "Redis->HOST" declared in ".env.example"`, + snapshot[3].Errors[0].Message, + ) + + assert.EqualValues(t, "REDIS_PORT", snapshot[4].Var.Key) + assert.EqualValues(t, "invalid-port", snapshot[4].Value.Resolved) + assert.EqualValues(t, + `Error 1: The value of variable "REDIS_PORT" failed tag validation "number" required by "Redis->PORT" declared in ".env.example"`, + snapshot[4].Errors[0].Message, + ) + }) +} + +func Test_Store_ComplexWithDbUrlValidation(t *testing.T) { + t.Run("Valid", func(t *testing.T) { + fake := []byte(`GOPATH=/Users/sourishkrout/go + DATABASE_URL=postgres://platform:platform@localhost:5432/platform # DatabaseUrl`) + store, err := NewStore(withSpecsFile(".env.example", fake, true), WithEnvFile(".env", fake)) + require.NoError(t, err) + require.NotNil(t, store) + + snapshot, err := store.Snapshot() + require.NoError(t, err) + snapshot.sortbyKey() + require.Len(t, snapshot[0].Errors, 0) + }) + + t.Run("Invalid scheme", func(t *testing.T) { + fake := []byte(`GOPATH=/Users/sourishkrout/go + DATABASE_URL=abcdef://platform:platform@localhost:5432/platform # DatabaseUrl`) + store, err := NewStore(withSpecsFile(".env.example", fake, true), WithEnvFile(".env", fake)) + require.NoError(t, err) + require.NotNil(t, store) + + snapshot, err := store.Snapshot() + require.NoError(t, err) + + snapshot.sortbyKey() + assert.EqualValues(t, "DATABASE_URL", snapshot[0].Var.Key) + assert.EqualValues(t, "abc...orm", snapshot[0].Value.Resolved) + assert.EqualValues(t, + `Error 2: The value of variable "DATABASE_URL" failed DatabaseUrl validation "unknown database scheme" required by "DatabaseUrl->URL" declared in ".env.example"`, + snapshot[0].Errors[0].Message, + ) + }) + + t.Run("Invalid format", func(t *testing.T) { + fake := []byte(`GOPATH=/Users/sourishkrout/go + DATABASE_URL=this-is-not-a-database-url # DatabaseUrl`) + store, err := NewStore(withSpecsFile(".env.example", fake, true), WithEnvFile(".env", fake)) + require.NoError(t, err) + require.NotNil(t, store) + + snapshot, err := store.Snapshot() + require.NoError(t, err) + + snapshot.sortbyKey() + assert.EqualValues(t, "DATABASE_URL", snapshot[0].Var.Key) + assert.EqualValues(t, "thi...url", snapshot[0].Value.Resolved) + assert.EqualValues(t, + `Error 2: The value of variable "DATABASE_URL" failed DatabaseUrl validation "invalid database scheme" required by "DatabaseUrl->URL" declared in ".env.example"`, + snapshot[0].Errors[0].Message, + ) + }) +} diff --git a/internal/runner/command.go b/internal/runner/command.go index 169e3c387..62762dd74 100644 --- a/internal/runner/command.go +++ b/internal/runner/command.go @@ -51,9 +51,10 @@ type command struct { tempScriptFile string - wg sync.WaitGroup - mu sync.Mutex - err error + context context.Context + wg sync.WaitGroup + mu sync.Mutex + err error logger *zap.Logger } @@ -103,7 +104,7 @@ type commandConfig struct { Logger *zap.Logger } -func newCommand(cfg *commandConfig) (*command, error) { +func newCommand(context context.Context, cfg *commandConfig) (*command, error) { var pathEnv string // If PATH is set in the session, use it in the system @@ -244,6 +245,7 @@ func newCommand(cfg *commandConfig) (*command, error) { args = append(args, cfg.Args...) cmd := &command{ + context: context, ProgramPath: programPath, Args: append(args, extraArgs...), Directory: directory, @@ -501,7 +503,7 @@ func (c *command) collectEnvs() { newEnvStore(endEnvs...), ) - err = c.Session.UpdateStore(c.cmd.Env, newOrUpdated, deleted) + err = c.Session.UpdateStore(c.context, c.cmd.Env, newOrUpdated, deleted) c.seterr(err) } diff --git a/internal/runner/command_test.go b/internal/runner/command_test.go index 2c30d3159..e5cdfad36 100644 --- a/internal/runner/command_test.go +++ b/internal/runner/command_test.go @@ -32,6 +32,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Stdout: stdout, @@ -59,6 +60,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Stdout: stdout, @@ -86,6 +88,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "", LanguageID: "shellscript", @@ -114,6 +117,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "", LanguageID: "js", @@ -142,6 +146,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "/usr/bin/env node", LanguageID: "js", @@ -170,6 +175,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "", LanguageID: "sql", @@ -200,6 +206,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Tty: true, @@ -231,6 +238,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Tty: true, @@ -266,6 +274,7 @@ func Test_command(t *testing.T) { _, _ = stdin.WriteString("hello") cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Stdin: stdin, @@ -295,6 +304,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Tty: true, @@ -337,6 +347,7 @@ func Test_command(t *testing.T) { _, _ = stdin.WriteString("hello") cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Stdin: stdin, @@ -371,6 +382,7 @@ func Test_command(t *testing.T) { stderr := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Tty: true, @@ -427,6 +439,7 @@ func Test_command(t *testing.T) { require.NoError(t, err) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Session: session, @@ -473,6 +486,7 @@ func Test_command(t *testing.T) { stdin := new(bytes.Buffer) cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Stdout: stdout, @@ -502,6 +516,7 @@ func Test_command_Stop(t *testing.T) { t.Parallel() cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Stdin: bytes.NewBuffer(nil), @@ -529,6 +544,7 @@ func Test_command_Stop(t *testing.T) { func Test_exitCodeFromErr(t *testing.T) { cmd, err := newCommand( + context.Background(), &commandConfig{ ProgramName: "bash", Tty: true, diff --git a/internal/runner/service.go b/internal/runner/service.go index 49f307199..727fa2581 100644 --- a/internal/runner/service.go +++ b/internal/runner/service.go @@ -206,7 +206,8 @@ func ConvertRunnerProject(runnerProj *runnerv1.Project) (*project.Project, error } func (r *runnerService) Execute(srv runnerv1.RunnerService_ExecuteServer) error { - logger := r.logger.With(zap.String("_id", ulid.GenerateID())) + _id := ulid.GenerateID() + logger := r.logger.With(zap.String("_id", _id)) logger.Info("running Execute in runnerService") @@ -221,6 +222,13 @@ func (r *runnerService) Execute(srv runnerv1.RunnerService_ExecuteServer) error return errors.WithStack(err) } + execInfo := &commandpkg.ExecutionInfo{ + RunID: _id, + KnownName: req.GetKnownName(), + KnownID: req.GetKnownId(), + } + ctx := commandpkg.ContextWithExecutionInfo(srv.Context(), execInfo) + // We want to always log the request because it is used for AI training. // see: https://github.com/stateful/runme/issues/574 if req.KnownId != "" { @@ -255,7 +263,7 @@ func (r *runnerService) Execute(srv runnerv1.RunnerService_ExecuteServer) error } if len(req.Envs) > 0 { - err := sess.AddEnvs(req.Envs) + err := sess.AddEnvs(ctx, req.Envs) if err != nil { return err } @@ -304,7 +312,7 @@ func (r *runnerService) Execute(srv runnerv1.RunnerService_ExecuteServer) error } logger.Debug("command config", zap.Any("cfg", cfg)) - cmd, err := newCommand(cfg) + cmd, err := newCommand(ctx, cfg) if err != nil { var errInvalidLanguage ErrInvalidLanguage if errors.As(err, &errInvalidLanguage) { @@ -343,10 +351,10 @@ func (r *runnerService) Execute(srv runnerv1.RunnerService_ExecuteServer) error return err } - cmdCtx := srv.Context() + cmdCtx := ctx if req.Background { - cmdCtx = context.Background() + cmdCtx = commandpkg.ContextWithExecutionInfo(context.Background(), execInfo) } if err := cmd.StartWithOpts(cmdCtx, &startOpts{}); err != nil { @@ -518,14 +526,14 @@ func (r *runnerService) Execute(srv runnerv1.RunnerService_ExecuteServer) error } if storeStdout { - err := sess.SetEnv("__", string(stdoutMem)) + err := sess.SetEnv(ctx, "__", string(stdoutMem)) if err != nil { logger.Sugar().Errorf("%v", err) } knownName := req.GetKnownName() if knownName != "" && runnerConformsOpinionatedEnvVarNaming(knownName) { - err = sess.SetEnv(knownName, string(stdoutMem)) + err = sess.SetEnv(ctx, knownName, string(stdoutMem)) if err != nil { logger.Warn("failed to set env", zap.Error(err)) } @@ -870,6 +878,7 @@ func convertToMonitorEnvStoreResponse(msg *runnerv1.MonitorEnvStoreResponse, sna es := &runnerv1.MonitorEnvStoreResponseSnapshot_SnapshotEnv{ Name: item.Var.Key, Spec: item.Spec.Name, + IsRequired: item.Spec.Required, Origin: item.Var.Origin, OriginalValue: item.Value.Original, ResolvedValue: item.Value.Resolved, diff --git a/internal/runner/session.go b/internal/runner/session.go index cae63338c..ddcac7214 100644 --- a/internal/runner/session.go +++ b/internal/runner/session.go @@ -18,9 +18,9 @@ type envStorer interface { getEnv(string) (string, error) envs() ([]string, error) sensitiveEnvKeys() ([]string, error) - addEnvs(envs []string) error - updateStore(envs []string, newOrUpdated []string, deleted []string) error - setEnv(k string, v string) error + addEnvs(context context.Context, envs []string) error + updateStore(context context.Context, envs []string, newOrUpdated []string, deleted []string) error + setEnv(context context.Context, k string, v string) error subscribe(ctx context.Context, snapshotc chan<- owl.SetVarItems) error complete() } @@ -65,20 +65,20 @@ func NewSessionWithStore(envs []string, proj *project.Project, owlStore bool, lo return s, nil } -func (s *Session) UpdateStore(envs []string, newOrUpdated []string, deleted []string) error { - return s.envStorer.updateStore(envs, newOrUpdated, deleted) +func (s *Session) UpdateStore(context context.Context, envs []string, newOrUpdated []string, deleted []string) error { + return s.envStorer.updateStore(context, envs, newOrUpdated, deleted) } -func (s *Session) AddEnvs(envs []string) error { - return s.envStorer.addEnvs(envs) +func (s *Session) AddEnvs(context context.Context, envs []string) error { + return s.envStorer.addEnvs(context, envs) } func (s *Session) SensitiveEnvKeys() ([]string, error) { return s.envStorer.sensitiveEnvKeys() } -func (s *Session) SetEnv(k string, v string) error { - return s.envStorer.setEnv(k, v) +func (s *Session) SetEnv(context context.Context, k string, v string) error { + return s.envStorer.setEnv(context, k, v) } func (s *Session) Envs() ([]string, error) { @@ -121,7 +121,7 @@ func newRunnerStorer(sessionEnvs ...string) *runnerEnvStorer { } } -func (es *runnerEnvStorer) subscribe(ctx context.Context, snapshotc chan<- owl.SetVarItems) error { +func (es *runnerEnvStorer) subscribe(_ context.Context, snapshotc chan<- owl.SetVarItems) error { defer close(snapshotc) return fmt.Errorf("not available for runner env store") } @@ -130,7 +130,7 @@ func (es *runnerEnvStorer) complete() { // noop } -func (es *runnerEnvStorer) addEnvs(envs []string) error { +func (es *runnerEnvStorer) addEnvs(_ context.Context, envs []string) error { es.envStore.Add(envs...) return nil } @@ -152,12 +152,12 @@ func (es *runnerEnvStorer) envs() ([]string, error) { return envs, nil } -func (es *runnerEnvStorer) setEnv(k string, v string) error { +func (es *runnerEnvStorer) setEnv(_ context.Context, k string, v string) error { _, err := es.envStore.Set(k, v) return err } -func (es *runnerEnvStorer) updateStore(envs []string, newOrUpdated []string, deleted []string) error { +func (es *runnerEnvStorer) updateStore(_ context.Context, envs []string, newOrUpdated []string, deleted []string) error { es.envStore = newEnvStore(envs...).Add(newOrUpdated...).Delete(deleted...) return nil } @@ -227,7 +227,7 @@ func newOwlStorer(envs []string, proj *project.Project, logger *zap.Logger) (*ow }, nil } -func (es *owlEnvStorer) subscribe(ctx context.Context, snapshotc chan<- owl.SetVarItems) error { +func (es *owlEnvStorer) subscribe(context context.Context, snapshotc chan<- owl.SetVarItems) error { defer es.mu.Unlock() es.mu.Lock() es.logger.Debug("subscribed to owl store") @@ -235,7 +235,7 @@ func (es *owlEnvStorer) subscribe(ctx context.Context, snapshotc chan<- owl.SetV es.subscribers = append(es.subscribers, snapshotc) go func() { - <-ctx.Done() + <-context.Done() err := es.unsubscribe(snapshotc) if err != nil { es.logger.Error("unsubscribe from owl store failed", zap.Error(err)) @@ -298,16 +298,16 @@ func (es *owlEnvStorer) notifySubscribers() { } } -func (es *owlEnvStorer) updateStore(envs []string, newOrUpdated []string, deleted []string) error { - if err := es.owlStore.Update(newOrUpdated, deleted); err != nil { +func (es *owlEnvStorer) updateStore(context context.Context, envs []string, newOrUpdated []string, deleted []string) error { + if err := es.owlStore.Update(context, newOrUpdated, deleted); err != nil { return err } es.notifySubscribers() return nil } -func (es *owlEnvStorer) addEnvs(envs []string) error { - if err := es.owlStore.Update(envs, nil); err != nil { +func (es *owlEnvStorer) addEnvs(context context.Context, envs []string) error { + if err := es.owlStore.Update(context, envs, nil); err != nil { return err } es.notifySubscribers() @@ -326,9 +326,9 @@ func (es *owlEnvStorer) sensitiveEnvKeys() ([]string, error) { return vals, nil } -func (es *owlEnvStorer) setEnv(k string, v string) error { +func (es *owlEnvStorer) setEnv(context context.Context, k string, v string) error { // todo(sebastian): add checking env length inside Update - err := es.owlStore.Update([]string{fmt.Sprintf("%s=%s", k, v)}, nil) + err := es.owlStore.Update(context, []string{fmt.Sprintf("%s=%s", k, v)}, nil) if err != nil { return err } diff --git a/internal/runner/shell.go b/internal/runner/shell.go index 130a9cbc7..76c7a8866 100644 --- a/internal/runner/shell.go +++ b/internal/runner/shell.go @@ -51,6 +51,7 @@ func (s Shell) DryRun(ctx context.Context, w io.Writer) { func (s *Shell) Run(ctx context.Context) error { cmd, err := newCommand( + ctx, &commandConfig{ ProgramName: s.ProgramPath(), Directory: s.Dir, diff --git a/internal/runner/shellraw.go b/internal/runner/shellraw.go index a6ed882c5..d01cd7b40 100644 --- a/internal/runner/shellraw.go +++ b/internal/runner/shellraw.go @@ -30,6 +30,7 @@ func (s ShellRaw) DryRun(ctx context.Context, w io.Writer) { func (s ShellRaw) Run(ctx context.Context) error { cmd, err := newCommand( + ctx, &commandConfig{ ProgramName: s.ProgramPath(), Directory: s.Dir, diff --git a/internal/runner/tempfile.go b/internal/runner/tempfile.go index d83f8d2bd..b0a1c03d2 100644 --- a/internal/runner/tempfile.go +++ b/internal/runner/tempfile.go @@ -32,6 +32,7 @@ func (s TempFile) DryRun(ctx context.Context, w io.Writer) { func (s *TempFile) Run(ctx context.Context) error { cmd, err := newCommand( + ctx, &commandConfig{ ProgramName: s.ProgramName, LanguageID: s.LanguageID, diff --git a/internal/version/version.go b/internal/version/version.go index dce590ea9..a6803a090 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -12,6 +12,10 @@ var ( Commit = "unknown" ) +func BaseVersionInfo() string { + return fmt.Sprintf("%s (%s) on %s", BuildVersion, Commit, BuildDate) +} + // BaseVersion returns the base version of the application. func BaseVersion() string { v, err := semver.NewVersion(BuildVersion) diff --git a/main.go b/main.go index b9cadcd82..fa575466e 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,7 @@ func main() { func root() (status int) { root := cmd.Root() - root.Version = fmt.Sprintf("%s (%s) on %s", version.BuildVersion, version.Commit, version.BuildDate) + root.Version = version.BaseVersionInfo() rootWithCPUProfile(func() { if err := root.Execute(); err != nil { diff --git a/pkg/api/gen/proto/go/runme/runner/v1/runner.pb.go b/pkg/api/gen/proto/go/runme/runner/v1/runner.pb.go index 10eb11457..798a64b54 100644 --- a/pkg/api/gen/proto/go/runme/runner/v1/runner.pb.go +++ b/pkg/api/gen/proto/go/runme/runner/v1/runner.pb.go @@ -1913,6 +1913,7 @@ type MonitorEnvStoreResponseSnapshot_SnapshotEnv struct { CreateTime string `protobuf:"bytes,7,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` UpdateTime string `protobuf:"bytes,8,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` Errors []*MonitorEnvStoreResponseSnapshot_Error `protobuf:"bytes,9,rep,name=errors,proto3" json:"errors,omitempty"` + IsRequired bool `protobuf:"varint,10,opt,name=is_required,json=isRequired,proto3" json:"is_required,omitempty"` } func (x *MonitorEnvStoreResponseSnapshot_SnapshotEnv) Reset() { @@ -2010,6 +2011,13 @@ func (x *MonitorEnvStoreResponseSnapshot_SnapshotEnv) GetErrors() []*MonitorEnvS return nil } +func (x *MonitorEnvStoreResponseSnapshot_SnapshotEnv) GetIsRequired() bool { + if x != nil { + return x.IsRequired + } + return false +} + type MonitorEnvStoreResponseSnapshot_Error struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2273,14 +2281,14 @@ var file_runme_runner_v1_runner_proto_rawDesc = []byte{ 0x74, 0x12, 0x32, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x87, 0x05, 0x0a, 0x1f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa8, 0x05, 0x0a, 0x1f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x50, 0x0a, 0x04, 0x65, 0x6e, 0x76, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, - 0x6f, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x04, 0x65, 0x6e, 0x76, 0x73, 0x1a, 0xfe, 0x02, 0x0a, 0x0b, + 0x6f, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x04, 0x65, 0x6e, 0x76, 0x73, 0x1a, 0x9f, 0x03, 0x0a, 0x0b, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x4f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, @@ -2304,108 +2312,110 @@ var file_runme_runner_v1_runner_proto_rawDesc = []byte{ 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x1a, 0x35, 0x0a, 0x05, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x22, 0x5a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, - 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x48, 0x49, 0x44, 0x44, 0x45, 0x4e, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x45, 0x44, 0x10, 0x03, 0x22, - 0xab, 0x01, 0x0a, 0x17, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, - 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x72, 0x75, 0x6e, 0x6d, - 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x4e, 0x0a, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, - 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x48, 0x00, 0x52, 0x08, 0x73, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x5d, 0x0a, - 0x13, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, - 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, - 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, - 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x57, 0x4c, 0x10, 0x01, 0x2a, 0x5e, 0x0a, 0x0b, - 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x1c, 0x0a, 0x18, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x52, - 0x55, 0x50, 0x54, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x45, - 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x4b, 0x49, 0x4c, 0x4c, 0x10, 0x02, 0x2a, 0x81, 0x01, 0x0a, - 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x18, - 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, - 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x4c, 0x49, 0x4e, - 0x45, 0x5f, 0x53, 0x48, 0x45, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4d, - 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x5f, 0x46, - 0x49, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, - 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x4c, 0x10, 0x03, - 0x2a, 0x55, 0x0a, 0x0f, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, - 0x65, 0x67, 0x79, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, - 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, - 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x4d, 0x4f, 0x53, 0x54, 0x5f, 0x52, - 0x45, 0x43, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x2a, 0x62, 0x0a, 0x13, 0x4d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, - 0x0a, 0x22, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, - 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x01, 0x32, 0xae, 0x05, 0x0a, 0x0d, - 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x60, 0x0a, - 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x69, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x1a, 0x35, 0x0a, + 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x5a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, + 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x48, 0x49, 0x44, 0x44, 0x45, 0x4e, 0x10, 0x02, 0x12, 0x11, 0x0a, + 0x0d, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x45, 0x44, 0x10, 0x03, + 0x22, 0xab, 0x01, 0x0a, 0x17, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x72, 0x75, 0x6e, + 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x4e, 0x0a, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, + 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, + 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x48, 0x00, 0x52, 0x08, 0x73, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x5d, + 0x0a, 0x13, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, + 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, + 0x1a, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, + 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x57, 0x4c, 0x10, 0x01, 0x2a, 0x5e, 0x0a, + 0x0b, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x1c, 0x0a, 0x18, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, + 0x52, 0x55, 0x50, 0x54, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x4b, 0x49, 0x4c, 0x4c, 0x10, 0x02, 0x2a, 0x81, 0x01, + 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, + 0x18, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x43, + 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x4c, 0x49, + 0x4e, 0x45, 0x5f, 0x53, 0x48, 0x45, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, + 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x5f, + 0x46, 0x49, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, + 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x4c, 0x10, + 0x03, 0x2a, 0x55, 0x0a, 0x0f, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, + 0x74, 0x65, 0x67, 0x79, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, + 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, + 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x4d, 0x4f, 0x53, 0x54, 0x5f, + 0x52, 0x45, 0x43, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x2a, 0x62, 0x0a, 0x13, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x26, 0x0a, 0x22, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, + 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x01, 0x32, 0xae, 0x05, 0x0a, + 0x0d, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x60, + 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, + 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x57, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, - 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x57, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x2e, 0x72, 0x75, 0x6e, 0x6d, + 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x6d, + 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x0f, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, - 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, - 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, - 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x0f, 0x4d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x27, 0x2e, 0x72, - 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, - 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, - 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x30, 0x01, 0x12, 0x52, 0x0a, 0x07, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x1f, - 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x63, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x6d, - 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, - 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, - 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, 0x4a, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x66, 0x75, 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, - 0x6f, 0x2f, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x76, - 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, + 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x30, 0x01, 0x12, 0x52, 0x0a, 0x07, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, + 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x63, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x26, 0x2e, 0x72, 0x75, 0x6e, + 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, + 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, + 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x66, 0x75, 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, + 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x67, 0x6f, 0x2f, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f, + 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/api/gen/proto/go/runme/runner/v2alpha1/runner.pb.go b/pkg/api/gen/proto/go/runme/runner/v2alpha1/runner.pb.go index c9cf03c49..d22946b5e 100644 --- a/pkg/api/gen/proto/go/runme/runner/v2alpha1/runner.pb.go +++ b/pkg/api/gen/proto/go/runme/runner/v2alpha1/runner.pb.go @@ -1809,12 +1809,13 @@ type MonitorEnvStoreResponseSnapshot_SnapshotEnv struct { Status MonitorEnvStoreResponseSnapshot_Status `protobuf:"varint,1,opt,name=status,proto3,enum=runme.runner.v2alpha1.MonitorEnvStoreResponseSnapshot_Status" json:"status,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Spec string `protobuf:"bytes,3,opt,name=spec,proto3" json:"spec,omitempty"` - Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` - OriginalValue string `protobuf:"bytes,5,opt,name=original_value,json=originalValue,proto3" json:"original_value,omitempty"` - ResolvedValue string `protobuf:"bytes,6,opt,name=resolved_value,json=resolvedValue,proto3" json:"resolved_value,omitempty"` - CreateTime string `protobuf:"bytes,7,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` - UpdateTime string `protobuf:"bytes,8,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` - Errors []*MonitorEnvStoreResponseSnapshot_Error `protobuf:"bytes,9,rep,name=errors,proto3" json:"errors,omitempty"` + IsRequired bool `protobuf:"varint,4,opt,name=is_required,json=isRequired,proto3" json:"is_required,omitempty"` + Origin string `protobuf:"bytes,5,opt,name=origin,proto3" json:"origin,omitempty"` + OriginalValue string `protobuf:"bytes,6,opt,name=original_value,json=originalValue,proto3" json:"original_value,omitempty"` + ResolvedValue string `protobuf:"bytes,7,opt,name=resolved_value,json=resolvedValue,proto3" json:"resolved_value,omitempty"` + CreateTime string `protobuf:"bytes,8,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` + UpdateTime string `protobuf:"bytes,9,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` + Errors []*MonitorEnvStoreResponseSnapshot_Error `protobuf:"bytes,10,rep,name=errors,proto3" json:"errors,omitempty"` } func (x *MonitorEnvStoreResponseSnapshot_SnapshotEnv) Reset() { @@ -1870,6 +1871,13 @@ func (x *MonitorEnvStoreResponseSnapshot_SnapshotEnv) GetSpec() string { return "" } +func (x *MonitorEnvStoreResponseSnapshot_SnapshotEnv) GetIsRequired() bool { + if x != nil { + return x.IsRequired + } + return false +} + func (x *MonitorEnvStoreResponseSnapshot_SnapshotEnv) GetOrigin() string { if x != nil { return x.Origin @@ -2184,7 +2192,7 @@ var file_runme_runner_v2alpha1_runner_proto_rawDesc = []byte{ 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x99, 0x05, 0x0a, 0x1f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xba, 0x05, 0x0a, 0x1f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x56, 0x0a, 0x04, 0x65, 0x6e, 0x76, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, @@ -2192,7 +2200,7 @@ var file_runme_runner_v2alpha1_runner_proto_rawDesc = []byte{ 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x04, 0x65, 0x6e, - 0x76, 0x73, 0x1a, 0x8a, 0x03, 0x0a, 0x0b, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x45, + 0x76, 0x73, 0x1a, 0xab, 0x03, 0x0a, 0x0b, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x55, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, @@ -2201,128 +2209,130 @@ var file_runme_runner_v2alpha1_runner_proto_rawDesc = []byte{ 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x70, 0x65, - 0x63, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x72, 0x69, - 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x06, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x72, 0x75, 0x6e, 0x6d, - 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, - 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x1a, - 0x35, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x5a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x48, 0x49, 0x44, 0x44, 0x45, 0x4e, 0x10, 0x02, 0x12, - 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x45, 0x44, - 0x10, 0x03, 0x22, 0xb7, 0x01, 0x0a, 0x17, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, - 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x72, - 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x54, - 0x0a, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x36, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, - 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x48, 0x00, 0x52, 0x08, 0x73, 0x6e, 0x61, 0x70, - 0x73, 0x68, 0x6f, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x5d, 0x0a, 0x13, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x45, - 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x53, - 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x57, 0x4c, 0x10, 0x01, 0x2a, 0x5e, 0x0a, 0x0b, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x52, 0x55, - 0x50, 0x54, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x45, 0x5f, - 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x4b, 0x49, 0x4c, 0x4c, 0x10, 0x02, 0x2a, 0x55, 0x0a, 0x0f, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x20, - 0x0a, 0x1c, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, - 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, - 0x54, 0x45, 0x47, 0x59, 0x5f, 0x4d, 0x4f, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x4e, 0x54, - 0x10, 0x01, 0x2a, 0x62, 0x0a, 0x13, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x4d, 0x4f, 0x4e, - 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x56, - 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x41, 0x50, - 0x53, 0x48, 0x4f, 0x54, 0x10, 0x01, 0x32, 0xf0, 0x06, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x6e, 0x65, - 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x6d, - 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, - 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, - 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, - 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x0c, 0x4c, - 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x2e, 0x72, 0x75, - 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, - 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, - 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, - 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, - 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, - 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x74, 0x0a, 0x0f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2d, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, - 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x6f, - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, - 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5e, 0x0a, 0x07, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x12, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, - 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x75, 0x6e, + 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x06, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6f, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, - 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x2c, 0x2e, 0x72, 0x75, 0x6e, + 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, + 0x6f, 0x74, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, + 0x1a, 0x35, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x5a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x11, 0x0a, + 0x0d, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x48, 0x49, 0x44, 0x44, 0x45, 0x4e, 0x10, 0x02, + 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x45, + 0x44, 0x10, 0x03, 0x22, 0xb7, 0x01, 0x0a, 0x17, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, + 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, + 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x54, 0x0a, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x36, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, + 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x48, 0x00, 0x52, 0x08, 0x73, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x5d, 0x0a, + 0x13, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, + 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, + 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x57, 0x4c, 0x10, 0x01, 0x2a, 0x5e, 0x0a, 0x0b, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x1c, 0x0a, 0x18, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x52, + 0x55, 0x50, 0x54, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x45, + 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x4b, 0x49, 0x4c, 0x4c, 0x10, 0x02, 0x2a, 0x55, 0x0a, 0x0f, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, + 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, + 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x52, + 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x4d, 0x4f, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x4e, + 0x54, 0x10, 0x01, 0x2a, 0x62, 0x0a, 0x13, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, + 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x4d, 0x4f, + 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, + 0x56, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x41, + 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x01, 0x32, 0xf0, 0x06, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x6e, + 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x0d, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, - 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, + 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, + 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, + 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x29, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, + 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x0c, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x2e, 0x72, + 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, + 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x58, 0x5a, 0x56, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x66, 0x75, 0x6c, - 0x2f, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x72, - 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x76, 0x32, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, + 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, + 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, + 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x0f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, + 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2d, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, + 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, + 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5e, 0x0a, 0x07, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x65, 0x12, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, + 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x75, + 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6f, 0x0a, 0x0e, 0x52, 0x65, 0x73, + 0x6f, 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x2c, 0x2e, 0x72, 0x75, + 0x6e, 0x6d, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x75, 0x6e, 0x6d, + 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x58, 0x5a, 0x56, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x66, 0x75, + 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, + 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x76, 0x32, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/api/gen/proto/ts/runme/runner/v1/runner_pb.d.ts b/pkg/api/gen/proto/ts/runme/runner/v1/runner_pb.d.ts index 3bcb0cecd..4cd602ff7 100644 --- a/pkg/api/gen/proto/ts/runme/runner/v1/runner_pb.d.ts +++ b/pkg/api/gen/proto/ts/runme/runner/v1/runner_pb.d.ts @@ -607,6 +607,10 @@ export interface MonitorEnvStoreResponseSnapshot_SnapshotEnv { * @generated from protobuf field: repeated runme.runner.v1.MonitorEnvStoreResponseSnapshot.Error errors = 9; */ errors: MonitorEnvStoreResponseSnapshot_Error[]; + /** + * @generated from protobuf field: bool is_required = 10; + */ + isRequired: boolean; } /** * @generated from protobuf message runme.runner.v1.MonitorEnvStoreResponseSnapshot.Error diff --git a/pkg/api/gen/proto/ts/runme/runner/v1/runner_pb.js b/pkg/api/gen/proto/ts/runme/runner/v1/runner_pb.js index 91375e5fa..690b68be8 100644 --- a/pkg/api/gen/proto/ts/runme/runner/v1/runner_pb.js +++ b/pkg/api/gen/proto/ts/runme/runner/v1/runner_pb.js @@ -489,7 +489,8 @@ class MonitorEnvStoreResponseSnapshot_SnapshotEnv$Type extends MessageType { { no: 6, name: "resolved_value", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 7, name: "create_time", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 8, name: "update_time", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 9, name: "errors", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => MonitorEnvStoreResponseSnapshot_Error } + { no: 9, name: "errors", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => MonitorEnvStoreResponseSnapshot_Error }, + { no: 10, name: "is_required", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } ]); } } diff --git a/pkg/api/gen/proto/ts/runme/runner/v2alpha1/runner_pb.d.ts b/pkg/api/gen/proto/ts/runme/runner/v2alpha1/runner_pb.d.ts index c54e1ad1d..35f7ebc2c 100644 --- a/pkg/api/gen/proto/ts/runme/runner/v2alpha1/runner_pb.d.ts +++ b/pkg/api/gen/proto/ts/runme/runner/v2alpha1/runner_pb.d.ts @@ -525,27 +525,31 @@ export interface MonitorEnvStoreResponseSnapshot_SnapshotEnv { */ spec: string; /** - * @generated from protobuf field: string origin = 4; + * @generated from protobuf field: bool is_required = 4; + */ + isRequired: boolean; + /** + * @generated from protobuf field: string origin = 5; */ origin: string; /** - * @generated from protobuf field: string original_value = 5; + * @generated from protobuf field: string original_value = 6; */ originalValue: string; /** - * @generated from protobuf field: string resolved_value = 6; + * @generated from protobuf field: string resolved_value = 7; */ resolvedValue: string; /** - * @generated from protobuf field: string create_time = 7; + * @generated from protobuf field: string create_time = 8; */ createTime: string; /** - * @generated from protobuf field: string update_time = 8; + * @generated from protobuf field: string update_time = 9; */ updateTime: string; /** - * @generated from protobuf field: repeated runme.runner.v2alpha1.MonitorEnvStoreResponseSnapshot.Error errors = 9; + * @generated from protobuf field: repeated runme.runner.v2alpha1.MonitorEnvStoreResponseSnapshot.Error errors = 10; */ errors: MonitorEnvStoreResponseSnapshot_Error[]; } diff --git a/pkg/api/gen/proto/ts/runme/runner/v2alpha1/runner_pb.js b/pkg/api/gen/proto/ts/runme/runner/v2alpha1/runner_pb.js index e6cad5683..d59a2f078 100644 --- a/pkg/api/gen/proto/ts/runme/runner/v2alpha1/runner_pb.js +++ b/pkg/api/gen/proto/ts/runme/runner/v2alpha1/runner_pb.js @@ -467,12 +467,13 @@ class MonitorEnvStoreResponseSnapshot_SnapshotEnv$Type extends MessageType { { no: 1, name: "status", kind: "enum", T: () => ["runme.runner.v2alpha1.MonitorEnvStoreResponseSnapshot.Status", MonitorEnvStoreResponseSnapshot_Status, "STATUS_"] }, { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 3, name: "spec", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 4, name: "origin", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 5, name: "original_value", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 6, name: "resolved_value", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 7, name: "create_time", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 8, name: "update_time", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 9, name: "errors", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => MonitorEnvStoreResponseSnapshot_Error } + { no: 4, name: "is_required", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 5, name: "origin", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 6, name: "original_value", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 7, name: "resolved_value", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 8, name: "create_time", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 9, name: "update_time", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 10, name: "errors", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => MonitorEnvStoreResponseSnapshot_Error } ]); } } diff --git a/pkg/api/proto/runme/runner/v1/runner.proto b/pkg/api/proto/runme/runner/v1/runner.proto index b6fee1141..55121607c 100644 --- a/pkg/api/proto/runme/runner/v1/runner.proto +++ b/pkg/api/proto/runme/runner/v1/runner.proto @@ -343,6 +343,8 @@ message MonitorEnvStoreResponseSnapshot { string update_time = 8; repeated Error errors = 9; + + bool is_required = 10; } message Error { diff --git a/pkg/api/proto/runme/runner/v2alpha1/runner.proto b/pkg/api/proto/runme/runner/v2alpha1/runner.proto index ab684244f..d05778205 100644 --- a/pkg/api/proto/runme/runner/v2alpha1/runner.proto +++ b/pkg/api/proto/runme/runner/v2alpha1/runner.proto @@ -290,17 +290,19 @@ message MonitorEnvStoreResponseSnapshot { string spec = 3; - string origin = 4; + bool is_required = 4; - string original_value = 5; + string origin = 5; - string resolved_value = 6; + string original_value = 6; - string create_time = 7; + string resolved_value = 7; - string update_time = 8; + string create_time = 8; - repeated Error errors = 9; + string update_time = 9; + + repeated Error errors = 10; } message Error {