From c7976307e7e47a2952cbfaea5cf2256bf8c30974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Wed, 14 Feb 2024 21:06:00 +0100 Subject: [PATCH 1/9] add config utilities for processors and connectors --- .golangci.yml | 1 + config/config.go | 145 ++++++++++ config/config_test.go | 346 +++++++++++++++++++++++ config/errors.go | 30 ++ config/parameter.go | 54 ++++ config/parameter_test.go | 50 ++++ config/validation.go | 140 ++++++++++ proto/buf.md | 2 +- proto/parameter/v1/parameter.pb.go | 429 +++++++++++++++++++++++++++++ proto/parameter/v1/parameter.proto | 57 ++++ 10 files changed, 1253 insertions(+), 1 deletion(-) create mode 100644 config/config.go create mode 100644 config/config_test.go create mode 100644 config/errors.go create mode 100644 config/parameter.go create mode 100644 config/parameter_test.go create mode 100644 config/validation.go create mode 100644 proto/parameter/v1/parameter.pb.go create mode 100644 proto/parameter/v1/parameter.proto diff --git a/.golangci.yml b/.golangci.yml index 0ba64cb..3261131 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -20,6 +20,7 @@ linters-settings: - .Errorf( - errors.New( - errors.Unwrap( + - errors.Join( - .Wrap( - .Wrapf( - .WithMessage( diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..f9f70f0 --- /dev/null +++ b/config/config.go @@ -0,0 +1,145 @@ +// Copyright © 2024 Meroxa, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package config provides types for specifying the expected configuration of a +// Conduit plugin (connector or processor). It also provides utilities to +// validate the configuration based on the specifications. +package config + +import ( + "errors" + "fmt" + "strconv" + "strings" + "time" +) + +// Config is a map of configuration values. The keys are the configuration +// parameter names and the values are the configuration parameter values. +type Config map[string]string + +// Sanitize removes leading and trailing spaces from all keys and values in the +// configuration. +func (c Config) Sanitize() Config { + for key, val := range c { + key = strings.TrimSpace(key) + val = strings.TrimSpace(val) + c[key] = val + } + return c +} + +// ApplyDefaults applies the default values defined in the parameter +// specifications to the configuration. If a parameter is not present in the +// configuration, the default value is applied. +func (c Config) ApplyDefaults(params Parameters) Config { + for key, param := range params { + if strings.TrimSpace(c[key]) == "" { + c[key] = param.Default + } + } + return c +} + +// Validate is a utility function that applies all the validations defined in +// the parameter specifications. It checks for unrecognized parameters, type +// validations, and value validations. It returns all encountered errors. +func (c Config) Validate(params Parameters) error { + errs := c.validateUnrecognizedParameters(params) + + for key := range params { + err := c.validateParamType(key, params[key]) + if err != nil { + // append error and continue with next parameter + errs = append(errs, err) + continue + } + err = c.validateParamValue(key, params[key]) + if err != nil { + errs = append(errs, err) + } + } + + return errors.Join(errs...) +} + +// validateUnrecognizedParameters validates that the config only contains +// parameters specified in the parameters. +func (c Config) validateUnrecognizedParameters(params Parameters) []error { + var errs []error + for key := range c { + if _, ok := params[key]; !ok { + errs = append(errs, fmt.Errorf("%q: %w", key, ErrUnrecognizedParameter)) + } + } + return errs +} + +// validateParamType validates that a parameter value is parsable to its assigned type. +func (c Config) validateParamType(key string, param Parameter) error { + value := c[key] + // empty value is valid for all types + if c[key] == "" { + return nil + } + + //nolint:exhaustive // type ParameterTypeFile and ParameterTypeString don't need type validations (both are strings or byte slices) + switch param.Type { + case ParameterTypeInt: + _, err := strconv.Atoi(value) + if err != nil { + return fmt.Errorf("error validating %q: %q value is not an integer: %w", key, value, ErrInvalidParamType) + } + case ParameterTypeFloat: + _, err := strconv.ParseFloat(value, 64) + if err != nil { + return fmt.Errorf("error validating %q: %q value is not a float: %w", key, value, ErrInvalidParamType) + } + case ParameterTypeDuration: + _, err := time.ParseDuration(value) + if err != nil { + return fmt.Errorf("error validating %q: %q value is not a duration: %w", key, value, ErrInvalidParamType) + } + case ParameterTypeBool: + _, err := strconv.ParseBool(value) + if err != nil { + return fmt.Errorf("error validating %q: %q value is not a boolean: %w", key, value, ErrInvalidParamType) + } + } + return nil +} + +// validateParamValue validates that a configuration value matches all the +// validations required for the parameter. +func (c Config) validateParamValue(key string, param Parameter) error { + value := c[key] + var errs []error + + isRequired := false + for _, v := range param.Validations { + if _, ok := v.(ValidationRequired); ok { + isRequired = true + } + err := v.Validate(value) + if err != nil { + errs = append(errs, fmt.Errorf("error validating %q: %w", key, err)) + continue + } + } + if value == "" && !isRequired { + return nil // empty optional parameter is valid + } + + return errors.Join(errs...) +} diff --git a/config/config_test.go b/config/config_test.go new file mode 100644 index 0000000..69d9edf --- /dev/null +++ b/config/config_test.go @@ -0,0 +1,346 @@ +// Copyright © 2024 Meroxa, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "errors" + "regexp" + "testing" + + "github.com/matryer/is" +) + +func TestConfig_Validate_ParameterType(t *testing.T) { + tests := []struct { + name string + config Config + params Parameters + wantErr bool + }{{ + name: "valid type number", + config: Config{"param1": "3"}, + params: Parameters{"param1": {Default: "3.3", Type: ParameterTypeFloat}}, + wantErr: false, + }, { + name: "invalid type float", + config: Config{"param1": "not-a-number"}, + params: Parameters{"param1": {Default: "3.3", Type: ParameterTypeFloat}}, + wantErr: true, + }, { + name: "valid default type float", + config: Config{"param1": ""}, + params: Parameters{"param1": {Default: "3", Type: ParameterTypeFloat}}, + wantErr: false, + }, { + name: "valid type int", + config: Config{"param1": "3"}, + params: Parameters{"param1": {Type: ParameterTypeInt}}, + wantErr: false, + }, { + name: "invalid type int", + config: Config{"param1": "3.3"}, + params: Parameters{"param1": {Type: ParameterTypeInt}}, + wantErr: true, + }, { + name: "valid type bool", + config: Config{"param1": "1"}, + params: Parameters{"param1": {Type: ParameterTypeBool}}, + wantErr: false, + }, { + name: "valid type bool", + config: Config{"param1": "true"}, + params: Parameters{"param1": {Type: ParameterTypeBool}}, + wantErr: false, + }, { + name: "invalid type bool", + config: Config{"param1": "not-a-bool"}, + params: Parameters{"param1": {Type: ParameterTypeBool}}, + wantErr: true, + }, { + name: "valid type duration", + config: Config{"param1": "1s"}, + params: Parameters{"param1": {Type: ParameterTypeDuration}}, + wantErr: false, + }, { + name: "empty value is valid for all types", + config: Config{"param1": ""}, + params: Parameters{"param1": {Type: ParameterTypeDuration}}, + wantErr: false, + }, { + name: "invalid type duration", + config: Config{"param1": "not-a-duration"}, + params: Parameters{"param1": {Type: ParameterTypeDuration}}, + wantErr: true, + }, { + name: "valid type string", + config: Config{"param1": "param"}, + params: Parameters{"param1": {Type: ParameterTypeString}}, + wantErr: false, + }, { + name: "valid type file", + config: Config{"param1": "some-data"}, + params: Parameters{"param1": {Type: ParameterTypeFile}}, + wantErr: false, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + is := is.New(t) + err := tt.config.Sanitize(). + ApplyDefaults(tt.params). + Validate(tt.params) + + if err != nil && tt.wantErr { + is.True(errors.Is(err, ErrInvalidParamType)) + } else if err != nil || tt.wantErr { + t.Errorf("UtilityFunc() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestConfig_Validate_Validations(t *testing.T) { + tests := []struct { + name string + config Config + params Parameters + wantErr bool + err error + }{{ + name: "required validation failed", + config: Config{"param1": ""}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + }}, + }, + wantErr: true, + err: ErrRequiredParameterMissing, + }, { + name: "required validation pass", + config: Config{"param1": "value"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + }}, + }, + wantErr: false, + }, { + name: "less than validation failed", + config: Config{"param1": "20"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationLessThan{10}, + }}, + }, + wantErr: true, + err: ErrLessThanValidationFail, + }, { + name: "less than validation pass", + config: Config{"param1": "0"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationLessThan{10}, + }}, + }, + wantErr: false, + }, { + name: "greater than validation failed", + config: Config{"param1": "0"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationGreaterThan{10}, + }}, + }, + wantErr: true, + err: ErrGreaterThanValidationFail, + }, { + name: "greater than validation failed", + config: Config{"param1": "20"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationGreaterThan{10}, + }}, + }, + wantErr: false, + }, { + name: "inclusion validation failed", + config: Config{"param1": "three"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationInclusion{[]string{"one", "two"}}, + }}, + }, + wantErr: true, + err: ErrInclusionValidationFail, + }, { + name: "inclusion validation pass", + config: Config{"param1": "two"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationInclusion{[]string{"one", "two"}}, + }}, + }, + wantErr: false, + }, { + name: "exclusion validation failed", + config: Config{"param1": "one"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationExclusion{[]string{"one", "two"}}, + }}, + }, + wantErr: true, + err: ErrExclusionValidationFail, + }, { + name: "exclusion validation pass", + config: Config{"param1": "three"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationExclusion{[]string{"one", "two"}}, + }}, + }, + wantErr: false, + }, { + name: "regex validation failed", + config: Config{"param1": "a-a"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationRegex{regexp.MustCompile("[a-z]-[1-9]")}, + }}, + }, + wantErr: true, + err: ErrRegexValidationFail, + }, { + name: "regex validation pass", + config: Config{"param1": "a-8"}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationRequired{}, + ValidationRegex{regexp.MustCompile("[a-z]-[1-9]")}, + }}, + }, + wantErr: false, + }, { + name: "optional validation pass", + config: Config{"param1": ""}, + params: Parameters{ + "param1": {Validations: []Validation{ + ValidationInclusion{[]string{"one", "two"}}, + ValidationExclusion{[]string{"three", "four"}}, + ValidationRegex{regexp.MustCompile("[a-z]")}, + ValidationGreaterThan{10}, + ValidationLessThan{20}, + }}, + }, + wantErr: false, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + is := is.New(t) + err := tt.config.Sanitize(). + ApplyDefaults(tt.params). + Validate(tt.params) + + if err != nil && tt.wantErr { + is.True(errors.Is(err, tt.err)) + } else if err != nil || tt.wantErr { + t.Errorf("UtilityFunc() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestConfig_Validate_MultiError(t *testing.T) { + is := is.New(t) + + params := map[string]Parameter{ + "limit": { + Type: ParameterTypeInt, + Validations: []Validation{ + ValidationGreaterThan{0}, + ValidationRegex{regexp.MustCompile("^[0-9]")}, + }, + }, + "option": { + Type: ParameterTypeString, + Validations: []Validation{ + ValidationInclusion{[]string{"one", "two", "three"}}, + ValidationExclusion{[]string{"one", "five"}}, + }, + }, + "name": { + Type: ParameterTypeString, + Validations: []Validation{ + ValidationRequired{}, + }, + }, + } + cfg := Config{ + "limit": "-1", + "option": "five", + } + + err := cfg.Sanitize(). + ApplyDefaults(params). + Validate(params) + is.True(err != nil) + + errs := unwrapErrors(err) + want := []error{ + ErrRequiredParameterMissing, + ErrInclusionValidationFail, + ErrExclusionValidationFail, + ErrGreaterThanValidationFail, + ErrRegexValidationFail, + } + +OUTER: + for _, gotErr := range errs { + for j, wantErr := range want { + if errors.Is(gotErr, wantErr) { + // remove error from want and continue asserting the rest + want = append(want[:j], want[j+1:]...) + continue OUTER + } + } + t.Fatalf("unexpected error: %v", gotErr) + } + if len(want) != 0 { + t.Fatalf("expected more errors: %v", want) + } +} + +// unwrapErrors recursively unwraps all errors combined using errors.Join. +func unwrapErrors(err error) []error { + errs, ok := err.(interface{ Unwrap() []error }) + if !ok { + return []error{err} + } + // unwrap recursively all sub-errors + var out []error + for _, err := range errs.Unwrap() { + out = append(out, unwrapErrors(err)...) + } + return out +} diff --git a/config/errors.go b/config/errors.go new file mode 100644 index 0000000..e2de977 --- /dev/null +++ b/config/errors.go @@ -0,0 +1,30 @@ +// Copyright © 2024 Meroxa, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import "errors" + +var ( + ErrUnrecognizedParameter = errors.New("unrecognized parameter") + ErrInvalidParamValue = errors.New("invalid parameter value") + ErrInvalidParamType = errors.New("invalid parameter type") + ErrRequiredParameterMissing = errors.New("required parameter is not provided") + + ErrLessThanValidationFail = errors.New("less-than validation failed") + ErrGreaterThanValidationFail = errors.New("greater-than validation failed") + ErrInclusionValidationFail = errors.New("inclusion validation failed") + ErrExclusionValidationFail = errors.New("exclusion validation failed") + ErrRegexValidationFail = errors.New("regex validation failed") +) diff --git a/config/parameter.go b/config/parameter.go new file mode 100644 index 0000000..31d6a32 --- /dev/null +++ b/config/parameter.go @@ -0,0 +1,54 @@ +// Copyright © 2024 Meroxa, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import parameterv1 "github.com/conduitio/conduit-commons/proto/parameter/v1" + +// Parameters is a map of all configuration parameters. +type Parameters map[string]Parameter + +// Parameter defines a single configuration parameter. +type Parameter struct { + // Description holds a description of the field and how to configure it. + Description string + // Default is the default value of the parameter, if any. + Default string + // Type defines the parameter data type. + Type ParameterType + // Validations list of validations to check for the parameter. + Validations []Validation +} + +type ParameterType int + +const ( + ParameterTypeString ParameterType = iota + 1 + ParameterTypeInt + ParameterTypeFloat + ParameterTypeBool + ParameterTypeFile + ParameterTypeDuration +) + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + var cTypes [1]struct{} + _ = cTypes[int(ParameterTypeString)-int(parameterv1.Parameter_TYPE_STRING)] + _ = cTypes[int(ParameterTypeInt)-int(parameterv1.Parameter_TYPE_INT)] + _ = cTypes[int(ParameterTypeFloat)-int(parameterv1.Parameter_TYPE_FLOAT)] + _ = cTypes[int(ParameterTypeBool)-int(parameterv1.Parameter_TYPE_BOOL)] + _ = cTypes[int(ParameterTypeFile)-int(parameterv1.Parameter_TYPE_FILE)] + _ = cTypes[int(ParameterTypeDuration)-int(parameterv1.Parameter_TYPE_DURATION)] +} diff --git a/config/parameter_test.go b/config/parameter_test.go new file mode 100644 index 0000000..8f248fd --- /dev/null +++ b/config/parameter_test.go @@ -0,0 +1,50 @@ +// Copyright © 2024 Meroxa, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +// func TestParameters_ToProto(t *testing.T) { +// is := is.New(t) +// validations := []Validation{ +// ValidationRequired{}, +// ValidationLessThan{5.10}, +// ValidationGreaterThan{0}, +// ValidationInclusion{[]string{"1", "2"}}, +// ValidationExclusion{[]string{"3", "4"}}, +// ValidationRegex{regexp.MustCompile("[a-z]*")}, +// } +// want := []parameterv1.Validation{ +// { +// Type: parameterv1.Validation_TYPE_REQUIRED, +// Value: "", +// }, { +// Type: parameterv1.Validation_TYPE_LESS_THAN, +// Value: "5.1", +// }, { +// Type: parameterv1.Validation_TYPE_GREATER_THAN, +// Value: "0", +// }, { +// Type: parameterv1.Validation_TYPE_INCLUSION, +// Value: "1,2", +// }, { +// Type: parameterv1.Validation_TYPE_EXCLUSION, +// Value: "3,4", +// }, { +// Type: parameterv1.Validation_TYPE_REGEX, +// Value: "[a-z]*", +// }, +// } +// got := convertValidations(validations) +// is.Equal(got, want) +// } diff --git a/config/validation.go b/config/validation.go new file mode 100644 index 0000000..87942a5 --- /dev/null +++ b/config/validation.go @@ -0,0 +1,140 @@ +// Copyright © 2024 Meroxa, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "fmt" + "regexp" + "slices" + "strconv" + "strings" + + parameterv1 "github.com/conduitio/conduit-commons/proto/parameter/v1" +) + +type Validation interface { + Type() ValidationType + Value() string + + Validate(string) error +} + +type ValidationType int64 + +const ( + ValidationTypeRequired ValidationType = iota + 1 + ValidationTypeGreaterThan + ValidationTypeLessThan + ValidationTypeInclusion + ValidationTypeExclusion + ValidationTypeRegex +) + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + var cTypes [1]struct{} + _ = cTypes[int(ValidationTypeRequired)-int(parameterv1.Validation_TYPE_REQUIRED)] + _ = cTypes[int(ValidationTypeGreaterThan)-int(parameterv1.Validation_TYPE_GREATER_THAN)] + _ = cTypes[int(ValidationTypeLessThan)-int(parameterv1.Validation_TYPE_LESS_THAN)] + _ = cTypes[int(ValidationTypeInclusion)-int(parameterv1.Validation_TYPE_INCLUSION)] + _ = cTypes[int(ValidationTypeExclusion)-int(parameterv1.Validation_TYPE_EXCLUSION)] + _ = cTypes[int(ValidationTypeRegex)-int(parameterv1.Validation_TYPE_REGEX)] +} + +type ValidationRequired struct{} + +func (v ValidationRequired) Type() ValidationType { return ValidationTypeRequired } +func (v ValidationRequired) Value() string { return "" } +func (v ValidationRequired) Validate(value string) error { + if value == "" { + return ErrRequiredParameterMissing + } + return nil +} + +type ValidationGreaterThan struct { + V float64 +} + +func (v ValidationGreaterThan) Type() ValidationType { return ValidationTypeGreaterThan } +func (v ValidationGreaterThan) Value() string { return strconv.FormatFloat(v.V, 'f', -1, 64) } +func (v ValidationGreaterThan) Validate(value string) error { + val, err := strconv.ParseFloat(value, 64) + if err != nil { + return fmt.Errorf("%q value should be a number: %w", value, ErrInvalidParamValue) + } + if !(val > v.V) { + formatted := strconv.FormatFloat(v.V, 'f', -1, 64) + return fmt.Errorf("%q should be greater than %s: %w", value, formatted, ErrGreaterThanValidationFail) + } + return nil +} + +type ValidationLessThan struct { + V float64 +} + +func (v ValidationLessThan) Type() ValidationType { return ValidationTypeLessThan } +func (v ValidationLessThan) Value() string { return strconv.FormatFloat(v.V, 'f', -1, 64) } +func (v ValidationLessThan) Validate(value string) error { + val, err := strconv.ParseFloat(value, 64) + if err != nil { + return fmt.Errorf("%q value should be a number: %w", value, ErrInvalidParamValue) + } + if !(val < v.V) { + formatted := strconv.FormatFloat(v.V, 'f', -1, 64) + return fmt.Errorf("%q should be less than %s: %w", value, formatted, ErrLessThanValidationFail) + } + return nil +} + +type ValidationInclusion struct { + List []string +} + +func (v ValidationInclusion) Type() ValidationType { return ValidationTypeInclusion } +func (v ValidationInclusion) Value() string { return strings.Join(v.List, ",") } +func (v ValidationInclusion) Validate(value string) error { + if !slices.Contains(v.List, value) { + return fmt.Errorf("%q value must be included in the list [%s]: %w", value, strings.Join(v.List, ","), ErrInclusionValidationFail) + } + return nil +} + +type ValidationExclusion struct { + List []string +} + +func (v ValidationExclusion) Type() ValidationType { return ValidationTypeExclusion } +func (v ValidationExclusion) Value() string { return strings.Join(v.List, ",") } +func (v ValidationExclusion) Validate(value string) error { + if slices.Contains(v.List, value) { + return fmt.Errorf("%q value must be excluded from the list [%s]: %w", value, strings.Join(v.List, ","), ErrExclusionValidationFail) + } + return nil +} + +type ValidationRegex struct { + Regex *regexp.Regexp +} + +func (v ValidationRegex) Type() ValidationType { return ValidationTypeRegex } +func (v ValidationRegex) Value() string { return v.Regex.String() } +func (v ValidationRegex) Validate(value string) error { + if !v.Regex.MatchString(value) { + return fmt.Errorf("%q should match the regex %q: %w", value, v.Regex.String(), ErrRegexValidationFail) + } + return nil +} diff --git a/proto/buf.md b/proto/buf.md index 0affdef..36fd6c0 100644 --- a/proto/buf.md +++ b/proto/buf.md @@ -1,5 +1,5 @@ # Conduit Commons This repository contains the proto definitions for common Conduit types, -specifically the OpenCDC record. For more info see the +specifically the OpenCDC record and plugin parameter. For more info see the [source repository](https://github.com/ConduitIO/conduit-commons). diff --git a/proto/parameter/v1/parameter.pb.go b/proto/parameter/v1/parameter.pb.go new file mode 100644 index 0000000..4cc345b --- /dev/null +++ b/proto/parameter/v1/parameter.pb.go @@ -0,0 +1,429 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: parameter/v1/parameter.proto + +package parameterv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Type shows the parameter type. +type Parameter_Type int32 + +const ( + Parameter_TYPE_UNSPECIFIED Parameter_Type = 0 + // Parameter is a string. + Parameter_TYPE_STRING Parameter_Type = 1 + // Parameter is an integer. + Parameter_TYPE_INT Parameter_Type = 2 + // Parameter is a float. + Parameter_TYPE_FLOAT Parameter_Type = 3 + // Parameter is a boolean. + Parameter_TYPE_BOOL Parameter_Type = 4 + // Parameter is a file. + Parameter_TYPE_FILE Parameter_Type = 5 + // Parameter is a duration. + Parameter_TYPE_DURATION Parameter_Type = 6 +) + +// Enum value maps for Parameter_Type. +var ( + Parameter_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "TYPE_STRING", + 2: "TYPE_INT", + 3: "TYPE_FLOAT", + 4: "TYPE_BOOL", + 5: "TYPE_FILE", + 6: "TYPE_DURATION", + } + Parameter_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "TYPE_STRING": 1, + "TYPE_INT": 2, + "TYPE_FLOAT": 3, + "TYPE_BOOL": 4, + "TYPE_FILE": 5, + "TYPE_DURATION": 6, + } +) + +func (x Parameter_Type) Enum() *Parameter_Type { + p := new(Parameter_Type) + *p = x + return p +} + +func (x Parameter_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Parameter_Type) Descriptor() protoreflect.EnumDescriptor { + return file_parameter_v1_parameter_proto_enumTypes[0].Descriptor() +} + +func (Parameter_Type) Type() protoreflect.EnumType { + return &file_parameter_v1_parameter_proto_enumTypes[0] +} + +func (x Parameter_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Parameter_Type.Descriptor instead. +func (Parameter_Type) EnumDescriptor() ([]byte, []int) { + return file_parameter_v1_parameter_proto_rawDescGZIP(), []int{0, 0} +} + +type Validation_Type int32 + +const ( + Validation_TYPE_UNSPECIFIED Validation_Type = 0 + // Parameter must be present. + Validation_TYPE_REQUIRED Validation_Type = 1 + // Parameter must be greater than {value}. + Validation_TYPE_GREATER_THAN Validation_Type = 2 + // Parameter must be less than {value}. + Validation_TYPE_LESS_THAN Validation_Type = 3 + // Parameter must be included in the comma separated list {value}. + Validation_TYPE_INCLUSION Validation_Type = 4 + // Parameter must not be included in the comma separated list {value}. + Validation_TYPE_EXCLUSION Validation_Type = 5 + // Parameter must match the regex {value}. + Validation_TYPE_REGEX Validation_Type = 6 +) + +// Enum value maps for Validation_Type. +var ( + Validation_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "TYPE_REQUIRED", + 2: "TYPE_GREATER_THAN", + 3: "TYPE_LESS_THAN", + 4: "TYPE_INCLUSION", + 5: "TYPE_EXCLUSION", + 6: "TYPE_REGEX", + } + Validation_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "TYPE_REQUIRED": 1, + "TYPE_GREATER_THAN": 2, + "TYPE_LESS_THAN": 3, + "TYPE_INCLUSION": 4, + "TYPE_EXCLUSION": 5, + "TYPE_REGEX": 6, + } +) + +func (x Validation_Type) Enum() *Validation_Type { + p := new(Validation_Type) + *p = x + return p +} + +func (x Validation_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Validation_Type) Descriptor() protoreflect.EnumDescriptor { + return file_parameter_v1_parameter_proto_enumTypes[1].Descriptor() +} + +func (Validation_Type) Type() protoreflect.EnumType { + return &file_parameter_v1_parameter_proto_enumTypes[1] +} + +func (x Validation_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Validation_Type.Descriptor instead. +func (Validation_Type) EnumDescriptor() ([]byte, []int) { + return file_parameter_v1_parameter_proto_rawDescGZIP(), []int{1, 0} +} + +// Parameter describes a single config parameter. +type Parameter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Default is the default value of the parameter. If there is no default + // value use an empty string. + Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty"` + // Description explains what the parameter does and how to configure it. + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // Type defines the parameter data type. + Type Parameter_Type `protobuf:"varint,3,opt,name=type,proto3,enum=parameter.v1.Parameter_Type" json:"type,omitempty"` + // Validations are validations to be made on the parameter. + Validations []*Validation `protobuf:"bytes,4,rep,name=validations,proto3" json:"validations,omitempty"` +} + +func (x *Parameter) Reset() { + *x = Parameter{} + if protoimpl.UnsafeEnabled { + mi := &file_parameter_v1_parameter_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Parameter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Parameter) ProtoMessage() {} + +func (x *Parameter) ProtoReflect() protoreflect.Message { + mi := &file_parameter_v1_parameter_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Parameter.ProtoReflect.Descriptor instead. +func (*Parameter) Descriptor() ([]byte, []int) { + return file_parameter_v1_parameter_proto_rawDescGZIP(), []int{0} +} + +func (x *Parameter) GetDefault() string { + if x != nil { + return x.Default + } + return "" +} + +func (x *Parameter) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Parameter) GetType() Parameter_Type { + if x != nil { + return x.Type + } + return Parameter_TYPE_UNSPECIFIED +} + +func (x *Parameter) GetValidations() []*Validation { + if x != nil { + return x.Validations + } + return nil +} + +// Validation to be made on the parameter. +type Validation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type Validation_Type `protobuf:"varint,1,opt,name=type,proto3,enum=parameter.v1.Validation_Type" json:"type,omitempty"` + // The value to be compared with the parameter, + // or a comma separated list in case of Validation.TYPE_INCLUSION or Validation.TYPE_EXCLUSION. + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Validation) Reset() { + *x = Validation{} + if protoimpl.UnsafeEnabled { + mi := &file_parameter_v1_parameter_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Validation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Validation) ProtoMessage() {} + +func (x *Validation) ProtoReflect() protoreflect.Message { + mi := &file_parameter_v1_parameter_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Validation.ProtoReflect.Descriptor instead. +func (*Validation) Descriptor() ([]byte, []int) { + return file_parameter_v1_parameter_proto_rawDescGZIP(), []int{1} +} + +func (x *Validation) GetType() Validation_Type { + if x != nil { + return x.Type + } + return Validation_TYPE_UNSPECIFIED +} + +func (x *Validation) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +var File_parameter_v1_parameter_proto protoreflect.FileDescriptor + +var file_parameter_v1_parameter_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x22, 0xb3, 0x02, 0x0a, + 0x09, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, + 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x10, + 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, + 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x04, + 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x05, 0x12, + 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x10, 0x06, 0x22, 0xea, 0x01, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x31, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1d, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x04, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x45, 0x41, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, 0x41, + 0x4e, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x45, 0x53, 0x53, + 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, + 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, 0x06, 0x42, + 0xb8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x69, 0x74, 0x69, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, + 0x64, 0x75, 0x69, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x58, + 0x58, 0xaa, 0x02, 0x0c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x31, + 0xca, 0x02, 0x0c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, + 0x02, 0x18, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_parameter_v1_parameter_proto_rawDescOnce sync.Once + file_parameter_v1_parameter_proto_rawDescData = file_parameter_v1_parameter_proto_rawDesc +) + +func file_parameter_v1_parameter_proto_rawDescGZIP() []byte { + file_parameter_v1_parameter_proto_rawDescOnce.Do(func() { + file_parameter_v1_parameter_proto_rawDescData = protoimpl.X.CompressGZIP(file_parameter_v1_parameter_proto_rawDescData) + }) + return file_parameter_v1_parameter_proto_rawDescData +} + +var file_parameter_v1_parameter_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_parameter_v1_parameter_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_parameter_v1_parameter_proto_goTypes = []interface{}{ + (Parameter_Type)(0), // 0: parameter.v1.Parameter.Type + (Validation_Type)(0), // 1: parameter.v1.Validation.Type + (*Parameter)(nil), // 2: parameter.v1.Parameter + (*Validation)(nil), // 3: parameter.v1.Validation +} +var file_parameter_v1_parameter_proto_depIdxs = []int32{ + 0, // 0: parameter.v1.Parameter.type:type_name -> parameter.v1.Parameter.Type + 3, // 1: parameter.v1.Parameter.validations:type_name -> parameter.v1.Validation + 1, // 2: parameter.v1.Validation.type:type_name -> parameter.v1.Validation.Type + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_parameter_v1_parameter_proto_init() } +func file_parameter_v1_parameter_proto_init() { + if File_parameter_v1_parameter_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_parameter_v1_parameter_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Parameter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_parameter_v1_parameter_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Validation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_parameter_v1_parameter_proto_rawDesc, + NumEnums: 2, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_parameter_v1_parameter_proto_goTypes, + DependencyIndexes: file_parameter_v1_parameter_proto_depIdxs, + EnumInfos: file_parameter_v1_parameter_proto_enumTypes, + MessageInfos: file_parameter_v1_parameter_proto_msgTypes, + }.Build() + File_parameter_v1_parameter_proto = out.File + file_parameter_v1_parameter_proto_rawDesc = nil + file_parameter_v1_parameter_proto_goTypes = nil + file_parameter_v1_parameter_proto_depIdxs = nil +} diff --git a/proto/parameter/v1/parameter.proto b/proto/parameter/v1/parameter.proto new file mode 100644 index 0000000..44fed72 --- /dev/null +++ b/proto/parameter/v1/parameter.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; + +package parameter.v1; + +// Parameter describes a single config parameter. +message Parameter { + // Type shows the parameter type. + enum Type { + TYPE_UNSPECIFIED = 0; + // Parameter is a string. + TYPE_STRING = 1; + // Parameter is an integer. + TYPE_INT = 2; + // Parameter is a float. + TYPE_FLOAT = 3; + // Parameter is a boolean. + TYPE_BOOL = 4; + // Parameter is a file. + TYPE_FILE = 5; + // Parameter is a duration. + TYPE_DURATION = 6; + } + + // Default is the default value of the parameter. If there is no default + // value use an empty string. + string default = 1; + // Description explains what the parameter does and how to configure it. + string description = 2; + // Type defines the parameter data type. + Type type = 3; + // Validations are validations to be made on the parameter. + repeated Validation validations = 4; +} + +// Validation to be made on the parameter. +message Validation { + enum Type { + TYPE_UNSPECIFIED = 0; + // Parameter must be present. + TYPE_REQUIRED = 1; + // Parameter must be greater than {value}. + TYPE_GREATER_THAN = 2; + // Parameter must be less than {value}. + TYPE_LESS_THAN = 3; + // Parameter must be included in the comma separated list {value}. + TYPE_INCLUSION = 4; + // Parameter must not be included in the comma separated list {value}. + TYPE_EXCLUSION = 5; + // Parameter must match the regex {value}. + TYPE_REGEX = 6; + } + + Type type = 1; + // The value to be compared with the parameter, + // or a comma separated list in case of Validation.TYPE_INCLUSION or Validation.TYPE_EXCLUSION. + string value = 2; +} \ No newline at end of file From e2f0c779c89747cbb6edc0efebb8ae1c465344c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Thu, 15 Feb 2024 14:12:46 +0100 Subject: [PATCH 2/9] add proto functions to parameter --- config/parameter.go | 13 ---- config/proto.go | 180 +++++++++++++++++++++++++++++++++++++++++++ config/validation.go | 13 ---- 3 files changed, 180 insertions(+), 26 deletions(-) create mode 100644 config/proto.go diff --git a/config/parameter.go b/config/parameter.go index 31d6a32..ef80589 100644 --- a/config/parameter.go +++ b/config/parameter.go @@ -14,8 +14,6 @@ package config -import parameterv1 "github.com/conduitio/conduit-commons/proto/parameter/v1" - // Parameters is a map of all configuration parameters. type Parameters map[string]Parameter @@ -41,14 +39,3 @@ const ( ParameterTypeFile ParameterTypeDuration ) - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - var cTypes [1]struct{} - _ = cTypes[int(ParameterTypeString)-int(parameterv1.Parameter_TYPE_STRING)] - _ = cTypes[int(ParameterTypeInt)-int(parameterv1.Parameter_TYPE_INT)] - _ = cTypes[int(ParameterTypeFloat)-int(parameterv1.Parameter_TYPE_FLOAT)] - _ = cTypes[int(ParameterTypeBool)-int(parameterv1.Parameter_TYPE_BOOL)] - _ = cTypes[int(ParameterTypeFile)-int(parameterv1.Parameter_TYPE_FILE)] - _ = cTypes[int(ParameterTypeDuration)-int(parameterv1.Parameter_TYPE_DURATION)] -} diff --git a/config/proto.go b/config/proto.go new file mode 100644 index 0000000..6c4f79e --- /dev/null +++ b/config/proto.go @@ -0,0 +1,180 @@ +// Copyright © 2024 Meroxa, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "fmt" + "regexp" + "strconv" + "strings" + + parameterv1 "github.com/conduitio/conduit-commons/proto/parameter/v1" +) + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + var cTypes [1]struct{} + _ = cTypes[int(ParameterTypeString)-int(parameterv1.Parameter_TYPE_STRING)] + _ = cTypes[int(ParameterTypeInt)-int(parameterv1.Parameter_TYPE_INT)] + _ = cTypes[int(ParameterTypeFloat)-int(parameterv1.Parameter_TYPE_FLOAT)] + _ = cTypes[int(ParameterTypeBool)-int(parameterv1.Parameter_TYPE_BOOL)] + _ = cTypes[int(ParameterTypeFile)-int(parameterv1.Parameter_TYPE_FILE)] + _ = cTypes[int(ParameterTypeDuration)-int(parameterv1.Parameter_TYPE_DURATION)] +} + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + var cTypes [1]struct{} + _ = cTypes[int(ValidationTypeRequired)-int(parameterv1.Validation_TYPE_REQUIRED)] + _ = cTypes[int(ValidationTypeGreaterThan)-int(parameterv1.Validation_TYPE_GREATER_THAN)] + _ = cTypes[int(ValidationTypeLessThan)-int(parameterv1.Validation_TYPE_LESS_THAN)] + _ = cTypes[int(ValidationTypeInclusion)-int(parameterv1.Validation_TYPE_INCLUSION)] + _ = cTypes[int(ValidationTypeExclusion)-int(parameterv1.Validation_TYPE_EXCLUSION)] + _ = cTypes[int(ValidationTypeRegex)-int(parameterv1.Validation_TYPE_REGEX)] +} + +// -- From Proto To Parameter -------------------------------------------------- + +// FromProto takes data from the supplied proto object and populates the +// receiver. If the proto object is nil, the receiver is set to its zero value. +// If the function returns an error, the receiver could be partially populated. +func (p *Parameters) FromProto(proto map[string]*parameterv1.Parameter) error { + if proto == nil { + *p = nil + return nil + } + + clear(*p) + for k, v := range proto { + var param Parameter + err := param.FromProto(v) + if err != nil { + return fmt.Errorf("error converting parameter: %w", err) + } + (*p)[k] = param + } + return nil +} + +// FromProto takes data from the supplied proto object and populates the +// receiver. If the proto object is nil, the receiver is set to its zero value. +// If the function returns an error, the receiver could be partially populated. +func (p *Parameter) FromProto(proto *parameterv1.Parameter) error { + if proto == nil { + *p = Parameter{} + return nil + } + + var err error + p.Validations, err = validationsFromProto(proto.Validations) + if err != nil { + return err + } + + p.Description = proto.Description + p.Default = proto.Default + p.Type = ParameterType(proto.Type) + return nil +} + +func validationsFromProto(proto []*parameterv1.Validation) ([]Validation, error) { + if proto == nil { + return nil, nil + } + + validations := make([]Validation, len(proto)) + for i, v := range proto { + var err error + validations[i], err = validationFromProto(v) + if err != nil { + return nil, fmt.Errorf("error converting validation: %w", err) + } + } + return validations, nil +} + +func validationFromProto(proto *parameterv1.Validation) (Validation, error) { + if proto == nil { + return nil, nil + } + + switch proto.Type { + case parameterv1.Validation_TYPE_REQUIRED: + return ValidationRequired{}, nil + case parameterv1.Validation_TYPE_GREATER_THAN: + v, err := strconv.ParseFloat(proto.Value, 64) + if err != nil { + return nil, fmt.Errorf("error parsing greater than value: %w", err) + } + return ValidationGreaterThan{V: v}, nil + case parameterv1.Validation_TYPE_LESS_THAN: + v, err := strconv.ParseFloat(proto.Value, 64) + if err != nil { + return nil, fmt.Errorf("error parsing less than value: %w", err) + } + return ValidationLessThan{V: v}, nil + case parameterv1.Validation_TYPE_INCLUSION: + return ValidationInclusion{List: strings.Split(proto.Value, ",")}, nil + case parameterv1.Validation_TYPE_EXCLUSION: + return ValidationExclusion{List: strings.Split(proto.Value, ",")}, nil + case parameterv1.Validation_TYPE_REGEX: + regex, err := regexp.Compile(proto.Value) + if err != nil { + return nil, fmt.Errorf("error compiling regex: %w", err) + } + return ValidationRegex{Regex: regex}, nil + default: + return nil, fmt.Errorf("unknown validation type: %v", proto.Type) + } +} + +// -- From Parameter To Proto -------------------------------------------------- + +// ToProto takes data from the receiver and populates the supplied proto object. +func (p Parameters) ToProto(proto map[string]*parameterv1.Parameter) { + clear(proto) + for k, param := range p { + var v parameterv1.Parameter + param.ToProto(&v) + proto[k] = &v + } +} + +// ToProto takes data from the receiver and populates the supplied proto object. +func (p Parameter) ToProto(proto *parameterv1.Parameter) { + proto.Description = p.Description + proto.Default = p.Default + proto.Type = parameterv1.Parameter_Type(p.Type) + proto.Validations = validationsToProto(p.Validations) +} + +func validationsToProto(validations []Validation) []*parameterv1.Validation { + if validations == nil { + return nil + } + + proto := make([]*parameterv1.Validation, len(validations)) + for i, v := range validations { + proto[i] = validationToProto(v) + } + return proto +} + +func validationToProto(validation Validation) *parameterv1.Validation { + return ¶meterv1.Validation{ + Type: parameterv1.Validation_Type(validation.Type()), + Value: validation.Value(), + } +} diff --git a/config/validation.go b/config/validation.go index 87942a5..b5b7ac2 100644 --- a/config/validation.go +++ b/config/validation.go @@ -20,8 +20,6 @@ import ( "slices" "strconv" "strings" - - parameterv1 "github.com/conduitio/conduit-commons/proto/parameter/v1" ) type Validation interface { @@ -42,17 +40,6 @@ const ( ValidationTypeRegex ) -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - var cTypes [1]struct{} - _ = cTypes[int(ValidationTypeRequired)-int(parameterv1.Validation_TYPE_REQUIRED)] - _ = cTypes[int(ValidationTypeGreaterThan)-int(parameterv1.Validation_TYPE_GREATER_THAN)] - _ = cTypes[int(ValidationTypeLessThan)-int(parameterv1.Validation_TYPE_LESS_THAN)] - _ = cTypes[int(ValidationTypeInclusion)-int(parameterv1.Validation_TYPE_INCLUSION)] - _ = cTypes[int(ValidationTypeExclusion)-int(parameterv1.Validation_TYPE_EXCLUSION)] - _ = cTypes[int(ValidationTypeRegex)-int(parameterv1.Validation_TYPE_REGEX)] -} - type ValidationRequired struct{} func (v ValidationRequired) Type() ValidationType { return ValidationTypeRequired } From 9288f51b4183cd03e420c66f8989f9c654015b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Thu, 15 Feb 2024 14:44:39 +0100 Subject: [PATCH 3/9] add proto tests --- config/parameter.go | 18 +-- config/parameter_test.go | 50 -------- config/parametertype_string.go | 29 +++++ config/proto.go | 4 +- config/proto_test.go | 202 ++++++++++++++++++++++++++++++++ config/validation.go | 14 ++- config/validationtype_string.go | 29 +++++ 7 files changed, 280 insertions(+), 66 deletions(-) delete mode 100644 config/parameter_test.go create mode 100644 config/parametertype_string.go create mode 100644 config/proto_test.go create mode 100644 config/validationtype_string.go diff --git a/config/parameter.go b/config/parameter.go index ef80589..4931535 100644 --- a/config/parameter.go +++ b/config/parameter.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:generate stringer -type=ParameterType -linecomment + package config // Parameters is a map of all configuration parameters. @@ -19,10 +21,10 @@ type Parameters map[string]Parameter // Parameter defines a single configuration parameter. type Parameter struct { - // Description holds a description of the field and how to configure it. - Description string // Default is the default value of the parameter, if any. Default string + // Description holds a description of the field and how to configure it. + Description string // Type defines the parameter data type. Type ParameterType // Validations list of validations to check for the parameter. @@ -32,10 +34,10 @@ type Parameter struct { type ParameterType int const ( - ParameterTypeString ParameterType = iota + 1 - ParameterTypeInt - ParameterTypeFloat - ParameterTypeBool - ParameterTypeFile - ParameterTypeDuration + ParameterTypeString ParameterType = iota + 1 // string + ParameterTypeInt // int + ParameterTypeFloat // float + ParameterTypeBool // bool + ParameterTypeFile // file + ParameterTypeDuration // duration ) diff --git a/config/parameter_test.go b/config/parameter_test.go deleted file mode 100644 index 8f248fd..0000000 --- a/config/parameter_test.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright © 2024 Meroxa, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package config - -// func TestParameters_ToProto(t *testing.T) { -// is := is.New(t) -// validations := []Validation{ -// ValidationRequired{}, -// ValidationLessThan{5.10}, -// ValidationGreaterThan{0}, -// ValidationInclusion{[]string{"1", "2"}}, -// ValidationExclusion{[]string{"3", "4"}}, -// ValidationRegex{regexp.MustCompile("[a-z]*")}, -// } -// want := []parameterv1.Validation{ -// { -// Type: parameterv1.Validation_TYPE_REQUIRED, -// Value: "", -// }, { -// Type: parameterv1.Validation_TYPE_LESS_THAN, -// Value: "5.1", -// }, { -// Type: parameterv1.Validation_TYPE_GREATER_THAN, -// Value: "0", -// }, { -// Type: parameterv1.Validation_TYPE_INCLUSION, -// Value: "1,2", -// }, { -// Type: parameterv1.Validation_TYPE_EXCLUSION, -// Value: "3,4", -// }, { -// Type: parameterv1.Validation_TYPE_REGEX, -// Value: "[a-z]*", -// }, -// } -// got := convertValidations(validations) -// is.Equal(got, want) -// } diff --git a/config/parametertype_string.go b/config/parametertype_string.go new file mode 100644 index 0000000..1b8249a --- /dev/null +++ b/config/parametertype_string.go @@ -0,0 +1,29 @@ +// Code generated by "stringer -type=ParameterType -linecomment"; DO NOT EDIT. + +package config + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ParameterTypeString-1] + _ = x[ParameterTypeInt-2] + _ = x[ParameterTypeFloat-3] + _ = x[ParameterTypeBool-4] + _ = x[ParameterTypeFile-5] + _ = x[ParameterTypeDuration-6] +} + +const _ParameterType_name = "stringintfloatboolfileduration" + +var _ParameterType_index = [...]uint8{0, 6, 9, 14, 18, 22, 30} + +func (i ParameterType) String() string { + i -= 1 + if i < 0 || i >= ParameterType(len(_ParameterType_index)-1) { + return "ParameterType(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _ParameterType_name[_ParameterType_index[i]:_ParameterType_index[i+1]] +} diff --git a/config/proto.go b/config/proto.go index 6c4f79e..ea471ae 100644 --- a/config/proto.go +++ b/config/proto.go @@ -83,8 +83,8 @@ func (p *Parameter) FromProto(proto *parameterv1.Parameter) error { return err } - p.Description = proto.Description p.Default = proto.Default + p.Description = proto.Description p.Type = ParameterType(proto.Type) return nil } @@ -154,8 +154,8 @@ func (p Parameters) ToProto(proto map[string]*parameterv1.Parameter) { // ToProto takes data from the receiver and populates the supplied proto object. func (p Parameter) ToProto(proto *parameterv1.Parameter) { - proto.Description = p.Description proto.Default = p.Default + proto.Description = p.Description proto.Type = parameterv1.Parameter_Type(p.Type) proto.Validations = validationsToProto(p.Validations) } diff --git a/config/proto_test.go b/config/proto_test.go new file mode 100644 index 0000000..910a363 --- /dev/null +++ b/config/proto_test.go @@ -0,0 +1,202 @@ +// Copyright © 2024 Meroxa, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "regexp" + "testing" + + parameterv1 "github.com/conduitio/conduit-commons/proto/parameter/v1" + "github.com/matryer/is" +) + +func TestParameter_FromProto(t *testing.T) { + is := is.New(t) + + have := ¶meterv1.Parameter{ + Description: "test-description", + Default: "test-default", + Type: parameterv1.Parameter_TYPE_STRING, + Validations: []*parameterv1.Validation{ + {Type: parameterv1.Validation_TYPE_REQUIRED}, + {Type: parameterv1.Validation_TYPE_GREATER_THAN, Value: "1.2"}, + {Type: parameterv1.Validation_TYPE_LESS_THAN, Value: "3.4"}, + {Type: parameterv1.Validation_TYPE_INCLUSION, Value: "1,2,3"}, + {Type: parameterv1.Validation_TYPE_EXCLUSION, Value: "4,5,6"}, + {Type: parameterv1.Validation_TYPE_REGEX, Value: "test-regex"}, + }, + } + + want := Parameter{ + Description: "test-description", + Default: "test-default", + Type: ParameterTypeString, + Validations: []Validation{ + ValidationRequired{}, + ValidationGreaterThan{V: 1.2}, + ValidationLessThan{V: 3.4}, + ValidationInclusion{List: []string{"1", "2", "3"}}, + ValidationExclusion{List: []string{"4", "5", "6"}}, + ValidationRegex{Regex: regexp.MustCompile("test-regex")}, + }, + } + + var got Parameter + err := got.FromProto(have) + is.NoErr(err) + is.Equal(want, got) +} + +func TestParameter_ToProto(t *testing.T) { + is := is.New(t) + + have := Parameter{ + Description: "test-description", + Default: "test-default", + Type: ParameterTypeString, + Validations: []Validation{ + ValidationRequired{}, + ValidationRegex{Regex: regexp.MustCompile("test-regex")}, + }, + } + + want := ¶meterv1.Parameter{ + Description: "test-description", + Default: "test-default", + Type: parameterv1.Parameter_TYPE_STRING, + Validations: []*parameterv1.Validation{ + {Type: parameterv1.Validation_TYPE_REQUIRED}, + {Type: parameterv1.Validation_TYPE_REGEX, Value: "test-regex"}, + }, + } + + got := ¶meterv1.Parameter{} + have.ToProto(got) + is.Equal(want, got) +} + +func TestParameter_ParameterTypes(t *testing.T) { + is := is.New(t) + + testCases := []struct { + protoType parameterv1.Parameter_Type + goType ParameterType + }{ + {protoType: parameterv1.Parameter_TYPE_UNSPECIFIED, goType: 0}, + {protoType: parameterv1.Parameter_TYPE_STRING, goType: ParameterTypeString}, + {protoType: parameterv1.Parameter_TYPE_INT, goType: ParameterTypeInt}, + {protoType: parameterv1.Parameter_TYPE_FLOAT, goType: ParameterTypeFloat}, + {protoType: parameterv1.Parameter_TYPE_BOOL, goType: ParameterTypeBool}, + {protoType: parameterv1.Parameter_TYPE_FILE, goType: ParameterTypeFile}, + {protoType: parameterv1.Parameter_TYPE_DURATION, goType: ParameterTypeDuration}, + {protoType: parameterv1.Parameter_Type(100), goType: 100}, + } + + t.Run("FromProto", func(t *testing.T) { + for _, tc := range testCases { + t.Run(tc.goType.String(), func(t *testing.T) { + have := ¶meterv1.Parameter{Type: tc.protoType} + want := Parameter{Type: tc.goType} + + var got Parameter + err := got.FromProto(have) + is.NoErr(err) + is.Equal(want, got) + }) + } + }) + + t.Run("ToProto", func(t *testing.T) { + for _, tc := range testCases { + t.Run(tc.goType.String(), func(t *testing.T) { + have := Parameter{Type: tc.goType} + want := ¶meterv1.Parameter{Type: tc.protoType} + + got := ¶meterv1.Parameter{} + have.ToProto(got) + is.Equal(want, got) + }) + } + }) +} + +func TestParameter_Validation(t *testing.T) { + is := is.New(t) + + testCases := []struct { + protoType *parameterv1.Validation + goType Validation + }{ + { + protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_REQUIRED}, + goType: ValidationRequired{}, + }, + { + protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_GREATER_THAN, Value: "1.2"}, + goType: ValidationGreaterThan{V: 1.2}, + }, + { + protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_LESS_THAN, Value: "3.4"}, + goType: ValidationLessThan{V: 3.4}, + }, + { + protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_INCLUSION, Value: "1,2,3"}, + goType: ValidationInclusion{List: []string{"1", "2", "3"}}, + }, + { + protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_EXCLUSION, Value: "4,5,6"}, + goType: ValidationExclusion{List: []string{"4", "5", "6"}}, + }, + { + protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_REGEX, Value: "test-regex"}, + goType: ValidationRegex{Regex: regexp.MustCompile("test-regex")}, + }, + } + + t.Run("FromProto", func(t *testing.T) { + for _, tc := range testCases { + t.Run(tc.goType.Type().String(), func(t *testing.T) { + have := ¶meterv1.Parameter{ + Validations: []*parameterv1.Validation{tc.protoType}, + } + want := Parameter{ + Validations: []Validation{tc.goType}, + } + + var got Parameter + err := got.FromProto(have) + is.NoErr(err) + is.Equal(want, got) + }) + } + }) + + t.Run("ToProto", func(t *testing.T) { + for _, tc := range testCases { + t.Run(tc.goType.Type().String(), func(t *testing.T) { + have := Parameter{ + Validations: []Validation{tc.goType}, + } + want := ¶meterv1.Parameter{ + Validations: []*parameterv1.Validation{tc.protoType}, + } + + got := ¶meterv1.Parameter{} + have.ToProto(got) + is.Equal(want, got) + }) + } + }) +} diff --git a/config/validation.go b/config/validation.go index b5b7ac2..7df011a 100644 --- a/config/validation.go +++ b/config/validation.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:generate stringer -type=ValidationType -linecomment + package config import ( @@ -32,12 +34,12 @@ type Validation interface { type ValidationType int64 const ( - ValidationTypeRequired ValidationType = iota + 1 - ValidationTypeGreaterThan - ValidationTypeLessThan - ValidationTypeInclusion - ValidationTypeExclusion - ValidationTypeRegex + ValidationTypeRequired ValidationType = iota + 1 // required + ValidationTypeGreaterThan // greater-than + ValidationTypeLessThan // less-than + ValidationTypeInclusion // inclusion + ValidationTypeExclusion // exclusion + ValidationTypeRegex // regex ) type ValidationRequired struct{} diff --git a/config/validationtype_string.go b/config/validationtype_string.go new file mode 100644 index 0000000..e15a33c --- /dev/null +++ b/config/validationtype_string.go @@ -0,0 +1,29 @@ +// Code generated by "stringer -type=ValidationType -linecomment"; DO NOT EDIT. + +package config + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ValidationTypeRequired-1] + _ = x[ValidationTypeGreaterThan-2] + _ = x[ValidationTypeLessThan-3] + _ = x[ValidationTypeInclusion-4] + _ = x[ValidationTypeExclusion-5] + _ = x[ValidationTypeRegex-6] +} + +const _ValidationType_name = "requiredgreater-thanless-thaninclusionexclusionregex" + +var _ValidationType_index = [...]uint8{0, 8, 20, 29, 38, 47, 52} + +func (i ValidationType) String() string { + i -= 1 + if i < 0 || i >= ValidationType(len(_ValidationType_index)-1) { + return "ValidationType(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _ValidationType_name[_ValidationType_index[i]:_ValidationType_index[i+1]] +} From 4b5e5620100326ac2650702dc2bacebcb3a6d5d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Thu, 15 Feb 2024 14:57:29 +0100 Subject: [PATCH 4/9] fix linter errors --- config/config.go | 8 ++++---- config/config_test.go | 2 +- config/errors.go | 5 +++-- config/proto.go | 6 ++++-- config/proto_test.go | 23 ++++++++++++++++++----- config/validation.go | 4 ++-- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/config/config.go b/config/config.go index f9f70f0..b0cd4c1 100644 --- a/config/config.go +++ b/config/config.go @@ -99,22 +99,22 @@ func (c Config) validateParamType(key string, param Parameter) error { case ParameterTypeInt: _, err := strconv.Atoi(value) if err != nil { - return fmt.Errorf("error validating %q: %q value is not an integer: %w", key, value, ErrInvalidParamType) + return fmt.Errorf("error validating %q: %q value is not an integer: %w", key, value, ErrInvalidParameterType) } case ParameterTypeFloat: _, err := strconv.ParseFloat(value, 64) if err != nil { - return fmt.Errorf("error validating %q: %q value is not a float: %w", key, value, ErrInvalidParamType) + return fmt.Errorf("error validating %q: %q value is not a float: %w", key, value, ErrInvalidParameterType) } case ParameterTypeDuration: _, err := time.ParseDuration(value) if err != nil { - return fmt.Errorf("error validating %q: %q value is not a duration: %w", key, value, ErrInvalidParamType) + return fmt.Errorf("error validating %q: %q value is not a duration: %w", key, value, ErrInvalidParameterType) } case ParameterTypeBool: _, err := strconv.ParseBool(value) if err != nil { - return fmt.Errorf("error validating %q: %q value is not a boolean: %w", key, value, ErrInvalidParamType) + return fmt.Errorf("error validating %q: %q value is not a boolean: %w", key, value, ErrInvalidParameterType) } } return nil diff --git a/config/config_test.go b/config/config_test.go index 69d9edf..b4d9ad0 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -102,7 +102,7 @@ func TestConfig_Validate_ParameterType(t *testing.T) { Validate(tt.params) if err != nil && tt.wantErr { - is.True(errors.Is(err, ErrInvalidParamType)) + is.True(errors.Is(err, ErrInvalidParameterType)) } else if err != nil || tt.wantErr { t.Errorf("UtilityFunc() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/config/errors.go b/config/errors.go index e2de977..edd2a9f 100644 --- a/config/errors.go +++ b/config/errors.go @@ -18,8 +18,9 @@ import "errors" var ( ErrUnrecognizedParameter = errors.New("unrecognized parameter") - ErrInvalidParamValue = errors.New("invalid parameter value") - ErrInvalidParamType = errors.New("invalid parameter type") + ErrInvalidParameterValue = errors.New("invalid parameter value") + ErrInvalidParameterType = errors.New("invalid parameter type") + ErrInvalidValidationType = errors.New("invalid validation type") ErrRequiredParameterMissing = errors.New("required parameter is not provided") ErrLessThanValidationFail = errors.New("less-than validation failed") diff --git a/config/proto.go b/config/proto.go index ea471ae..e0c94e8 100644 --- a/config/proto.go +++ b/config/proto.go @@ -107,7 +107,7 @@ func validationsFromProto(proto []*parameterv1.Validation) ([]Validation, error) func validationFromProto(proto *parameterv1.Validation) (Validation, error) { if proto == nil { - return nil, nil + return nil, nil //nolint:nilnil // This is the expected behavior. } switch proto.Type { @@ -135,8 +135,10 @@ func validationFromProto(proto *parameterv1.Validation) (Validation, error) { return nil, fmt.Errorf("error compiling regex: %w", err) } return ValidationRegex{Regex: regex}, nil + case parameterv1.Validation_TYPE_UNSPECIFIED: + fallthrough default: - return nil, fmt.Errorf("unknown validation type: %v", proto.Type) + return nil, fmt.Errorf("%v: %w", proto.Type, ErrInvalidValidationType) } } diff --git a/config/proto_test.go b/config/proto_test.go index 910a363..112a3a0 100644 --- a/config/proto_test.go +++ b/config/proto_test.go @@ -15,6 +15,7 @@ package config import ( + "errors" "regexp" "testing" @@ -88,8 +89,6 @@ func TestParameter_ToProto(t *testing.T) { } func TestParameter_ParameterTypes(t *testing.T) { - is := is.New(t) - testCases := []struct { protoType parameterv1.Parameter_Type goType ParameterType @@ -106,7 +105,8 @@ func TestParameter_ParameterTypes(t *testing.T) { t.Run("FromProto", func(t *testing.T) { for _, tc := range testCases { - t.Run(tc.goType.String(), func(t *testing.T) { + t.Run(tc.goType.String(), func(*testing.T) { + is := is.New(t) have := ¶meterv1.Parameter{Type: tc.protoType} want := Parameter{Type: tc.goType} @@ -121,6 +121,7 @@ func TestParameter_ParameterTypes(t *testing.T) { t.Run("ToProto", func(t *testing.T) { for _, tc := range testCases { t.Run(tc.goType.String(), func(t *testing.T) { + is := is.New(t) have := Parameter{Type: tc.goType} want := ¶meterv1.Parameter{Type: tc.protoType} @@ -133,8 +134,6 @@ func TestParameter_ParameterTypes(t *testing.T) { } func TestParameter_Validation(t *testing.T) { - is := is.New(t) - testCases := []struct { protoType *parameterv1.Validation goType Validation @@ -168,6 +167,7 @@ func TestParameter_Validation(t *testing.T) { t.Run("FromProto", func(t *testing.T) { for _, tc := range testCases { t.Run(tc.goType.Type().String(), func(t *testing.T) { + is := is.New(t) have := ¶meterv1.Parameter{ Validations: []*parameterv1.Validation{tc.protoType}, } @@ -186,6 +186,7 @@ func TestParameter_Validation(t *testing.T) { t.Run("ToProto", func(t *testing.T) { for _, tc := range testCases { t.Run(tc.goType.Type().String(), func(t *testing.T) { + is := is.New(t) have := Parameter{ Validations: []Validation{tc.goType}, } @@ -200,3 +201,15 @@ func TestParameter_Validation(t *testing.T) { } }) } + +func TestParameter_Validation_InvalidType(t *testing.T) { + is := is.New(t) + have := ¶meterv1.Parameter{ + Validations: []*parameterv1.Validation{ + {Type: parameterv1.Validation_TYPE_UNSPECIFIED}, + }, + } + var got Parameter + err := got.FromProto(have) + is.True(errors.Is(err, ErrInvalidValidationType)) +} diff --git a/config/validation.go b/config/validation.go index 7df011a..1425022 100644 --- a/config/validation.go +++ b/config/validation.go @@ -62,7 +62,7 @@ func (v ValidationGreaterThan) Value() string { return strconv.FormatFloa func (v ValidationGreaterThan) Validate(value string) error { val, err := strconv.ParseFloat(value, 64) if err != nil { - return fmt.Errorf("%q value should be a number: %w", value, ErrInvalidParamValue) + return fmt.Errorf("%q value should be a number: %w", value, ErrInvalidParameterValue) } if !(val > v.V) { formatted := strconv.FormatFloat(v.V, 'f', -1, 64) @@ -80,7 +80,7 @@ func (v ValidationLessThan) Value() string { return strconv.FormatFloat(v func (v ValidationLessThan) Validate(value string) error { val, err := strconv.ParseFloat(value, 64) if err != nil { - return fmt.Errorf("%q value should be a number: %w", value, ErrInvalidParamValue) + return fmt.Errorf("%q value should be a number: %w", value, ErrInvalidParameterValue) } if !(val < v.V) { formatted := strconv.FormatFloat(v.V, 'f', -1, 64) From a2c52ff56f0fe41d4077f75110b70e6adf3c3c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Thu, 15 Feb 2024 18:17:50 +0100 Subject: [PATCH 5/9] rename proto folder parameter to config --- config/proto.go | 66 +++---- config/proto_test.go | 86 ++++----- .../{parameter => config}/v1/parameter.pb.go | 179 +++++++++--------- .../{parameter => config}/v1/parameter.proto | 0 4 files changed, 165 insertions(+), 166 deletions(-) rename proto/{parameter => config}/v1/parameter.pb.go (54%) rename proto/{parameter => config}/v1/parameter.proto (100%) diff --git a/config/proto.go b/config/proto.go index e0c94e8..defd048 100644 --- a/config/proto.go +++ b/config/proto.go @@ -20,29 +20,29 @@ import ( "strconv" "strings" - parameterv1 "github.com/conduitio/conduit-commons/proto/parameter/v1" + configv1 "github.com/conduitio/conduit-commons/proto/config/v1" ) func _() { // An "invalid array index" compiler error signifies that the constant values have changed. var cTypes [1]struct{} - _ = cTypes[int(ParameterTypeString)-int(parameterv1.Parameter_TYPE_STRING)] - _ = cTypes[int(ParameterTypeInt)-int(parameterv1.Parameter_TYPE_INT)] - _ = cTypes[int(ParameterTypeFloat)-int(parameterv1.Parameter_TYPE_FLOAT)] - _ = cTypes[int(ParameterTypeBool)-int(parameterv1.Parameter_TYPE_BOOL)] - _ = cTypes[int(ParameterTypeFile)-int(parameterv1.Parameter_TYPE_FILE)] - _ = cTypes[int(ParameterTypeDuration)-int(parameterv1.Parameter_TYPE_DURATION)] + _ = cTypes[int(ParameterTypeString)-int(configv1.Parameter_TYPE_STRING)] + _ = cTypes[int(ParameterTypeInt)-int(configv1.Parameter_TYPE_INT)] + _ = cTypes[int(ParameterTypeFloat)-int(configv1.Parameter_TYPE_FLOAT)] + _ = cTypes[int(ParameterTypeBool)-int(configv1.Parameter_TYPE_BOOL)] + _ = cTypes[int(ParameterTypeFile)-int(configv1.Parameter_TYPE_FILE)] + _ = cTypes[int(ParameterTypeDuration)-int(configv1.Parameter_TYPE_DURATION)] } func _() { // An "invalid array index" compiler error signifies that the constant values have changed. var cTypes [1]struct{} - _ = cTypes[int(ValidationTypeRequired)-int(parameterv1.Validation_TYPE_REQUIRED)] - _ = cTypes[int(ValidationTypeGreaterThan)-int(parameterv1.Validation_TYPE_GREATER_THAN)] - _ = cTypes[int(ValidationTypeLessThan)-int(parameterv1.Validation_TYPE_LESS_THAN)] - _ = cTypes[int(ValidationTypeInclusion)-int(parameterv1.Validation_TYPE_INCLUSION)] - _ = cTypes[int(ValidationTypeExclusion)-int(parameterv1.Validation_TYPE_EXCLUSION)] - _ = cTypes[int(ValidationTypeRegex)-int(parameterv1.Validation_TYPE_REGEX)] + _ = cTypes[int(ValidationTypeRequired)-int(configv1.Validation_TYPE_REQUIRED)] + _ = cTypes[int(ValidationTypeGreaterThan)-int(configv1.Validation_TYPE_GREATER_THAN)] + _ = cTypes[int(ValidationTypeLessThan)-int(configv1.Validation_TYPE_LESS_THAN)] + _ = cTypes[int(ValidationTypeInclusion)-int(configv1.Validation_TYPE_INCLUSION)] + _ = cTypes[int(ValidationTypeExclusion)-int(configv1.Validation_TYPE_EXCLUSION)] + _ = cTypes[int(ValidationTypeRegex)-int(configv1.Validation_TYPE_REGEX)] } // -- From Proto To Parameter -------------------------------------------------- @@ -50,7 +50,7 @@ func _() { // FromProto takes data from the supplied proto object and populates the // receiver. If the proto object is nil, the receiver is set to its zero value. // If the function returns an error, the receiver could be partially populated. -func (p *Parameters) FromProto(proto map[string]*parameterv1.Parameter) error { +func (p *Parameters) FromProto(proto map[string]*configv1.Parameter) error { if proto == nil { *p = nil return nil @@ -71,7 +71,7 @@ func (p *Parameters) FromProto(proto map[string]*parameterv1.Parameter) error { // FromProto takes data from the supplied proto object and populates the // receiver. If the proto object is nil, the receiver is set to its zero value. // If the function returns an error, the receiver could be partially populated. -func (p *Parameter) FromProto(proto *parameterv1.Parameter) error { +func (p *Parameter) FromProto(proto *configv1.Parameter) error { if proto == nil { *p = Parameter{} return nil @@ -89,7 +89,7 @@ func (p *Parameter) FromProto(proto *parameterv1.Parameter) error { return nil } -func validationsFromProto(proto []*parameterv1.Validation) ([]Validation, error) { +func validationsFromProto(proto []*configv1.Validation) ([]Validation, error) { if proto == nil { return nil, nil } @@ -105,37 +105,37 @@ func validationsFromProto(proto []*parameterv1.Validation) ([]Validation, error) return validations, nil } -func validationFromProto(proto *parameterv1.Validation) (Validation, error) { +func validationFromProto(proto *configv1.Validation) (Validation, error) { if proto == nil { return nil, nil //nolint:nilnil // This is the expected behavior. } switch proto.Type { - case parameterv1.Validation_TYPE_REQUIRED: + case configv1.Validation_TYPE_REQUIRED: return ValidationRequired{}, nil - case parameterv1.Validation_TYPE_GREATER_THAN: + case configv1.Validation_TYPE_GREATER_THAN: v, err := strconv.ParseFloat(proto.Value, 64) if err != nil { return nil, fmt.Errorf("error parsing greater than value: %w", err) } return ValidationGreaterThan{V: v}, nil - case parameterv1.Validation_TYPE_LESS_THAN: + case configv1.Validation_TYPE_LESS_THAN: v, err := strconv.ParseFloat(proto.Value, 64) if err != nil { return nil, fmt.Errorf("error parsing less than value: %w", err) } return ValidationLessThan{V: v}, nil - case parameterv1.Validation_TYPE_INCLUSION: + case configv1.Validation_TYPE_INCLUSION: return ValidationInclusion{List: strings.Split(proto.Value, ",")}, nil - case parameterv1.Validation_TYPE_EXCLUSION: + case configv1.Validation_TYPE_EXCLUSION: return ValidationExclusion{List: strings.Split(proto.Value, ",")}, nil - case parameterv1.Validation_TYPE_REGEX: + case configv1.Validation_TYPE_REGEX: regex, err := regexp.Compile(proto.Value) if err != nil { return nil, fmt.Errorf("error compiling regex: %w", err) } return ValidationRegex{Regex: regex}, nil - case parameterv1.Validation_TYPE_UNSPECIFIED: + case configv1.Validation_TYPE_UNSPECIFIED: fallthrough default: return nil, fmt.Errorf("%v: %w", proto.Type, ErrInvalidValidationType) @@ -145,38 +145,38 @@ func validationFromProto(proto *parameterv1.Validation) (Validation, error) { // -- From Parameter To Proto -------------------------------------------------- // ToProto takes data from the receiver and populates the supplied proto object. -func (p Parameters) ToProto(proto map[string]*parameterv1.Parameter) { +func (p Parameters) ToProto(proto map[string]*configv1.Parameter) { clear(proto) for k, param := range p { - var v parameterv1.Parameter + var v configv1.Parameter param.ToProto(&v) proto[k] = &v } } // ToProto takes data from the receiver and populates the supplied proto object. -func (p Parameter) ToProto(proto *parameterv1.Parameter) { +func (p Parameter) ToProto(proto *configv1.Parameter) { proto.Default = p.Default proto.Description = p.Description - proto.Type = parameterv1.Parameter_Type(p.Type) + proto.Type = configv1.Parameter_Type(p.Type) proto.Validations = validationsToProto(p.Validations) } -func validationsToProto(validations []Validation) []*parameterv1.Validation { +func validationsToProto(validations []Validation) []*configv1.Validation { if validations == nil { return nil } - proto := make([]*parameterv1.Validation, len(validations)) + proto := make([]*configv1.Validation, len(validations)) for i, v := range validations { proto[i] = validationToProto(v) } return proto } -func validationToProto(validation Validation) *parameterv1.Validation { - return ¶meterv1.Validation{ - Type: parameterv1.Validation_Type(validation.Type()), +func validationToProto(validation Validation) *configv1.Validation { + return &configv1.Validation{ + Type: configv1.Validation_Type(validation.Type()), Value: validation.Value(), } } diff --git a/config/proto_test.go b/config/proto_test.go index 112a3a0..fcb2c70 100644 --- a/config/proto_test.go +++ b/config/proto_test.go @@ -19,24 +19,24 @@ import ( "regexp" "testing" - parameterv1 "github.com/conduitio/conduit-commons/proto/parameter/v1" + configv1 "github.com/conduitio/conduit-commons/proto/config/v1" "github.com/matryer/is" ) func TestParameter_FromProto(t *testing.T) { is := is.New(t) - have := ¶meterv1.Parameter{ + have := &configv1.Parameter{ Description: "test-description", Default: "test-default", - Type: parameterv1.Parameter_TYPE_STRING, - Validations: []*parameterv1.Validation{ - {Type: parameterv1.Validation_TYPE_REQUIRED}, - {Type: parameterv1.Validation_TYPE_GREATER_THAN, Value: "1.2"}, - {Type: parameterv1.Validation_TYPE_LESS_THAN, Value: "3.4"}, - {Type: parameterv1.Validation_TYPE_INCLUSION, Value: "1,2,3"}, - {Type: parameterv1.Validation_TYPE_EXCLUSION, Value: "4,5,6"}, - {Type: parameterv1.Validation_TYPE_REGEX, Value: "test-regex"}, + Type: configv1.Parameter_TYPE_STRING, + Validations: []*configv1.Validation{ + {Type: configv1.Validation_TYPE_REQUIRED}, + {Type: configv1.Validation_TYPE_GREATER_THAN, Value: "1.2"}, + {Type: configv1.Validation_TYPE_LESS_THAN, Value: "3.4"}, + {Type: configv1.Validation_TYPE_INCLUSION, Value: "1,2,3"}, + {Type: configv1.Validation_TYPE_EXCLUSION, Value: "4,5,6"}, + {Type: configv1.Validation_TYPE_REGEX, Value: "test-regex"}, }, } @@ -73,41 +73,41 @@ func TestParameter_ToProto(t *testing.T) { }, } - want := ¶meterv1.Parameter{ + want := &configv1.Parameter{ Description: "test-description", Default: "test-default", - Type: parameterv1.Parameter_TYPE_STRING, - Validations: []*parameterv1.Validation{ - {Type: parameterv1.Validation_TYPE_REQUIRED}, - {Type: parameterv1.Validation_TYPE_REGEX, Value: "test-regex"}, + Type: configv1.Parameter_TYPE_STRING, + Validations: []*configv1.Validation{ + {Type: configv1.Validation_TYPE_REQUIRED}, + {Type: configv1.Validation_TYPE_REGEX, Value: "test-regex"}, }, } - got := ¶meterv1.Parameter{} + got := &configv1.Parameter{} have.ToProto(got) is.Equal(want, got) } func TestParameter_ParameterTypes(t *testing.T) { testCases := []struct { - protoType parameterv1.Parameter_Type + protoType configv1.Parameter_Type goType ParameterType }{ - {protoType: parameterv1.Parameter_TYPE_UNSPECIFIED, goType: 0}, - {protoType: parameterv1.Parameter_TYPE_STRING, goType: ParameterTypeString}, - {protoType: parameterv1.Parameter_TYPE_INT, goType: ParameterTypeInt}, - {protoType: parameterv1.Parameter_TYPE_FLOAT, goType: ParameterTypeFloat}, - {protoType: parameterv1.Parameter_TYPE_BOOL, goType: ParameterTypeBool}, - {protoType: parameterv1.Parameter_TYPE_FILE, goType: ParameterTypeFile}, - {protoType: parameterv1.Parameter_TYPE_DURATION, goType: ParameterTypeDuration}, - {protoType: parameterv1.Parameter_Type(100), goType: 100}, + {protoType: configv1.Parameter_TYPE_UNSPECIFIED, goType: 0}, + {protoType: configv1.Parameter_TYPE_STRING, goType: ParameterTypeString}, + {protoType: configv1.Parameter_TYPE_INT, goType: ParameterTypeInt}, + {protoType: configv1.Parameter_TYPE_FLOAT, goType: ParameterTypeFloat}, + {protoType: configv1.Parameter_TYPE_BOOL, goType: ParameterTypeBool}, + {protoType: configv1.Parameter_TYPE_FILE, goType: ParameterTypeFile}, + {protoType: configv1.Parameter_TYPE_DURATION, goType: ParameterTypeDuration}, + {protoType: configv1.Parameter_Type(100), goType: 100}, } t.Run("FromProto", func(t *testing.T) { for _, tc := range testCases { t.Run(tc.goType.String(), func(*testing.T) { is := is.New(t) - have := ¶meterv1.Parameter{Type: tc.protoType} + have := &configv1.Parameter{Type: tc.protoType} want := Parameter{Type: tc.goType} var got Parameter @@ -123,9 +123,9 @@ func TestParameter_ParameterTypes(t *testing.T) { t.Run(tc.goType.String(), func(t *testing.T) { is := is.New(t) have := Parameter{Type: tc.goType} - want := ¶meterv1.Parameter{Type: tc.protoType} + want := &configv1.Parameter{Type: tc.protoType} - got := ¶meterv1.Parameter{} + got := &configv1.Parameter{} have.ToProto(got) is.Equal(want, got) }) @@ -135,31 +135,31 @@ func TestParameter_ParameterTypes(t *testing.T) { func TestParameter_Validation(t *testing.T) { testCases := []struct { - protoType *parameterv1.Validation + protoType *configv1.Validation goType Validation }{ { - protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_REQUIRED}, + protoType: &configv1.Validation{Type: configv1.Validation_TYPE_REQUIRED}, goType: ValidationRequired{}, }, { - protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_GREATER_THAN, Value: "1.2"}, + protoType: &configv1.Validation{Type: configv1.Validation_TYPE_GREATER_THAN, Value: "1.2"}, goType: ValidationGreaterThan{V: 1.2}, }, { - protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_LESS_THAN, Value: "3.4"}, + protoType: &configv1.Validation{Type: configv1.Validation_TYPE_LESS_THAN, Value: "3.4"}, goType: ValidationLessThan{V: 3.4}, }, { - protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_INCLUSION, Value: "1,2,3"}, + protoType: &configv1.Validation{Type: configv1.Validation_TYPE_INCLUSION, Value: "1,2,3"}, goType: ValidationInclusion{List: []string{"1", "2", "3"}}, }, { - protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_EXCLUSION, Value: "4,5,6"}, + protoType: &configv1.Validation{Type: configv1.Validation_TYPE_EXCLUSION, Value: "4,5,6"}, goType: ValidationExclusion{List: []string{"4", "5", "6"}}, }, { - protoType: ¶meterv1.Validation{Type: parameterv1.Validation_TYPE_REGEX, Value: "test-regex"}, + protoType: &configv1.Validation{Type: configv1.Validation_TYPE_REGEX, Value: "test-regex"}, goType: ValidationRegex{Regex: regexp.MustCompile("test-regex")}, }, } @@ -168,8 +168,8 @@ func TestParameter_Validation(t *testing.T) { for _, tc := range testCases { t.Run(tc.goType.Type().String(), func(t *testing.T) { is := is.New(t) - have := ¶meterv1.Parameter{ - Validations: []*parameterv1.Validation{tc.protoType}, + have := &configv1.Parameter{ + Validations: []*configv1.Validation{tc.protoType}, } want := Parameter{ Validations: []Validation{tc.goType}, @@ -190,11 +190,11 @@ func TestParameter_Validation(t *testing.T) { have := Parameter{ Validations: []Validation{tc.goType}, } - want := ¶meterv1.Parameter{ - Validations: []*parameterv1.Validation{tc.protoType}, + want := &configv1.Parameter{ + Validations: []*configv1.Validation{tc.protoType}, } - got := ¶meterv1.Parameter{} + got := &configv1.Parameter{} have.ToProto(got) is.Equal(want, got) }) @@ -204,9 +204,9 @@ func TestParameter_Validation(t *testing.T) { func TestParameter_Validation_InvalidType(t *testing.T) { is := is.New(t) - have := ¶meterv1.Parameter{ - Validations: []*parameterv1.Validation{ - {Type: parameterv1.Validation_TYPE_UNSPECIFIED}, + have := &configv1.Parameter{ + Validations: []*configv1.Validation{ + {Type: configv1.Validation_TYPE_UNSPECIFIED}, }, } var got Parameter diff --git a/proto/parameter/v1/parameter.pb.go b/proto/config/v1/parameter.pb.go similarity index 54% rename from proto/parameter/v1/parameter.pb.go rename to proto/config/v1/parameter.pb.go index 4cc345b..5ff2efe 100644 --- a/proto/parameter/v1/parameter.pb.go +++ b/proto/config/v1/parameter.pb.go @@ -2,7 +2,7 @@ // versions: // protoc-gen-go v1.31.0 // protoc (unknown) -// source: parameter/v1/parameter.proto +// source: config/v1/parameter.proto package parameterv1 @@ -72,11 +72,11 @@ func (x Parameter_Type) String() string { } func (Parameter_Type) Descriptor() protoreflect.EnumDescriptor { - return file_parameter_v1_parameter_proto_enumTypes[0].Descriptor() + return file_config_v1_parameter_proto_enumTypes[0].Descriptor() } func (Parameter_Type) Type() protoreflect.EnumType { - return &file_parameter_v1_parameter_proto_enumTypes[0] + return &file_config_v1_parameter_proto_enumTypes[0] } func (x Parameter_Type) Number() protoreflect.EnumNumber { @@ -85,7 +85,7 @@ func (x Parameter_Type) Number() protoreflect.EnumNumber { // Deprecated: Use Parameter_Type.Descriptor instead. func (Parameter_Type) EnumDescriptor() ([]byte, []int) { - return file_parameter_v1_parameter_proto_rawDescGZIP(), []int{0, 0} + return file_config_v1_parameter_proto_rawDescGZIP(), []int{0, 0} } type Validation_Type int32 @@ -139,11 +139,11 @@ func (x Validation_Type) String() string { } func (Validation_Type) Descriptor() protoreflect.EnumDescriptor { - return file_parameter_v1_parameter_proto_enumTypes[1].Descriptor() + return file_config_v1_parameter_proto_enumTypes[1].Descriptor() } func (Validation_Type) Type() protoreflect.EnumType { - return &file_parameter_v1_parameter_proto_enumTypes[1] + return &file_config_v1_parameter_proto_enumTypes[1] } func (x Validation_Type) Number() protoreflect.EnumNumber { @@ -152,7 +152,7 @@ func (x Validation_Type) Number() protoreflect.EnumNumber { // Deprecated: Use Validation_Type.Descriptor instead. func (Validation_Type) EnumDescriptor() ([]byte, []int) { - return file_parameter_v1_parameter_proto_rawDescGZIP(), []int{1, 0} + return file_config_v1_parameter_proto_rawDescGZIP(), []int{1, 0} } // Parameter describes a single config parameter. @@ -175,7 +175,7 @@ type Parameter struct { func (x *Parameter) Reset() { *x = Parameter{} if protoimpl.UnsafeEnabled { - mi := &file_parameter_v1_parameter_proto_msgTypes[0] + mi := &file_config_v1_parameter_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -188,7 +188,7 @@ func (x *Parameter) String() string { func (*Parameter) ProtoMessage() {} func (x *Parameter) ProtoReflect() protoreflect.Message { - mi := &file_parameter_v1_parameter_proto_msgTypes[0] + mi := &file_config_v1_parameter_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -201,7 +201,7 @@ func (x *Parameter) ProtoReflect() protoreflect.Message { // Deprecated: Use Parameter.ProtoReflect.Descriptor instead. func (*Parameter) Descriptor() ([]byte, []int) { - return file_parameter_v1_parameter_proto_rawDescGZIP(), []int{0} + return file_config_v1_parameter_proto_rawDescGZIP(), []int{0} } func (x *Parameter) GetDefault() string { @@ -247,7 +247,7 @@ type Validation struct { func (x *Validation) Reset() { *x = Validation{} if protoimpl.UnsafeEnabled { - mi := &file_parameter_v1_parameter_proto_msgTypes[1] + mi := &file_config_v1_parameter_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -260,7 +260,7 @@ func (x *Validation) String() string { func (*Validation) ProtoMessage() {} func (x *Validation) ProtoReflect() protoreflect.Message { - mi := &file_parameter_v1_parameter_proto_msgTypes[1] + mi := &file_config_v1_parameter_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -273,7 +273,7 @@ func (x *Validation) ProtoReflect() protoreflect.Message { // Deprecated: Use Validation.ProtoReflect.Descriptor instead. func (*Validation) Descriptor() ([]byte, []int) { - return file_parameter_v1_parameter_proto_rawDescGZIP(), []int{1} + return file_config_v1_parameter_proto_rawDescGZIP(), []int{1} } func (x *Validation) GetType() Validation_Type { @@ -290,82 +290,81 @@ func (x *Validation) GetValue() string { return "" } -var File_parameter_v1_parameter_proto protoreflect.FileDescriptor - -var file_parameter_v1_parameter_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x22, 0xb3, 0x02, 0x0a, - 0x09, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, - 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x10, - 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, - 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x04, - 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x05, 0x12, - 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x10, 0x06, 0x22, 0xea, 0x01, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x31, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1d, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x04, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x45, 0x41, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, 0x41, - 0x4e, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x45, 0x53, 0x53, - 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, - 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, 0x06, 0x42, - 0xb8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x69, 0x74, 0x69, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, - 0x64, 0x75, 0x69, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x58, - 0x58, 0xaa, 0x02, 0x0c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x31, - 0xca, 0x02, 0x0c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, - 0x02, 0x18, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, +var File_config_v1_parameter_proto protoreflect.FileDescriptor + +var file_config_v1_parameter_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x22, 0xb3, 0x02, 0x0a, 0x09, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x1c, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x7c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, + 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x0e, + 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x03, 0x12, 0x0d, + 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x04, 0x12, 0x0d, 0x0a, + 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x22, + 0xea, 0x01, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, + 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x47, 0x52, 0x45, 0x41, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x10, 0x02, + 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, + 0x41, 0x4e, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x43, + 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, 0x06, 0x42, 0xb5, 0x01, 0x0a, + 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x42, 0x0e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x69, 0x74, 0x69, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x69, + 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0c, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0c, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x18, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_parameter_v1_parameter_proto_rawDescOnce sync.Once - file_parameter_v1_parameter_proto_rawDescData = file_parameter_v1_parameter_proto_rawDesc + file_config_v1_parameter_proto_rawDescOnce sync.Once + file_config_v1_parameter_proto_rawDescData = file_config_v1_parameter_proto_rawDesc ) -func file_parameter_v1_parameter_proto_rawDescGZIP() []byte { - file_parameter_v1_parameter_proto_rawDescOnce.Do(func() { - file_parameter_v1_parameter_proto_rawDescData = protoimpl.X.CompressGZIP(file_parameter_v1_parameter_proto_rawDescData) +func file_config_v1_parameter_proto_rawDescGZIP() []byte { + file_config_v1_parameter_proto_rawDescOnce.Do(func() { + file_config_v1_parameter_proto_rawDescData = protoimpl.X.CompressGZIP(file_config_v1_parameter_proto_rawDescData) }) - return file_parameter_v1_parameter_proto_rawDescData + return file_config_v1_parameter_proto_rawDescData } -var file_parameter_v1_parameter_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_parameter_v1_parameter_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_parameter_v1_parameter_proto_goTypes = []interface{}{ +var file_config_v1_parameter_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_config_v1_parameter_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_config_v1_parameter_proto_goTypes = []interface{}{ (Parameter_Type)(0), // 0: parameter.v1.Parameter.Type (Validation_Type)(0), // 1: parameter.v1.Validation.Type (*Parameter)(nil), // 2: parameter.v1.Parameter (*Validation)(nil), // 3: parameter.v1.Validation } -var file_parameter_v1_parameter_proto_depIdxs = []int32{ +var file_config_v1_parameter_proto_depIdxs = []int32{ 0, // 0: parameter.v1.Parameter.type:type_name -> parameter.v1.Parameter.Type 3, // 1: parameter.v1.Parameter.validations:type_name -> parameter.v1.Validation 1, // 2: parameter.v1.Validation.type:type_name -> parameter.v1.Validation.Type @@ -376,13 +375,13 @@ var file_parameter_v1_parameter_proto_depIdxs = []int32{ 0, // [0:3] is the sub-list for field type_name } -func init() { file_parameter_v1_parameter_proto_init() } -func file_parameter_v1_parameter_proto_init() { - if File_parameter_v1_parameter_proto != nil { +func init() { file_config_v1_parameter_proto_init() } +func file_config_v1_parameter_proto_init() { + if File_config_v1_parameter_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_parameter_v1_parameter_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_config_v1_parameter_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Parameter); i { case 0: return &v.state @@ -394,7 +393,7 @@ func file_parameter_v1_parameter_proto_init() { return nil } } - file_parameter_v1_parameter_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_config_v1_parameter_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Validation); i { case 0: return &v.state @@ -411,19 +410,19 @@ func file_parameter_v1_parameter_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_parameter_v1_parameter_proto_rawDesc, + RawDescriptor: file_config_v1_parameter_proto_rawDesc, NumEnums: 2, NumMessages: 2, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_parameter_v1_parameter_proto_goTypes, - DependencyIndexes: file_parameter_v1_parameter_proto_depIdxs, - EnumInfos: file_parameter_v1_parameter_proto_enumTypes, - MessageInfos: file_parameter_v1_parameter_proto_msgTypes, + GoTypes: file_config_v1_parameter_proto_goTypes, + DependencyIndexes: file_config_v1_parameter_proto_depIdxs, + EnumInfos: file_config_v1_parameter_proto_enumTypes, + MessageInfos: file_config_v1_parameter_proto_msgTypes, }.Build() - File_parameter_v1_parameter_proto = out.File - file_parameter_v1_parameter_proto_rawDesc = nil - file_parameter_v1_parameter_proto_goTypes = nil - file_parameter_v1_parameter_proto_depIdxs = nil + File_config_v1_parameter_proto = out.File + file_config_v1_parameter_proto_rawDesc = nil + file_config_v1_parameter_proto_goTypes = nil + file_config_v1_parameter_proto_depIdxs = nil } diff --git a/proto/parameter/v1/parameter.proto b/proto/config/v1/parameter.proto similarity index 100% rename from proto/parameter/v1/parameter.proto rename to proto/config/v1/parameter.proto From 10082a421fa6970fbb709bfc80bd02421bd32c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Thu, 15 Feb 2024 18:20:03 +0100 Subject: [PATCH 6/9] rename proto package to config.v1 --- proto/config/v1/parameter.pb.go | 112 ++++++++++++++++---------------- proto/config/v1/parameter.proto | 2 +- 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/proto/config/v1/parameter.pb.go b/proto/config/v1/parameter.pb.go index 5ff2efe..dd1a031 100644 --- a/proto/config/v1/parameter.pb.go +++ b/proto/config/v1/parameter.pb.go @@ -4,7 +4,7 @@ // protoc (unknown) // source: config/v1/parameter.proto -package parameterv1 +package configv1 import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -167,7 +167,7 @@ type Parameter struct { // Description explains what the parameter does and how to configure it. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // Type defines the parameter data type. - Type Parameter_Type `protobuf:"varint,3,opt,name=type,proto3,enum=parameter.v1.Parameter_Type" json:"type,omitempty"` + Type Parameter_Type `protobuf:"varint,3,opt,name=type,proto3,enum=config.v1.Parameter_Type" json:"type,omitempty"` // Validations are validations to be made on the parameter. Validations []*Validation `protobuf:"bytes,4,rep,name=validations,proto3" json:"validations,omitempty"` } @@ -238,7 +238,7 @@ type Validation struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type Validation_Type `protobuf:"varint,1,opt,name=type,proto3,enum=parameter.v1.Validation_Type" json:"type,omitempty"` + Type Validation_Type `protobuf:"varint,1,opt,name=type,proto3,enum=config.v1.Validation_Type" json:"type,omitempty"` // The value to be compared with the parameter, // or a comma separated list in case of Validation.TYPE_INCLUSION or Validation.TYPE_EXCLUSION. Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` @@ -294,54 +294,52 @@ var File_config_v1_parameter_proto protoreflect.FileDescriptor var file_config_v1_parameter_proto_rawDesc = []byte{ 0x0a, 0x19, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x22, 0xb3, 0x02, 0x0a, 0x09, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x1c, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x22, 0x7c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, - 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x0e, - 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x03, 0x12, 0x0d, - 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x04, 0x12, 0x0d, 0x0a, - 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x22, - 0xea, 0x01, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x22, 0xad, 0x02, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, + 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x37, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, - 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x47, 0x52, 0x45, 0x41, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x10, 0x02, - 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, - 0x41, 0x4e, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x43, - 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, 0x06, 0x42, 0xb5, 0x01, 0x0a, - 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x42, 0x0e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x69, 0x74, 0x69, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x69, - 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0c, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0c, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x18, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, + 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x49, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, + 0x4f, 0x41, 0x54, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, + 0x4f, 0x4c, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, + 0x45, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x55, 0x52, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x22, 0xe7, 0x01, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x04, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x15, 0x0a, + 0x11, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x45, 0x41, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, + 0x41, 0x4e, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x45, 0x53, + 0x53, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x05, + 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, 0x06, + 0x42, 0xa3, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x76, 0x31, 0x42, 0x0e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x69, 0x74, 0x69, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x75, + 0x69, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x58, 0x58, 0xaa, 0x02, 0x09, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x15, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -359,15 +357,15 @@ func file_config_v1_parameter_proto_rawDescGZIP() []byte { var file_config_v1_parameter_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_config_v1_parameter_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_config_v1_parameter_proto_goTypes = []interface{}{ - (Parameter_Type)(0), // 0: parameter.v1.Parameter.Type - (Validation_Type)(0), // 1: parameter.v1.Validation.Type - (*Parameter)(nil), // 2: parameter.v1.Parameter - (*Validation)(nil), // 3: parameter.v1.Validation + (Parameter_Type)(0), // 0: config.v1.Parameter.Type + (Validation_Type)(0), // 1: config.v1.Validation.Type + (*Parameter)(nil), // 2: config.v1.Parameter + (*Validation)(nil), // 3: config.v1.Validation } var file_config_v1_parameter_proto_depIdxs = []int32{ - 0, // 0: parameter.v1.Parameter.type:type_name -> parameter.v1.Parameter.Type - 3, // 1: parameter.v1.Parameter.validations:type_name -> parameter.v1.Validation - 1, // 2: parameter.v1.Validation.type:type_name -> parameter.v1.Validation.Type + 0, // 0: config.v1.Parameter.type:type_name -> config.v1.Parameter.Type + 3, // 1: config.v1.Parameter.validations:type_name -> config.v1.Validation + 1, // 2: config.v1.Validation.type:type_name -> config.v1.Validation.Type 3, // [3:3] is the sub-list for method output_type 3, // [3:3] is the sub-list for method input_type 3, // [3:3] is the sub-list for extension type_name diff --git a/proto/config/v1/parameter.proto b/proto/config/v1/parameter.proto index 44fed72..90439fc 100644 --- a/proto/config/v1/parameter.proto +++ b/proto/config/v1/parameter.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package parameter.v1; +package config.v1; // Parameter describes a single config parameter. message Parameter { From cdd09ccdce50bb9f9b70b150483c288f81000752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Fri, 16 Feb 2024 16:27:28 +0100 Subject: [PATCH 7/9] add config utility to decode into object --- config/config.go | 68 ++++++++++++++ config/config_test.go | 204 ++++++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- 3 files changed, 273 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index b0cd4c1..cd6031c 100644 --- a/config/config.go +++ b/config/config.go @@ -20,9 +20,12 @@ package config import ( "errors" "fmt" + "reflect" "strconv" "strings" "time" + + "github.com/mitchellh/mapstructure" ) // Config is a map of configuration values. The keys are the configuration @@ -143,3 +146,68 @@ func (c Config) validateParamValue(key string, param Parameter) error { return errors.Join(errs...) } + +// DecodeInto copies configuration values into the target object. +// Under the hood, this function uses github.com/mitchellh/mapstructure, with +// the "mapstructure" tag renamed to "json". To rename a key, use the "json" +// tag. To embed structs, append ",squash" to your tag. For more details and +// docs, see https://pkg.go.dev/github.com/mitchellh/mapstructure. +func (c Config) DecodeInto(target any) error { + dConfig := &mapstructure.DecoderConfig{ + WeaklyTypedInput: true, + Result: &target, + DecodeHook: mapstructure.ComposeDecodeHookFunc( + emptyStringToZeroValueHookFunc(), + mapstructure.StringToTimeDurationHookFunc(), + mapstructure.StringToSliceHookFunc(","), + ), + TagName: "json", + Squash: true, + } + + decoder, err := mapstructure.NewDecoder(dConfig) + if err != nil { + return fmt.Errorf("failed to create decoder: %w", err) + } + err = decoder.Decode(c.breakUp()) + if err != nil { + return fmt.Errorf("failed to decode configuration map into target: %w", err) + } + + return nil +} + +// breakUp breaks up the configuration into a map of maps based on the dot separator. +func (c Config) breakUp() map[string]any { + const sep = "." + + brokenUp := make(map[string]any) + for k, v := range c { + // break up based on dot and put in maps in case target struct is broken up + tokens := strings.Split(k, sep) + remain := k + current := brokenUp + for _, t := range tokens { + current[remain] = v // we don't care if we overwrite a map here, the string has precedence + if _, ok := current[t]; !ok { + current[t] = map[string]any{} + } + var ok bool + current, ok = current[t].(map[string]any) + if !ok { + break // this key is a string, leave it as it is + } + _, remain, _ = strings.Cut(remain, sep) + } + } + return brokenUp +} + +func emptyStringToZeroValueHookFunc() mapstructure.DecodeHookFunc { + return func(f reflect.Type, t reflect.Type, data any) (any, error) { + if f.Kind() != reflect.String || data != "" { + return data, nil + } + return reflect.New(t).Elem().Interface(), nil + } +} diff --git a/config/config_test.go b/config/config_test.go index b4d9ad0..ee08380 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -18,6 +18,7 @@ import ( "errors" "regexp" "testing" + "time" "github.com/matryer/is" ) @@ -344,3 +345,206 @@ func unwrapErrors(err error) []error { } return out } + +func TestParseConfig_Simple_Struct(t *testing.T) { + is := is.New(t) + + type Person struct { + Name string `json:"person_name"` + Age int + Dur time.Duration + } + + input := Config{ + "person_name": "meroxa", + "age": "91", + "dur": "", // empty value should result in zero value + } + want := Person{ + Name: "meroxa", + Age: 91, + } + + var got Person + err := input.DecodeInto(&got) + is.NoErr(err) + is.Equal(want, got) +} + +func TestParseConfig_Embedded_Struct(t *testing.T) { + is := is.New(t) + + type Family struct { + LastName string `json:"last.name"` + } + type Location struct { + City string + } + type Person struct { + Family // last.name + Location // City + F1 Family // F1.last.name + // City + L1 Location `json:",squash"` //nolint:staticcheck // json here is a rename for the mapstructure tag + L2 Location // L2.City + L3 Location `json:"loc3"` // loc3.City + FirstName string `json:"First.Name"` // First.Name + First string // First + } + + input := Config{ + "last.name": "meroxa", + "F1.last.name": "turbine", + "City": "San Francisco", + "L2.City": "Paris", + "loc3.City": "London", + "First.Name": "conduit", + "First": "Mickey", + } + want := Person{ + Family: Family{LastName: "meroxa"}, + F1: Family{LastName: "turbine"}, + Location: Location{City: "San Francisco"}, + L1: Location{City: "San Francisco"}, + L2: Location{City: "Paris"}, + L3: Location{City: "London"}, + FirstName: "conduit", + First: "Mickey", + } + + var got Person + err := input.DecodeInto(&got) + is.NoErr(err) + is.Equal(want, got) +} + +func TestParseConfig_All_Types(t *testing.T) { + is := is.New(t) + type testCfg struct { + MyString string + MyBool1 bool + MyBool2 bool + MyBool3 bool + MyBoolDefault bool + + MyInt int + MyUint uint + MyInt8 int8 + MyUint8 uint8 + MyInt16 int16 + MyUint16 uint16 + MyInt32 int32 + MyUint32 uint32 + MyInt64 int64 + MyUint64 uint64 + + MyByte byte + MyRune rune + + MyFloat32 float32 + MyFloat64 float64 + + MyDuration time.Duration + MyDurationDefault time.Duration + + MySlice []string + MyIntSlice []int + MyFloatSlice []float32 + } + + input := Config{ + "mystring": "string", + "mybool1": "t", + "mybool2": "true", + "mybool3": "1", // 1 is true + "myInt": "-1", + "myuint": "1", + "myint8": "-1", + "myuint8": "1", + "myInt16": "-1", + "myUint16": "1", + "myint32": "-1", + "myuint32": "1", + "myint64": "-1", + "myuint64": "1", + + "mybyte": "99", // 99 fits in one byte + "myrune": "4567", + + "myfloat32": "1.1122334455", + "myfloat64": "1.1122334455", + + "myduration": "1s", + + "myslice": "1,2,3,4", + "myIntSlice": "1,2,3,4", + "myFloatSlice": "1.1,2.2", + } + want := testCfg{ + MyString: "string", + MyBool1: true, + MyBool2: true, + MyBool3: true, + MyBoolDefault: false, // default + MyInt: -1, + MyUint: 0x1, + MyInt8: -1, + MyUint8: 0x1, + MyInt16: -1, + MyUint16: 0x1, + MyInt32: -1, + MyUint32: 0x1, + MyInt64: -1, + MyUint64: 0x1, + MyByte: 0x63, + MyRune: 4567, + MyFloat32: 1.1122334, + MyFloat64: 1.1122334455, + MyDuration: 1000000000, + MyDurationDefault: 0, + MySlice: []string{"1", "2", "3", "4"}, + MyIntSlice: []int{1, 2, 3, 4}, + MyFloatSlice: []float32{1.1, 2.2}, + } + + var result testCfg + err := input.DecodeInto(&result) + is.NoErr(err) + is.Equal(want, result) +} + +func TestBreakUpConfig(t *testing.T) { + is := is.New(t) + + input := Config{ + "foo.bar.baz": "1", + "test": "2", + } + want := map[string]interface{}{ + "foo": map[string]interface{}{ + "bar": map[string]interface{}{ + "baz": "1", + }, + "bar.baz": "1", + }, + "foo.bar.baz": "1", + "test": "2", + } + got := input.breakUp() + is.Equal(want, got) +} + +func TestBreakUpConfig_Conflict_Value(t *testing.T) { + is := is.New(t) + + input := Config{ + "foo": "1", + "foo.bar.baz": "1", // key foo is already taken, will not be broken up + } + want := map[string]interface{}{ + "foo": "1", + "foo.bar.baz": "1", + } + got := input.breakUp() + is.Equal(want, got) +} diff --git a/go.mod b/go.mod index b54c6e5..0eb093f 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/matryer/is v1.4.1 + github.com/mitchellh/mapstructure v1.5.0 go.uber.org/goleak v1.3.0 golang.org/x/tools v0.18.0 google.golang.org/protobuf v1.32.0 @@ -149,7 +150,6 @@ require ( github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.3.7 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/moricho/tparallel v0.3.1 // indirect github.com/morikuni/aec v1.0.0 // indirect From d18256f5d7c4ca2314dee396e09c8e8d1a62198e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Fri, 16 Feb 2024 16:48:35 +0100 Subject: [PATCH 8/9] fix config sanitize --- config/config.go | 1 + config/config_test.go | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/config/config.go b/config/config.go index cd6031c..3eb3965 100644 --- a/config/config.go +++ b/config/config.go @@ -36,6 +36,7 @@ type Config map[string]string // configuration. func (c Config) Sanitize() Config { for key, val := range c { + delete(c, key) key = strings.TrimSpace(key) val = strings.TrimSpace(val) c[key] = val diff --git a/config/config_test.go b/config/config_test.go index ee08380..217974a 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -23,6 +23,15 @@ import ( "github.com/matryer/is" ) +func TestConfig_Sanitize(t *testing.T) { + is := is.New(t) + have := Config{" key ": " value "} + want := Config{"key": "value"} + + have.Sanitize() + is.Equal(have, want) +} + func TestConfig_Validate_ParameterType(t *testing.T) { tests := []struct { name string From c2bddf517e71a092ece2de5ecca8ca96f1ebb379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Fri, 16 Feb 2024 18:07:22 +0100 Subject: [PATCH 9/9] decode hook funcs --- config/config.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/config/config.go b/config/config.go index 3eb3965..ec9789f 100644 --- a/config/config.go +++ b/config/config.go @@ -153,14 +153,17 @@ func (c Config) validateParamValue(key string, param Parameter) error { // the "mapstructure" tag renamed to "json". To rename a key, use the "json" // tag. To embed structs, append ",squash" to your tag. For more details and // docs, see https://pkg.go.dev/github.com/mitchellh/mapstructure. -func (c Config) DecodeInto(target any) error { +func (c Config) DecodeInto(target any, hookFunc ...mapstructure.DecodeHookFunc) error { dConfig := &mapstructure.DecoderConfig{ WeaklyTypedInput: true, Result: &target, DecodeHook: mapstructure.ComposeDecodeHookFunc( - emptyStringToZeroValueHookFunc(), - mapstructure.StringToTimeDurationHookFunc(), - mapstructure.StringToSliceHookFunc(","), + append( + hookFunc, + emptyStringToZeroValueHookFunc(), + mapstructure.StringToTimeDurationHookFunc(), + mapstructure.StringToSliceHookFunc(","), + )..., ), TagName: "json", Squash: true,