@@ -3,7 +3,10 @@ package gapi
33import (
44 "bytes"
55 "encoding/json"
6+ "errors"
67 "fmt"
8+ "regexp"
9+ "strconv"
710)
811
912// DataSource represents a Grafana data source.
@@ -27,16 +30,52 @@ type DataSource struct {
2730 // Deprecated: Use secureJsonData.basicAuthPassword instead.
2831 BasicAuthPassword string `json:"basicAuthPassword,omitempty"`
2932
33+ // Helper to read/write http headers
34+ HTTPHeaders map [string ]string `json:"-"`
35+
3036 JSONData JSONData `json:"jsonData,omitempty"`
3137 SecureJSONData SecureJSONData `json:"secureJsonData,omitempty"`
3238}
3339
40+ // Required to avoid recursion during (un)marshal
41+ type _DataSource DataSource
42+
43+ // Marshal DataSource
44+ func (ds * DataSource ) MarshalJSON () ([]byte , error ) {
45+ var index int64
46+ dataSource := _DataSource (* ds )
47+ dataSource .JSONData .httpHeaderNames = make (map [int64 ]string , len (ds .HTTPHeaders ))
48+ dataSource .SecureJSONData .httpHeaderValues = make (map [int64 ]string , len (ds .HTTPHeaders ))
49+ for name , value := range ds .HTTPHeaders {
50+ dataSource .JSONData .httpHeaderNames [index ] = name
51+ dataSource .SecureJSONData .httpHeaderValues [index ] = value
52+ index ++
53+ }
54+ return json .Marshal (dataSource )
55+ }
56+
57+ // Unmarshal DataSource
58+ func (ds * DataSource ) UnmarshalJSON (b []byte ) (err error ) {
59+ dataSource := _DataSource (* ds )
60+ if err = json .Unmarshal (b , & dataSource ); err == nil {
61+ * ds = DataSource (dataSource )
62+ }
63+ if len (ds .JSONData .httpHeaderNames ) != len (ds .SecureJSONData .httpHeaderValues ) {
64+ return errors .New ("HTTP headers names length doesn't match HTTP header values length" )
65+ }
66+ for index , value := range ds .JSONData .httpHeaderNames {
67+ ds .HTTPHeaders [value ] = ds .SecureJSONData .httpHeaderValues [index ]
68+ }
69+ return err
70+ }
71+
3472// JSONData is a representation of the datasource `jsonData` property
3573type JSONData struct {
3674 // Used by all datasources
3775 TLSAuth bool `json:"tlsAuth,omitempty"`
3876 TLSAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"`
3977 TLSSkipVerify bool `json:"tlsSkipVerify,omitempty"`
78+ httpHeaderNames map [int64 ]string
4079
4180 // Used by Graphite
4281 GraphiteVersion string `json:"graphiteVersion,omitempty"`
@@ -95,6 +134,49 @@ type JSONData struct {
95134 SigV4Region string `json:"sigV4Region,omitempty"`
96135}
97136
137+ // Required to avoid recursion during (un)marshal
138+ type _JSONData JSONData
139+
140+ // Marshal JSONData
141+ func (jd JSONData ) MarshalJSON () ([]byte , error ) {
142+ jsonData := _JSONData (jd )
143+ b , err := json .Marshal (jsonData )
144+ if err != nil {
145+ return nil , err
146+ }
147+ fields := make (map [string ]interface {})
148+ if err = json .Unmarshal (b , & fields ); err != nil {
149+ return nil , err
150+ }
151+ for index , name := range jd .httpHeaderNames {
152+ fields [fmt .Sprintf ("httpHeaderName%d" , index + 1 )] = name
153+ }
154+ return json .Marshal (fields )
155+ }
156+
157+ // Unmarshal JSONData
158+ func (jd * JSONData ) UnmarshalJSON (b []byte ) (err error ) {
159+ jsonData := _JSONData (* jd )
160+ if err = json .Unmarshal (b , & jsonData ); err == nil {
161+ * jd = JSONData (jsonData )
162+ }
163+ fields := make (map [string ]interface {})
164+ if err = json .Unmarshal (b , & fields ); err == nil {
165+ for name , value := range fields {
166+ re := regexp .MustCompile ("httpHeaderName([0-9]+)" )
167+ match := re .FindStringSubmatch (name )
168+ if len (match ) == 1 {
169+ index , err := strconv .ParseInt (match [0 ], 10 , 64 )
170+ if err != nil {
171+ return err
172+ }
173+ jd .httpHeaderNames [index - 1 ] = value .(string )
174+ }
175+ }
176+ }
177+ return err
178+ }
179+
98180// SecureJSONData is a representation of the datasource `secureJsonData` property
99181type SecureJSONData struct {
100182 // Used by all datasources
@@ -103,6 +185,7 @@ type SecureJSONData struct {
103185 TLSClientKey string `json:"tlsClientKey,omitempty"`
104186 Password string `json:"password,omitempty"`
105187 BasicAuthPassword string `json:"basicAuthPassword,omitempty"`
188+ httpHeaderValues map [int64 ]string
106189
107190 // Used by Cloudwatch
108191 AccessKey string `json:"accessKey,omitempty"`
@@ -116,6 +199,26 @@ type SecureJSONData struct {
116199 SigV4SecretKey string `json:"sigV4SecretKey,omitempty"`
117200}
118201
202+ // Required to avoid recursion during unmarshal
203+ type _SecureJSONData SecureJSONData
204+
205+ // Marshal SecureJSONData
206+ func (sjd SecureJSONData ) MarshalJSON () ([]byte , error ) {
207+ secureJSONData := _SecureJSONData (sjd )
208+ b , err := json .Marshal (secureJSONData )
209+ if err != nil {
210+ return nil , err
211+ }
212+ fields := make (map [string ]interface {})
213+ if err = json .Unmarshal (b , & fields ); err != nil {
214+ return nil , err
215+ }
216+ for index , value := range sjd .httpHeaderValues {
217+ fields [fmt .Sprintf ("httpHeaderValue%d" , index + 1 )] = value
218+ }
219+ return json .Marshal (fields )
220+ }
221+
119222// NewDataSource creates a new Grafana data source.
120223func (c * Client ) NewDataSource (s * DataSource ) (int64 , error ) {
121224 data , err := json .Marshal (s )
0 commit comments