@@ -4,8 +4,12 @@ import (
44 "bytes"
55 "encoding/json"
66 "fmt"
7+ "regexp"
8+ "strconv"
79)
810
11+ var headerNameRegex = regexp .MustCompile (`^httpHeaderName(\d+)$` )
12+
913// DataSource represents a Grafana data source.
1014type DataSource struct {
1115 ID int64 `json:"id,omitempty"`
@@ -28,16 +32,46 @@ type DataSource struct {
2832 // Deprecated: Use secureJsonData.basicAuthPassword instead.
2933 BasicAuthPassword string `json:"basicAuthPassword,omitempty"`
3034
35+ // Helper to read/write http headers
36+ HTTPHeaders map [string ]string `json:"-"`
37+
3138 JSONData JSONData `json:"jsonData,omitempty"`
3239 SecureJSONData SecureJSONData `json:"secureJsonData,omitempty"`
3340}
3441
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+
3568// JSONData is a representation of the datasource `jsonData` property
3669type JSONData struct {
3770 // Used by all datasources
3871 TLSAuth bool `json:"tlsAuth,omitempty"`
3972 TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"`
4073 TLSSkipVerify bool `json:"tlsSkipVerify,omitempty"`
74+ httpHeaderNames []string
4175
4276 // Used by Graphite
4377 GraphiteVersion string `json:"graphiteVersion,omitempty"`
@@ -104,6 +138,57 @@ type JSONData struct {
104138 Implementation string `json:"implementation,omitempty"`
105139}
106140
141+ // Required to avoid recursion during (un)marshal
142+ type _JSONData JSONData
143+
144+ // Marshal JSONData
145+ func (jd JSONData ) MarshalJSON () ([]byte , error ) {
146+ jsonData := _JSONData (jd )
147+ b , err := json .Marshal (jsonData )
148+ if err != nil {
149+ return nil , err
150+ }
151+ fields := make (map [string ]interface {})
152+ if err = json .Unmarshal (b , & fields ); err != nil {
153+ return nil , err
154+ }
155+ for index , name := range jd .httpHeaderNames {
156+ fields [fmt .Sprintf ("httpHeaderName%d" , index + 1 )] = name
157+ }
158+ return json .Marshal (fields )
159+ }
160+
161+ // Unmarshal JSONData
162+ func (jd * JSONData ) UnmarshalJSON (b []byte ) (err error ) {
163+ jsonData := _JSONData (* jd )
164+ if err = json .Unmarshal (b , & jsonData ); err == nil {
165+ * jd = JSONData (jsonData )
166+ }
167+ fields := make (map [string ]interface {})
168+ if err = json .Unmarshal (b , & fields ); err == nil {
169+ headerCount := 0
170+ for name := range fields {
171+ match := headerNameRegex .FindStringSubmatch (name )
172+ if len (match ) > 0 {
173+ headerCount ++
174+ }
175+ }
176+
177+ jd .httpHeaderNames = make ([]string , headerCount )
178+ for name , value := range fields {
179+ match := headerNameRegex .FindStringSubmatch (name )
180+ if len (match ) == 2 {
181+ index , err := strconv .ParseInt (match [1 ], 10 , 64 )
182+ if err != nil {
183+ return err
184+ }
185+ jd .httpHeaderNames [index - 1 ] = value .(string )
186+ }
187+ }
188+ }
189+ return err
190+ }
191+
107192// SecureJSONData is a representation of the datasource `secureJsonData` property
108193type SecureJSONData struct {
109194 // Used by all datasources
@@ -112,6 +197,7 @@ type SecureJSONData struct {
112197 TLSClientKey string `json:"tlsClientKey,omitempty"`
113198 Password string `json:"password,omitempty"`
114199 BasicAuthPassword string `json:"basicAuthPassword,omitempty"`
200+ httpHeaderValues []string
115201
116202 // Used by Cloudwatch
117203 AccessKey string `json:"accessKey,omitempty"`
@@ -125,6 +211,26 @@ type SecureJSONData struct {
125211 SigV4SecretKey string `json:"sigV4SecretKey,omitempty"`
126212}
127213
214+ // Required to avoid recursion during unmarshal
215+ type _SecureJSONData SecureJSONData
216+
217+ // Marshal SecureJSONData
218+ func (sjd SecureJSONData ) MarshalJSON () ([]byte , error ) {
219+ secureJSONData := _SecureJSONData (sjd )
220+ b , err := json .Marshal (secureJSONData )
221+ if err != nil {
222+ return nil , err
223+ }
224+ fields := make (map [string ]interface {})
225+ if err = json .Unmarshal (b , & fields ); err != nil {
226+ return nil , err
227+ }
228+ for index , value := range sjd .httpHeaderValues {
229+ fields [fmt .Sprintf ("httpHeaderValue%d" , index + 1 )] = value
230+ }
231+ return json .Marshal (fields )
232+ }
233+
128234// NewDataSource creates a new Grafana data source.
129235func (c * Client ) NewDataSource (s * DataSource ) (int64 , error ) {
130236 data , err := json .Marshal (s )
0 commit comments