github.com/yandex/pandora@v0.5.32/components/providers/scenario/config/config.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/spf13/afero" 8 grpcgun "github.com/yandex/pandora/components/guns/grpc/scenario" 9 httpscenario "github.com/yandex/pandora/components/guns/http_scenario" 10 "github.com/yandex/pandora/components/providers/scenario/http/preprocessor" 11 "github.com/yandex/pandora/components/providers/scenario/vs" 12 ) 13 14 // AmmoConfig is a config for dynamic converting from map[string]interface{} 15 type AmmoConfig struct { 16 Locals map[string]any 17 VariableSources []vs.VariableSource `config:"variable_sources"` 18 Requests []RequestConfig 19 Calls []CallConfig 20 Scenarios []ScenarioConfig 21 } 22 23 // ScenarioConfig is a config for dynamic converting from map[string]interface{} 24 type ScenarioConfig struct { 25 Name string 26 Weight int64 27 MinWaitingTime int64 `config:"min_waiting_time"` 28 Requests []string 29 } 30 31 // RequestConfig is a config for dynamic converting from map[string]interface{} 32 type RequestConfig struct { 33 Name string 34 Method string 35 Headers map[string]string 36 Tag string 37 Body *string 38 URI string 39 Preprocessor *preprocessor.Preprocessor 40 Postprocessors []httpscenario.Postprocessor 41 Templater httpscenario.Templater 42 } 43 44 type CallConfig struct { 45 Name string 46 Tag string 47 Call string 48 Payload string 49 Metadata map[string]string 50 Preprocessors []grpcgun.Preprocessor 51 Postprocessors []grpcgun.Postprocessor 52 } 53 54 func ReadAmmoConfig(fs afero.Fs, fileName string) (ammoCfg *AmmoConfig, err error) { 55 const op = "scenario.ReadAmmoConfig" 56 57 if fileName == "" { 58 return nil, fmt.Errorf("scenario provider config should contain non-empty 'file' field") 59 } 60 file, openErr := fs.Open(fileName) 61 if openErr != nil { 62 return nil, fmt.Errorf("%s %w", op, openErr) 63 } 64 defer func() { 65 closeErr := file.Close() 66 if closeErr != nil { 67 if err != nil { 68 err = fmt.Errorf("%s multiple errors faced: %w, with close err: %s", op, err, closeErr) 69 } else { 70 err = fmt.Errorf("%s, %w", op, closeErr) 71 } 72 } 73 }() 74 stat, statErr := file.Stat() 75 if statErr != nil { 76 err = fmt.Errorf("%s file.Stat() %w", op, err) 77 return 78 } 79 lowerName := strings.ToLower(stat.Name()) 80 switch { 81 case strings.HasSuffix(lowerName, ".hcl"): 82 ammoHcl, parseErr := ParseHCLFile(file) 83 if parseErr != nil { 84 err = fmt.Errorf("%s ParseHCLFile %w", op, parseErr) 85 return 86 } 87 ammoCfg, err = ConvertHCLToAmmo(ammoHcl) 88 case strings.HasSuffix(lowerName, ".yaml") || strings.HasPrefix(lowerName, ".yml"): 89 ammoCfg, err = ParseAmmoConfig(file) 90 default: 91 err = fmt.Errorf("%s file extension should be .yaml or .yml", op) 92 return 93 } 94 if err != nil { 95 err = fmt.Errorf("%s ParseAmmoConfig %w", op, err) 96 return 97 } 98 99 return ammoCfg, nil 100 }