Skip to content

Commit bff0f1e

Browse files
authored
Merge pull request #15 from grafana/moreConfigFixes
More config fixes
2 parents 914f21b + 6bcc0ff commit bff0f1e

File tree

4 files changed

+85
-43
lines changed

4 files changed

+85
-43
lines changed

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ require (
77
github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc
88
github.com/kelseyhightower/envconfig v1.4.0
99
github.com/kubernetes/helm v2.9.0+incompatible
10-
github.com/mitchellh/mapstructure v1.1.2
1110
github.com/sirupsen/logrus v1.8.1
1211
github.com/stretchr/testify v1.7.0
1312
github.com/xdg/scram v1.0.3

pkg/kafka/config.go

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ package kafka
2323
import (
2424
"encoding/json"
2525
"errors"
26+
"fmt"
2627
"time"
2728

2829
"github.com/Shopify/sarama"
2930
"github.com/kelseyhightower/envconfig"
3031
"github.com/kubernetes/helm/pkg/strvals"
31-
"github.com/mitchellh/mapstructure"
3232
"gopkg.in/guregu/null.v3"
3333

3434
"go.k6.io/k6/lib/types"
@@ -54,24 +54,6 @@ type Config struct {
5454
InfluxDBConfig influxdbConfig `json:"influxdb"`
5555
}
5656

57-
// config is a duplicate of ConfigFields as we can not mapstructure.Decode into
58-
// null types so we duplicate the struct with primitive types to Decode into
59-
type config struct {
60-
Brokers []string `json:"brokers" mapstructure:"brokers" envconfig:"K6_KAFKA_BROKERS"`
61-
Topic string `json:"topic" mapstructure:"topic" envconfig:"K6_KAFKA_TOPIC"`
62-
Format string `json:"format" mapstructure:"format" envconfig:"K6_KAFKA_FORMAT"`
63-
PushInterval string `json:"pushInterval" mapstructure:"pushInterval" envconfig:"K6_KAFKA_PUSH_INTERVAL"`
64-
User string `json:"user" mapstructure:"user" envconfig:"K6_KAFKA_SASL_USER"`
65-
Password string `json:"password" mapstructure:"password" envconfig:"K6_KAFKA_SASL_PASSWORD"`
66-
AuthMechanism string `json:"authMechanism" mapstructure:"authMechanism" envconfig:"K6_KAFKA_AUTH_MECHANISM"`
67-
68-
InfluxDBConfig influxdbConfig `json:"influxdb" mapstructure:"influxdb"`
69-
Version string `json:"version" mapstructure:"version"`
70-
SSL bool `json:"ssl" mapstructure:"ssl"`
71-
Insecure bool `json:"insecureSkipTLSVerify" mapstructure:"insecure"`
72-
LogError bool `json:"logError" mapstructure:"logError"`
73-
}
74-
7557
// NewConfig creates a new Config instance with default values for some fields.
7658
func NewConfig() Config {
7759
return Config{
@@ -135,10 +117,6 @@ func ParseArg(arg string) (Config, error) {
135117
return c, err
136118
}
137119

138-
if v, ok := params["brokers"].(string); ok {
139-
params["brokers"] = []string{v}
140-
}
141-
142120
if v, ok := params["influxdb"].(map[string]interface{}); ok {
143121
influxConfig, err := influxdbParseMap(v)
144122
if err != nil {
@@ -154,49 +132,85 @@ func ParseArg(arg string) (Config, error) {
154132
if err != nil {
155133
return c, err
156134
}
135+
delete(params, "pushInterval")
157136
}
158137

159138
if v, ok := params["version"].(string); ok {
160139
c.Version = null.StringFrom(v)
140+
delete(params, "version")
161141
}
162142

163143
if v, ok := params["ssl"].(bool); ok {
164144
c.SSL = null.BoolFrom(v)
145+
delete(params, "ssl")
165146
}
166147

167148
if v, ok := params["insecureSkipTLSVerify"].(bool); ok {
168149
c.InsecureSkipTLSVerify = null.BoolFrom(v)
150+
delete(params, "insecureSkipTLSVerify")
169151
}
170152

171153
if v, ok := params["logError"].(bool); ok {
172154
c.LogError = null.BoolFrom(v)
155+
delete(params, "logError")
173156
}
174157

175158
if v, ok := params["authMechanism"].(string); ok {
176159
c.AuthMechanism = null.StringFrom(v)
160+
delete(params, "authMechanism")
177161
}
178162

179163
if v, ok := params["user"].(string); ok {
180164
c.User = null.StringFrom(v)
165+
delete(params, "user")
181166
}
182167

183168
if v, ok := params["password"].(string); ok {
184169
c.Password = null.StringFrom(v)
170+
delete(params, "password")
185171
}
172+
if v, ok := params["topic"].(string); ok {
173+
c.Topic = null.StringFrom(v)
174+
delete(params, "topic")
175+
}
176+
if v, ok := params["format"].(string); ok {
177+
c.Format = null.StringFrom(v)
186178

187-
var cfg config
188-
err = mapstructure.Decode(params, &cfg)
189-
if err != nil {
190-
return c, err
179+
delete(params, "format")
191180
}
192181

193-
c.Brokers = cfg.Brokers
194-
c.Topic = null.StringFrom(cfg.Topic)
195-
c.Format = null.StringFrom(cfg.Format)
182+
if v, ok := params["brokers"].(string); ok {
183+
c.Brokers = []string{v}
196184

185+
delete(params, "brokers")
186+
}
187+
if v, ok := params["brokers"].([]interface{}); ok {
188+
c.Brokers = interfaceSliceToStringSlice(v)
189+
delete(params, "brokers")
190+
}
191+
192+
if len(params) > 0 {
193+
return c, errors.New("Unknown or unparsed options '" + mapToString(params) + "'")
194+
}
197195
return c, nil
198196
}
199197

198+
func mapToString(m map[string]interface{}) string {
199+
var s string
200+
for k, v := range m {
201+
s += fmt.Sprintf("%s=%v,", k, v)
202+
}
203+
return s[:len(s)-1]
204+
}
205+
206+
func interfaceSliceToStringSlice(input []interface{}) []string {
207+
output := make([]string, len(input))
208+
for i, v := range input {
209+
output[i] = fmt.Sprintf("%v", v)
210+
}
211+
return output
212+
}
213+
200214
// GetConsolidatedConfig combines {default config values + JSON config +
201215
// environment vars + arg config values}, and returns the final result.
202216
func GetConsolidatedConfig(jsonRawConf json.RawMessage, env map[string]string, arg string) (Config, error) {

pkg/kafka/config_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ func TestConfigParseArg(t *testing.T) {
129129
assert.Equal(t, null.StringFrom("SASL_PLAINTEXT"), c.AuthMechanism)
130130
assert.Equal(t, null.StringFrom("johndoe"), c.User)
131131
assert.Equal(t, null.BoolFrom(false), c.LogError)
132+
133+
c, err = ParseArg("badOption=212")
134+
assert.Error(t, err)
135+
assert.Contains(t, err.Error(), `Unknown or unparsed options 'badOption=212'`)
136+
137+
c, err = ParseArg("ssl=nottrue")
138+
assert.Error(t, err)
139+
assert.Contains(t, err.Error(), `Unknown or unparsed options 'ssl=nottrue'`)
140+
141+
c, err = ParseArg("brokers={broker2,broker3:9092},topic=someTopic,format=influxdb,influxdb.tagsAsFields=fake,influxdb.something=else")
142+
assert.Error(t, err)
143+
assert.Contains(t, err.Error(), `Unknown or unparsed options 'something=else'`)
132144
}
133145

134146
func TestConsolidatedConfig(t *testing.T) {
@@ -256,6 +268,25 @@ func TestConsolidatedConfig(t *testing.T) {
256268
LogError: null.BoolFrom(false),
257269
},
258270
},
271+
"arg_over_env_with_brokers": {
272+
env: map[string]string{
273+
"K6_KAFKA_AUTH_MECHANISM": "none",
274+
"K6_KAFKA_LOG_ERROR": "false",
275+
"K6_KAFKA_BROKERS": "something",
276+
},
277+
arg: "logError=true",
278+
config: Config{
279+
Format: null.StringFrom("json"),
280+
PushInterval: types.NullDurationFrom(1 * time.Second),
281+
InfluxDBConfig: newInfluxdbConfig(),
282+
AuthMechanism: null.StringFrom("none"),
283+
Version: null.StringFrom(sarama.DefaultVersion.String()),
284+
SSL: null.BoolFrom(false),
285+
InsecureSkipTLSVerify: null.BoolFrom(false),
286+
LogError: null.BoolFrom(true),
287+
Brokers: []string{"something"},
288+
},
289+
},
259290
}
260291

261292
for name, testCase := range testCases {

pkg/kafka/format_influxdb.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@
2121
package kafka
2222

2323
import (
24+
"errors"
2425
"fmt"
2526
"strconv"
2627
"strings"
2728

2829
client "github.com/influxdata/influxdb1-client/v2"
29-
"github.com/mitchellh/mapstructure"
3030
"github.com/sirupsen/logrus"
31-
"go.k6.io/k6/lib/types"
3231
"go.k6.io/k6/stats"
3332
)
3433

@@ -172,18 +171,17 @@ func (c influxdbConfig) Apply(cfg influxdbConfig) influxdbConfig {
172171
func influxdbParseMap(m map[string]interface{}) (influxdbConfig, error) {
173172
c := influxdbConfig{}
174173
if v, ok := m["tagsAsFields"].(string); ok {
175-
m["tagsAsFields"] = []string{v}
174+
c.TagsAsFields = []string{v}
175+
delete(m, "tagsAsFields")
176176
}
177-
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
178-
DecodeHook: types.NullDecoder,
179-
Result: &c,
180-
})
181-
if err != nil {
182-
return c, err
177+
if v, ok := m["tagsAsFields"].([]interface{}); ok {
178+
c.TagsAsFields = interfaceSliceToStringSlice(v)
179+
delete(m, "tagsAsFields")
183180
}
184-
185-
err = dec.Decode(m)
186-
return c, err
181+
if len(m) > 0 {
182+
return c, errors.New("Unknown or unparsed options '" + mapToString(m) + "'")
183+
}
184+
return c, nil
187185
}
188186

189187
type influxdbConfig struct {

0 commit comments

Comments
 (0)