@@ -3,12 +3,15 @@ package remotewrite
3
3
import (
4
4
"crypto/tls"
5
5
"encoding/json"
6
+ "errors"
6
7
"fmt"
7
8
"net/http"
8
9
"strconv"
9
10
"strings"
10
11
"time"
11
12
13
+ "github.com/grafana/xk6-output-prometheus-remote/pkg/sigv4"
14
+
12
15
"github.com/grafana/xk6-output-prometheus-remote/pkg/remote"
13
16
"go.k6.io/k6/lib/types"
14
17
"gopkg.in/guregu/null.v3"
@@ -68,6 +71,15 @@ type Config struct {
68
71
TrendStats []string `json:"trendStats"`
69
72
70
73
StaleMarkers null.Bool `json:"staleMarkers"`
74
+
75
+ // SigV4Region is the AWS region where the workspace is.
76
+ SigV4Region null.String `json:"sigV4Region"`
77
+
78
+ // SigV4AccessKey is the AWS access key.
79
+ SigV4AccessKey null.String `json:"sigV4AccessKey"`
80
+
81
+ // SigV4SecretKey is the AWS secret key.
82
+ SigV4SecretKey null.String `json:"sigV4SecretKey"`
71
83
}
72
84
73
85
// NewConfig creates an Output's configuration.
@@ -81,6 +93,9 @@ func NewConfig() Config {
81
93
Headers : make (map [string ]string ),
82
94
TrendStats : defaultTrendStats ,
83
95
StaleMarkers : null .BoolFrom (false ),
96
+ SigV4Region : null .NewString ("" , false ),
97
+ SigV4AccessKey : null .NewString ("" , false ),
98
+ SigV4SecretKey : null .NewString ("" , false ),
84
99
}
85
100
}
86
101
@@ -110,6 +125,22 @@ func (conf Config) RemoteConfig() (*remote.HTTPConfig, error) {
110
125
hc .TLSConfig .Certificates = []tls.Certificate {cert }
111
126
}
112
127
128
+ if isSigV4PartiallyConfigured (conf .SigV4Region , conf .SigV4AccessKey , conf .SigV4SecretKey ) {
129
+ return nil , errors .New (
130
+ "sigv4 seems to be partially configured. All of " +
131
+ "K6_PROMETHEUS_RW_SIGV4_REGION, K6_PROMETHEUS_RW_SIGV4_ACCESS_KEY, K6_PROMETHEUS_RW_SIGV4_SECRET_KEY " +
132
+ "must all be set. Unset all to bypass sigv4" ,
133
+ )
134
+ }
135
+
136
+ if conf .SigV4Region .Valid && conf .SigV4AccessKey .Valid && conf .SigV4SecretKey .Valid {
137
+ hc .SigV4 = & sigv4.Config {
138
+ Region : conf .SigV4Region .String ,
139
+ AwsAccessKeyID : conf .SigV4AccessKey .String ,
140
+ AwsSecretAccessKey : conf .SigV4SecretKey .String ,
141
+ }
142
+ }
143
+
113
144
if len (conf .Headers ) > 0 {
114
145
hc .Headers = make (http.Header )
115
146
for k , v := range conf .Headers {
@@ -149,6 +180,18 @@ func (conf Config) Apply(applied Config) Config {
149
180
conf .BearerToken = applied .BearerToken
150
181
}
151
182
183
+ if applied .SigV4Region .Valid {
184
+ conf .SigV4Region = applied .SigV4Region
185
+ }
186
+
187
+ if applied .SigV4AccessKey .Valid {
188
+ conf .SigV4AccessKey = applied .SigV4AccessKey
189
+ }
190
+
191
+ if applied .SigV4SecretKey .Valid {
192
+ conf .SigV4SecretKey = applied .SigV4SecretKey
193
+ }
194
+
152
195
if applied .PushInterval .Valid {
153
196
conf .PushInterval = applied .PushInterval
154
197
}
@@ -299,6 +342,18 @@ func parseEnvs(env map[string]string) (Config, error) {
299
342
}
300
343
}
301
344
345
+ if sigV4Region , sigV4RegionDefined := env ["K6_PROMETHEUS_RW_SIGV4_REGION" ]; sigV4RegionDefined {
346
+ c .SigV4Region = null .StringFrom (sigV4Region )
347
+ }
348
+
349
+ if sigV4AccessKey , sigV4AccessKeyDefined := env ["K6_PROMETHEUS_RW_SIGV4_ACCESS_KEY" ]; sigV4AccessKeyDefined {
350
+ c .SigV4AccessKey = null .StringFrom (sigV4AccessKey )
351
+ }
352
+
353
+ if sigV4SecretKey , sigV4SecretKeyDefined := env ["K6_PROMETHEUS_RW_SIGV4_SECRET_KEY" ]; sigV4SecretKeyDefined {
354
+ c .SigV4SecretKey = null .StringFrom (sigV4SecretKey )
355
+ }
356
+
302
357
if b , err := envBool (env , "K6_PROMETHEUS_RW_TREND_AS_NATIVE_HISTOGRAM" ); err != nil {
303
358
return c , err
304
359
} else if b .Valid {
@@ -384,3 +439,12 @@ func parseArg(text string) (Config, error) {
384
439
385
440
return c , nil
386
441
}
442
+
443
+ func isSigV4PartiallyConfigured (region , accessKey , secretKey null.String ) bool {
444
+ hasRegion := region .Valid && len (strings .TrimSpace (region .String )) != 0
445
+ hasAccessID := accessKey .Valid && len (strings .TrimSpace (accessKey .String )) != 0
446
+ hasSecretAccessKey := secretKey .Valid && len (strings .TrimSpace (secretKey .String )) != 0
447
+ // either they are all set, or all not set. False if partial
448
+ isComplete := (hasRegion && hasAccessID && hasSecretAccessKey ) || (! hasRegion && ! hasAccessID && ! hasSecretAccessKey )
449
+ return ! isComplete
450
+ }
0 commit comments