diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index b059a46427..d0c4a7c02a 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -37,7 +37,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2 + uses: ossf/scorecard-action@80e868c13c90f172d68d1f4501dee99e2479f7af # v2.1.3 with: results_file: results.sarif results_format: sarif diff --git a/.secrets.baseline b/.secrets.baseline index de189dd404..5067f83858 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -100,34 +100,50 @@ } ], "results": { + "utils/config/fixtures/config-test.json": [ + { + "type": "Secret Keyword", + "filename": "utils/config/fixtures/config-test.json", + "hashed_secret": "e38ad214943daad1d64c102faec29de4afe9da3d", + "is_verified": false, + "line_number": 10 + }, + { + "type": "Secret Keyword", + "filename": "utils/config/fixtures/config-test.json", + "hashed_secret": "2aa60a8ff7fcd473d321e0146afd9e26df395147", + "is_verified": false, + "line_number": 19 + } + ], "utils/config/service_configuration_test.go": [ { "type": "Secret Keyword", "filename": "utils/config/service_configuration_test.go", "hashed_secret": "ddcec2f503a5d58f432a0beee3fb9544fa581f54", "is_verified": false, - "line_number": 29 + "line_number": 31 }, { "type": "Secret Keyword", "filename": "utils/config/service_configuration_test.go", "hashed_secret": "7ca1cc114e7e5f955880bb96a5bf391b4dc20ab6", "is_verified": false, - "line_number": 366 + "line_number": 368 }, { "type": "Secret Keyword", "filename": "utils/config/service_configuration_test.go", "hashed_secret": "11519c144be4850d95b34220a40030cbd5a36b57", "is_verified": false, - "line_number": 461 + "line_number": 463 }, { "type": "Secret Keyword", "filename": "utils/config/service_configuration_test.go", "hashed_secret": "15fae91d8fa7f2c531c1cf3ddc745e1f4473c02d", "is_verified": false, - "line_number": 468 + "line_number": 470 } ], "utils/filesystem/filehash_test.go": [ @@ -232,5 +248,5 @@ } ] }, - "generated_at": "2023-02-16T13:57:06Z" + "generated_at": "2023-04-04T13:50:30Z" } diff --git a/CHANGELOG.md b/CHANGELOG.md index a87b514aa3..6f9cf2c211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,40 @@ beta releases are not included in this history. [//]: # (begin_release_notes) +"1.31.0" (2023-04-04) +===================== + +Features +-------- + +- :sparkles: `[config]` Add a way via `LoadFromEnvironment` to read configuration from a file as long as the format is supported by [Viper](https://github.com/spf13/viper#what-is-viper) (#20230404144534) + + +Bugfixes +-------- + +- Dependency upgrade: scorecard-action-2.1.3 (#20230330110538, #20230330110540, #20230330110620) +- Dependency upgrade: v3-3.23.3 (#20230403110100, #20230403110109, #20230403110141, #20230403110148, #20230403110226) + + +"1.30.0" (2023-03-17) +===================== + +Features +-------- + +- `[field]` Extend utilities to set or retrieve `time.Time` fields (#20230317105143) + + +Bugfixes +-------- + +- Dependency upgrade: v5-5.6.0 (#20230301151839) +- Dependency upgrade: zap-1.24.0 (#20230316161820, #20230316161822) +- Dependency upgrade: v5-5.6.1 (#20230316165500, #20230316165503, #20230316165619, #20230316165625, #20230316165719, #20230316165806, #20230316165905, #20230316165944, #20230316170056, #20230316170118, #20230316170232, #20230316170303, #20230316170423, #20230316170442, #20230316170545, #20230316170614, #20230316170740, #20230316170800, #20230316170857, #20230316170917, #20230316171033, #20230316171040, #20230316171226, #20230316171243, #20230316171337, #20230316171401, #20230316171508, #20230316171530, #20230316171650, #20230316171712, #20230316171805, #20230316171819, #20230316172018, #20230316172035, #20230316172139, #20230316172208, #20230316172305, #20230316172346, #20230316172458, #20230316172510, #20230316172609, #20230316172642, #20230316172801, #20230316172815, #20230316172938, #20230316172958, #20230316173110, #20230316173140, #20230316173249, #20230316173313, #20230316173434, #20230316173506, #20230316173621, #20230316173656, #20230316173808, #20230316173832, #20230316173954, #20230316174030, #20230316174128, #20230316174209, #20230316174310, #20230316174350, #20230316174431, #20230316174530, #20230316174638, #20230316174721, #20230316174742, #20230316174810, #20230316174915, #20230316175009, #20230316175048, #20230316175118, #20230316175159, #20230316175259, #20230316175342, #20230316175441, #20230316175511, #20230316175604, #20230316175623, #20230316175735, #20230316175804, #20230316175934, #20230316175956, #20230316180047, #20230316180115, #20230316180316, #20230316180327, #20230316180421, #20230316180450, #20230316180614, #20230316180624, #20230316180728, #20230316180747, #20230316180849, #20230316180935, #20230316181031, #20230316181057, #20230316181217, #20230316181230, #20230316181327, #20230316181356, #20230316181513, #20230316181523, #20230316181623, #20230316181700, #20230316181802, #20230316181828, #20230316181926, #20230316181944, #20230316182112, #20230316182121, #20230316182257, #20230316182313, #20230316182421, #20230316182450, #20230316182537, #20230316182603, #20230316182716, #20230316182729, #20230316182848, #20230316182906, #20230316183025, #20230316183037, #20230316183150, #20230316183221, #20230316183319, #20230316183349, #20230316183452, #20230316183514, #20230316183618, #20230316183700, #20230316183748, #20230316183808, #20230316183920, #20230316183945, #20230316184103, #20230316184123, #20230316184236, #20230316184243, #20230316184415, #20230316184430, #20230316184616, #20230316184631, #20230316184817, #20230316184828, #20230316185002, #20230316185015, #20230316185119, #20230316185200, #20230316185330, #20230316185407, #20230316185456, #20230316185539, #20230316185654, #20230316185734, #20230316185838, #20230316185853, #20230316190049, #20230316190107, #20230316190225, #20230316190309, #20230316190432, #20230316190456, #20230316190624, #20230316190654, #20230316190817, #20230316190844, #20230316190951, #20230316191023, #20230316191045, #20230316191106, #20230316191128, #20230316191145, #20230316191235, #20230316191258, #20230316191322, #20230316191426, #20230316191449, #20230316191526, #20230316191533, #20230316191606, #20230316191645, #20230316191710, #20230316191752, #20230316191833, #20230316191907, #20230316191915, #20230316191946, #20230316192006, #20230316192048, #20230316192107, #20230316192148, #20230316192206, #20230316192254, #20230316192315, #20230316192344, #20230316192409, #20230316192429, #20230316192451, #20230316192516, #20230316192622, #20230316192631, #20230316192700, #20230316192740, #20230316192754, #20230316192837, #20230316192847, #20230316192919, #20230316193011) +- `[commonerrors]` make `commonerrors.CorrespondTo` case-insensitive (#20230317104522) + + "1.29.0" (2023-03-16) ===================== diff --git a/changes/20230301151839.bugfix b/changes/20230301151839.bugfix deleted file mode 100644 index 795e591ed8..0000000000 --- a/changes/20230301151839.bugfix +++ /dev/null @@ -1 +0,0 @@ -Dependency upgrade: v5-5.6.0 diff --git a/changes/20230316161820.bugfix b/changes/20230316161820.bugfix deleted file mode 100644 index b4ebdd5d37..0000000000 --- a/changes/20230316161820.bugfix +++ /dev/null @@ -1 +0,0 @@ -Dependency upgrade: zap-1.24.0 diff --git a/changes/20230316161822.bugfix b/changes/20230316161822.bugfix deleted file mode 100644 index b4ebdd5d37..0000000000 --- a/changes/20230316161822.bugfix +++ /dev/null @@ -1 +0,0 @@ -Dependency upgrade: zap-1.24.0 diff --git a/changes/20230406105920.bugfix b/changes/20230406105920.bugfix new file mode 100644 index 0000000000..029306153d --- /dev/null +++ b/changes/20230406105920.bugfix @@ -0,0 +1 @@ +Dependency upgrade: text-0.9.0 diff --git a/utils/commonerrors/errors.go b/utils/commonerrors/errors.go index af1fb1a4f9..ce1793c072 100644 --- a/utils/commonerrors/errors.go +++ b/utils/commonerrors/errors.go @@ -66,7 +66,7 @@ func None(target error, err ...error) bool { } // CorrespondTo determines whether a `target` error corresponds to a specific error described by `description` -// It will check whether the error contains the string in its description. +// It will check whether the error contains the string in its description. It is not case-sensitive. // ```code // // CorrespondTo(errors.New("feature a is not supported", "not supported") = True @@ -75,9 +75,10 @@ func CorrespondTo(target error, description ...string) bool { if target == nil { return false } - desc := target.Error() + desc := strings.ToLower(target.Error()) for i := range description { - if strings.Contains(desc, description[i]) { + d := strings.ToLower(description[i]) + if desc == d || strings.Contains(desc, d) { return true } } diff --git a/utils/commonerrors/errors_test.go b/utils/commonerrors/errors_test.go index 58794c4a58..f39ca1ea9a 100644 --- a/utils/commonerrors/errors_test.go +++ b/utils/commonerrors/errors_test.go @@ -7,6 +7,7 @@ package commonerrors import ( "context" "fmt" + "strings" "testing" "time" @@ -39,9 +40,12 @@ func TestNone(t *testing.T) { } func TestCorrespondTo(t *testing.T) { + assert.False(t, CorrespondTo(nil)) + assert.False(t, CorrespondTo(nil, faker.Sentence())) assert.False(t, CorrespondTo(ErrNotImplemented, ErrInvalid.Error(), ErrUnknown.Error())) assert.True(t, CorrespondTo(ErrNotImplemented, ErrInvalid.Error(), ErrNotImplemented.Error())) assert.True(t, CorrespondTo(fmt.Errorf("%v %w", faker.Sentence(), ErrUndefined), ErrUndefined.Error())) + assert.True(t, CorrespondTo(fmt.Errorf("%v %v", faker.Sentence(), strings.ToUpper(ErrUndefined.Error())), strings.ToLower(ErrUndefined.Error()))) } func TestContextErrorConversion(t *testing.T) { diff --git a/utils/config/fixtures/config-test.json b/utils/config/fixtures/config-test.json new file mode 100644 index 0000000000..19e2a0fadf --- /dev/null +++ b/utils/config/fixtures/config-test.json @@ -0,0 +1,23 @@ +{ + "dummy_string": "test string", + "dummy_int": 1, + "dummy_time": "54s", + "dummyconfig": { + "dummy_host": "host1", + "port": 20, + "db": "db1", + "user": "user1", + "password": "password1", + "flag": true, + "healthcheck_period": "1s" + }, + "dummy_config": { + "dummy_host": "host2", + "port": 304, + "db": "db2", + "user": "user2", + "password": "password2", + "flag": false, + "healthcheck_period": "24m" + } +} \ No newline at end of file diff --git a/utils/config/interfaces.go b/utils/config/interfaces.go index e58a1cdd26..247621d7f7 100644 --- a/utils/config/interfaces.go +++ b/utils/config/interfaces.go @@ -2,11 +2,18 @@ * Copyright (C) 2020-2022 Arm Limited or its affiliates and Contributors. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ + +// Package config provides utilities to load configuration from an environment and perform validation at load time. package config -//go:generate mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/golang-utils/utils/$GOPACKAGE IServiceConfiguration +//go:generate mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/golang-utils/utils/$GOPACKAGE IServiceConfiguration,Validator +// IServiceConfiguration defines a typical service configuration. type IServiceConfiguration interface { - // Validate validates configuration entries. + Validator +} + +// Validator defines an object which can perform some validation on itself. +type Validator interface { Validate() error } diff --git a/utils/config/service_configuration.go b/utils/config/service_configuration.go index 4a97008cf5..16dc1a492c 100644 --- a/utils/config/service_configuration.go +++ b/utils/config/service_configuration.go @@ -2,6 +2,7 @@ * Copyright (C) 2020-2022 Arm Limited or its affiliates and Contributors. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ + package config import ( @@ -38,11 +39,24 @@ func Load(envVarPrefix string, configurationToSet IServiceConfiguration, default // 1) values set using explicit calls to `Set` // 2) flags // 3) environment (variables or `.env`) +// 4) key/value store +// 5) default values (set via flag default values, or calls to `SetDefault` or via `defaultConfiguration` argument provided) +// Nonetheless, when it comes to default values. It differs slightly from Viper as default values from the default Configuration (i.e. `defaultConfiguration` argument provided) will take precedence over defaults set via `SetDefault` or flags unless they are considered empty values according to `reflection.IsEmpty`. +func LoadFromViper(viperSession *viper.Viper, envVarPrefix string, configurationToSet IServiceConfiguration, defaultConfiguration IServiceConfiguration) error { + return LoadFromEnvironment(viperSession, envVarPrefix, configurationToSet, defaultConfiguration, "") +} + +// LoadFromEnvironment is the same as `LoadFromViper` but also gives the ability to load the configuration from a configuration file as long as the format is supported by [Viper](https://github.com/spf13/viper#what-is-viper) +// Important note: +// Viper's precedence order is maintained: +// 1) values set using explicit calls to `Set` +// 2) flags +// 3) environment (variables or `.env`) // 4) configuration file // 5) key/value store // 6) default values (set via flag default values, or calls to `SetDefault` or via `defaultConfiguration` argument provided) // Nonetheless, when it comes to default values. It differs slightly from Viper as default values from the default Configuration (i.e. `defaultConfiguration` argument provided) will take precedence over defaults set via `SetDefault` or flags unless they are considered empty values according to `reflection.IsEmpty`. -func LoadFromViper(viperSession *viper.Viper, envVarPrefix string, configurationToSet IServiceConfiguration, defaultConfiguration IServiceConfiguration) (err error) { +func LoadFromEnvironment(viperSession *viper.Viper, envVarPrefix string, configurationToSet IServiceConfiguration, defaultConfiguration IServiceConfiguration, configFile string) (err error) { // Load Defaults var defaults map[string]interface{} err = mapstructure.Decode(defaultConfiguration, &defaults) @@ -62,10 +76,17 @@ func LoadFromViper(viperSession *viper.Viper, envVarPrefix string, configuration linkFlagKeysToStructureKeys(viperSession, envVarPrefix) + if configFile != "" { + err = LoadFromConfigurationFile(viperSession, configFile) + if err != nil { + return + } + } + // Merge together all the sources and unmarshal into struct err = viperSession.Unmarshal(configurationToSet) if err != nil { - err = fmt.Errorf("unable to decode config into struct, %w", err) + err = fmt.Errorf("%w: unable to fill configuration structure from the configuration session: %v", commonerrors.ErrMarshalling, err.Error()) return } // Run validation @@ -73,6 +94,34 @@ func LoadFromViper(viperSession *viper.Viper, envVarPrefix string, configuration return } +// LoadFromConfigurationFile loads the configuration from the environment. +// If the format is not supported, an error is raised and the same happens if the file cannot be found. +// Supported formats are the same as what [viper](https://github.com/spf13/viper#what-is-viper) supports +func LoadFromConfigurationFile(viperSession *viper.Viper, configFile string) (err error) { + if configFile == "" { + err = fmt.Errorf("%w: missing configuration file", commonerrors.ErrUndefined) + return + } + viperSession.SetConfigFile(configFile) + err = convertViperError(viperSession.ReadInConfig()) + return +} + +func convertViperError(vErr error) (err error) { + switch { + case vErr == nil: + case commonerrors.CorrespondTo(vErr, "unsupported"): + err = fmt.Errorf("%w: %v", commonerrors.ErrUnsupported, vErr.Error()) + case commonerrors.CorrespondTo(vErr, "not found"): + err = fmt.Errorf("%w: %v", commonerrors.ErrNotFound, vErr.Error()) + case commonerrors.CorrespondTo(vErr, "parsing", "marshaling", "decoding"): + err = fmt.Errorf("%w: %v", commonerrors.ErrMarshalling, vErr.Error()) + default: + err = fmt.Errorf("%w: %v", commonerrors.ErrUnexpected, vErr.Error()) + } + return +} + // BindFlagToEnv binds pflags to environment variable. // Envvar is the environment variable string with or without the prefix envVarPrefix func BindFlagToEnv(viperSession *viper.Viper, envVarPrefix string, envVar string, flag *pflag.Flag) (err error) { diff --git a/utils/config/service_configuration_test.go b/utils/config/service_configuration_test.go index e15114a5ce..611cf17d7b 100644 --- a/utils/config/service_configuration_test.go +++ b/utils/config/service_configuration_test.go @@ -5,9 +5,11 @@ package config import ( + "errors" "fmt" "math/rand" "os" + "path/filepath" "testing" "time" @@ -495,3 +497,90 @@ func TestGenerateEnvFile_Empty(t *testing.T) { _, err := DetermineConfigurationEnvironmentVariables(prefix, struct{ IServiceConfiguration }{}) require.ErrorIs(t, err, commonerrors.ErrUndefined) } + +func Test_convertViperError(t *testing.T) { + tests := []struct { + viperErr error + expectedError error + }{ + { + viperErr: nil, + expectedError: nil, + }, + { + viperErr: viper.ConfigFileNotFoundError{}, + expectedError: commonerrors.ErrNotFound, + }, + // Note: the following errors were considered but could not be created outside the viper module (non exposed fields) + // { + // viperErr: viper.ConfigParseError{}, + // expectedError: commonerrors.ErrMarshalling, + // }, + // { + // viperErr: viper.ConfigMarshalError{}, + // expectedError: commonerrors.ErrMarshalling, + // }, + { + viperErr: viper.UnsupportedConfigError(faker.Sentence()), + expectedError: commonerrors.ErrUnsupported, + }, + { + viperErr: viper.UnsupportedRemoteProviderError(faker.Sentence()), + expectedError: commonerrors.ErrUnsupported, + }, + { + viperErr: viper.ConfigFileAlreadyExistsError(faker.Sentence()), + expectedError: commonerrors.ErrUnexpected, + }, + { + viperErr: viper.RemoteConfigError(faker.Sentence()), + expectedError: commonerrors.ErrUnexpected, + }, + { + viperErr: errors.New(faker.Name()), + expectedError: commonerrors.ErrUnexpected, + }, + } + for i := range tests { + t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { + test := tests[i] + require.True(t, commonerrors.Any(convertViperError(test.viperErr), test.expectedError)) + }) + } +} + +func TestServiceConfigurationLoadFromFile(t *testing.T) { + os.Clearenv() + session := viper.New() + err := LoadFromConfigurationFile(session, "") + assert.Error(t, err) + err = LoadFromConfigurationFile(session, fmt.Sprintf("doesnotexist-%v.test", faker.DomainName())) + assert.Error(t, err) + err = LoadFromConfigurationFile(session, filepath.Join(".", "fixtures", "config-test.json")) + assert.NoError(t, err) + value := session.Get("dummy_string") + assert.NotEmpty(t, value) + assert.Equal(t, "test string", value) +} + +func TestServiceConfigurationLoadFromEnvironment(t *testing.T) { + os.Clearenv() + session := viper.New() + configTest := &ConfigurationTest{} + defaults := DefaultConfiguration() + err := LoadFromEnvironment(session, "test", configTest, defaults, filepath.Join(".", "fixtures", "config-test.json")) + require.NoError(t, err) + require.NoError(t, configTest.Validate()) + assert.Equal(t, "test string", configTest.TestString) + assert.Equal(t, 1, configTest.TestInt) + assert.Equal(t, 54*time.Second, configTest.TestTime) + assert.Equal(t, 20, configTest.TestConfig.Port) + assert.Equal(t, "host1", configTest.TestConfig.Host) + assert.Equal(t, "password2", configTest.TestConfig2.Password) + assert.Equal(t, "db2", configTest.TestConfig2.DB) + assert.NotEqual(t, expectedHost, configTest.TestConfig2.Host) + assert.NotEqual(t, expectedPassword, configTest.TestConfig.Password) + assert.NotEqual(t, expectedDB, configTest.TestConfig.DB) + assert.True(t, configTest.TestConfig.Flag) + assert.False(t, configTest.TestConfig2.Flag) +} diff --git a/utils/config/validation.go b/utils/config/validation.go index ca0b90545b..355920a701 100644 --- a/utils/config/validation.go +++ b/utils/config/validation.go @@ -6,10 +6,6 @@ package config import "reflect" -type Validator interface { - Validate() error -} - // ValidateEmbedded uses reflection to find embedded structs and validate them func ValidateEmbedded(cfg Validator) error { r := reflect.ValueOf(cfg).Elem() diff --git a/utils/field/fields.go b/utils/field/fields.go index 575ff9154c..47767ab5d1 100644 --- a/utils/field/fields.go +++ b/utils/field/fields.go @@ -165,3 +165,16 @@ func OptionalDuration(ptr *time.Duration, defaultValue time.Duration) time.Durat } return defaultValue } + +// ToOptionalTime returns a pointer to a Time. +func ToOptionalTime(i time.Time) *time.Time { + return &i +} + +// OptionalTime returns the value of an optional field or else returns defaultValue. +func OptionalTime(ptr *time.Time, defaultValue time.Time) time.Time { + if ptr != nil { + return *ptr + } + return defaultValue +} diff --git a/utils/field/fields_test.go b/utils/field/fields_test.go index 11fee50177..da782f5e39 100644 --- a/utils/field/fields_test.go +++ b/utils/field/fields_test.go @@ -185,6 +185,21 @@ func TestOptionalField(t *testing.T) { return OptionalDuration(ptr, a2.(time.Duration)) }, }, + { + fieldType: "time", + value: time.Now(), + defaultValue: time.Now().Add(-time.Hour), + setFunction: func(a any) any { + return ToOptionalTime(a.(time.Time)) + }, + getFunction: func(a any, a2 any) any { + var ptr *time.Time + if a != nil { + ptr = a.(*time.Time) + } + return OptionalTime(ptr, a2.(time.Time)) + }, + }, { fieldType: "Any", value: faker.Sentence(), diff --git a/utils/go.mod b/utils/go.mod index cef3f8987a..93a7cb8529 100644 --- a/utils/go.mod +++ b/utils/go.mod @@ -11,7 +11,7 @@ require ( github.com/deckarep/golang-set v1.8.0 github.com/djherbis/times v1.5.0 github.com/dolmen-go/contextio v0.0.0-20220904134943-e50796217f5f - github.com/go-git/go-git/v5 v5.6.0 + github.com/go-git/go-git/v5 v5.6.1 github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a github.com/go-logr/logr v0.4.0 // Staying on this version until kubernetes uses a more recent one github.com/go-logr/stdr v0.4.0 @@ -27,7 +27,7 @@ require ( github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 github.com/rs/zerolog v1.29.0 github.com/sasha-s/go-deadlock v0.3.1 - github.com/shirou/gopsutil/v3 v3.23.2 + github.com/shirou/gopsutil/v3 v3.23.3 github.com/sirupsen/logrus v1.9.0 github.com/spaolacci/murmur3 v1.1.0 github.com/spf13/afero v1.9.5 @@ -39,19 +39,19 @@ require ( go.uber.org/zap v1.24.0 golang.org/x/net v0.8.0 golang.org/x/sync v0.1.0 - golang.org/x/text v0.8.0 + golang.org/x/text v0.9.0 ) require ( github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect - github.com/acomagu/bufpipe v1.0.3 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect + github.com/acomagu/bufpipe v1.0.4 // indirect github.com/cloudflare/circl v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-git/gcfg v1.5.0 // indirect - github.com/go-git/go-billy/v5 v5.4.0 // indirect + github.com/go-git/go-billy/v5 v5.4.1 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.13 // indirect @@ -67,6 +67,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/sergi/go-diff v1.1.0 // indirect + github.com/shoenig/go-m1cpu v0.1.4 // indirect github.com/skeema/knownhosts v1.1.0 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -76,7 +77,7 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect go.uber.org/multierr v1.8.0 // indirect - golang.org/x/crypto v0.3.0 // indirect + golang.org/x/crypto v0.6.0 // indirect golang.org/x/sys v0.6.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/utils/go.sum b/utils/go.sum index 2bebe45a65..5b314c0c77 100644 --- a/utils/go.sum +++ b/utils/go.sum @@ -42,10 +42,10 @@ github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VM github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I= -github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= -github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= -github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= +github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -100,12 +100,12 @@ github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4x github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-billy/v5 v5.4.0 h1:Vaw7LaSTRJOUric7pe4vnzBSgyuf2KrLsu2Y4ZpQBDE= -github.com/go-git/go-billy/v5 v5.4.0/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= +github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= +github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ= github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= -github.com/go-git/go-git/v5 v5.6.0 h1:JvBdYfcttd+0kdpuWO7KTu0FYgCf5W0t5VwkWGobaa4= -github.com/go-git/go-git/v5 v5.6.0/go.mod h1:6nmJ0tJ3N4noMV1Omv7rC5FG3/o8Cm51TB4CJp7mRmE= +github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk= +github.com/go-git/go-git/v5 v5.6.1/go.mod h1:mvyoL6Unz0PiTQrGQfSfiLFhBH1c1e84ylC2MDs4ee8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -260,8 +260,12 @@ github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71e github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil/v3 v3.23.2 h1:PAWSuiAszn7IhPMBtXsbSCafej7PqUOvY6YywlQUExU= -github.com/shirou/gopsutil/v3 v3.23.2/go.mod h1:gv0aQw33GLo3pG8SiWKiQrbDzbRY1K80RyZJ7V4Th1M= +github.com/shirou/gopsutil/v3 v3.23.3 h1:Syt5vVZXUDXPEXpIBt5ziWsJ4LdSAAxF4l/xZeQgSEE= +github.com/shirou/gopsutil/v3 v3.23.3/go.mod h1:lSBNN6t3+D6W5e5nXTxc8KIMMVxAcS+6IJlffjRRlMU= +github.com/shoenig/go-m1cpu v0.1.4 h1:SZPIgRM2sEF9NJy50mRHu9PKGwxyyTTJIWvCtgVbozs= +github.com/shoenig/go-m1cpu v0.1.4/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ= +github.com/shoenig/test v0.6.3 h1:GVXWJFk9PiOjN0KoJ7VrJGH6uLPnqxR7/fe3HUPfE0c= +github.com/shoenig/test v0.6.3/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= @@ -338,8 +342,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -412,7 +416,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -501,7 +506,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -512,8 +517,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/utils/mocks/mock_config.go b/utils/mocks/mock_config.go index 74e744e739..01e37b05c9 100644 --- a/utils/mocks/mock_config.go +++ b/utils/mocks/mock_config.go @@ -4,7 +4,7 @@ */ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ARM-software/golang-utils/utils/config (interfaces: IServiceConfiguration) +// Source: github.com/ARM-software/golang-utils/utils/config (interfaces: IServiceConfiguration,Validator) // Package mocks is a generated GoMock package. package mocks @@ -51,3 +51,40 @@ func (mr *MockIServiceConfigurationMockRecorder) Validate() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validate", reflect.TypeOf((*MockIServiceConfiguration)(nil).Validate)) } + +// MockValidator is a mock of Validator interface. +type MockValidator struct { + ctrl *gomock.Controller + recorder *MockValidatorMockRecorder +} + +// MockValidatorMockRecorder is the mock recorder for MockValidator. +type MockValidatorMockRecorder struct { + mock *MockValidator +} + +// NewMockValidator creates a new mock instance. +func NewMockValidator(ctrl *gomock.Controller) *MockValidator { + mock := &MockValidator{ctrl: ctrl} + mock.recorder = &MockValidatorMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockValidator) EXPECT() *MockValidatorMockRecorder { + return m.recorder +} + +// Validate mocks base method. +func (m *MockValidator) Validate() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Validate") + ret0, _ := ret[0].(error) + return ret0 +} + +// Validate indicates an expected call of Validate. +func (mr *MockValidatorMockRecorder) Validate() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validate", reflect.TypeOf((*MockValidator)(nil).Validate)) +} diff --git a/utils/module.properties b/utils/module.properties index 2ca2f96361..3f61535fee 100644 --- a/utils/module.properties +++ b/utils/module.properties @@ -1,5 +1,5 @@ -Version=1.29.0 +Version=1.31.0 MajorVersion=1 -MinorVersion=29 +MinorVersion=31 PatchVersion=0 -CommitHash=570052eeb22e74b1fbab63dc302733bc0f2a5c6a \ No newline at end of file +CommitHash=815be0624b8243f8ace0b0ba3da73307e0c5449a \ No newline at end of file