@@ -4,8 +4,12 @@ import (
4
4
"bytes"
5
5
"encoding/json"
6
6
"fmt"
7
+ "regexp"
8
+ "strconv"
7
9
)
8
10
11
+ var headerNameRegex = regexp .MustCompile (`^httpHeaderName(\d+)$` )
12
+
9
13
// DataSource represents a Grafana data source.
10
14
type DataSource struct {
11
15
ID int64 `json:"id,omitempty"`
@@ -28,16 +32,46 @@ type DataSource struct {
28
32
// Deprecated: Use secureJsonData.basicAuthPassword instead.
29
33
BasicAuthPassword string `json:"basicAuthPassword,omitempty"`
30
34
35
+ // Helper to read/write http headers
36
+ HTTPHeaders map [string ]string `json:"-"`
37
+
31
38
JSONData JSONData `json:"jsonData,omitempty"`
32
39
SecureJSONData SecureJSONData `json:"secureJsonData,omitempty"`
33
40
}
34
41
42
+ // Required to avoid recursion during (un)marshal
43
+ type _DataSource DataSource
44
+
45
+ // Marshal DataSource
46
+ func (ds * DataSource ) MarshalJSON () ([]byte , error ) {
47
+ dataSource := _DataSource (* ds )
48
+ for name , value := range ds .HTTPHeaders {
49
+ dataSource .JSONData .httpHeaderNames = append (dataSource .JSONData .httpHeaderNames , name )
50
+ dataSource .SecureJSONData .httpHeaderValues = append (dataSource .SecureJSONData .httpHeaderValues , value )
51
+ }
52
+ return json .Marshal (dataSource )
53
+ }
54
+
55
+ // Unmarshal DataSource
56
+ func (ds * DataSource ) UnmarshalJSON (b []byte ) (err error ) {
57
+ dataSource := _DataSource (* ds )
58
+ if err = json .Unmarshal (b , & dataSource ); err == nil {
59
+ * ds = DataSource (dataSource )
60
+ }
61
+ ds .HTTPHeaders = make (map [string ]string )
62
+ for _ , value := range ds .JSONData .httpHeaderNames {
63
+ ds .HTTPHeaders [value ] = "true" // HTTP Headers are not returned by the API
64
+ }
65
+ return err
66
+ }
67
+
35
68
// JSONData is a representation of the datasource `jsonData` property
36
69
type JSONData struct {
37
70
// Used by all datasources
38
71
TLSAuth bool `json:"tlsAuth,omitempty"`
39
72
TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"`
40
73
TLSSkipVerify bool `json:"tlsSkipVerify,omitempty"`
74
+ httpHeaderNames []string
41
75
42
76
// Used by Graphite
43
77
GraphiteVersion string `json:"graphiteVersion,omitempty"`
@@ -97,6 +131,57 @@ type JSONData struct {
97
131
SigV4Region string `json:"sigV4Region,omitempty"`
98
132
}
99
133
134
+ // Required to avoid recursion during (un)marshal
135
+ type _JSONData JSONData
136
+
137
+ // Marshal JSONData
138
+ func (jd JSONData ) MarshalJSON () ([]byte , error ) {
139
+ jsonData := _JSONData (jd )
140
+ b , err := json .Marshal (jsonData )
141
+ if err != nil {
142
+ return nil , err
143
+ }
144
+ fields := make (map [string ]interface {})
145
+ if err = json .Unmarshal (b , & fields ); err != nil {
146
+ return nil , err
147
+ }
148
+ for index , name := range jd .httpHeaderNames {
149
+ fields [fmt .Sprintf ("httpHeaderName%d" , index + 1 )] = name
150
+ }
151
+ return json .Marshal (fields )
152
+ }
153
+
154
+ // Unmarshal JSONData
155
+ func (jd * JSONData ) UnmarshalJSON (b []byte ) (err error ) {
156
+ jsonData := _JSONData (* jd )
157
+ if err = json .Unmarshal (b , & jsonData ); err == nil {
158
+ * jd = JSONData (jsonData )
159
+ }
160
+ fields := make (map [string ]interface {})
161
+ if err = json .Unmarshal (b , & fields ); err == nil {
162
+ headerCount := 0
163
+ for name := range fields {
164
+ match := headerNameRegex .FindStringSubmatch (name )
165
+ if len (match ) > 0 {
166
+ headerCount ++
167
+ }
168
+ }
169
+
170
+ jd .httpHeaderNames = make ([]string , headerCount )
171
+ for name , value := range fields {
172
+ match := headerNameRegex .FindStringSubmatch (name )
173
+ if len (match ) == 2 {
174
+ index , err := strconv .ParseInt (match [1 ], 10 , 64 )
175
+ if err != nil {
176
+ return err
177
+ }
178
+ jd .httpHeaderNames [index - 1 ] = value .(string )
179
+ }
180
+ }
181
+ }
182
+ return err
183
+ }
184
+
100
185
// SecureJSONData is a representation of the datasource `secureJsonData` property
101
186
type SecureJSONData struct {
102
187
// Used by all datasources
@@ -105,6 +190,7 @@ type SecureJSONData struct {
105
190
TLSClientKey string `json:"tlsClientKey,omitempty"`
106
191
Password string `json:"password,omitempty"`
107
192
BasicAuthPassword string `json:"basicAuthPassword,omitempty"`
193
+ httpHeaderValues []string
108
194
109
195
// Used by Cloudwatch
110
196
AccessKey string `json:"accessKey,omitempty"`
@@ -118,6 +204,26 @@ type SecureJSONData struct {
118
204
SigV4SecretKey string `json:"sigV4SecretKey,omitempty"`
119
205
}
120
206
207
+ // Required to avoid recursion during unmarshal
208
+ type _SecureJSONData SecureJSONData
209
+
210
+ // Marshal SecureJSONData
211
+ func (sjd SecureJSONData ) MarshalJSON () ([]byte , error ) {
212
+ secureJSONData := _SecureJSONData (sjd )
213
+ b , err := json .Marshal (secureJSONData )
214
+ if err != nil {
215
+ return nil , err
216
+ }
217
+ fields := make (map [string ]interface {})
218
+ if err = json .Unmarshal (b , & fields ); err != nil {
219
+ return nil , err
220
+ }
221
+ for index , value := range sjd .httpHeaderValues {
222
+ fields [fmt .Sprintf ("httpHeaderValue%d" , index + 1 )] = value
223
+ }
224
+ return json .Marshal (fields )
225
+ }
226
+
121
227
// NewDataSource creates a new Grafana data source.
122
228
func (c * Client ) NewDataSource (s * DataSource ) (int64 , error ) {
123
229
data , err := json .Marshal (s )
0 commit comments