This commit is contained in:
Alec Sears
2019-10-18 16:02:23 -05:00
parent ca145c9acb
commit e153473421
13 changed files with 6490 additions and 962 deletions

View File

@@ -1,6 +1,7 @@
package main
import (
"encoding/json"
"errors"
"fmt"
@@ -37,10 +38,11 @@ func (b *ZabbixBackend) Query(ctx context.Context, tsdbReq *datasource.Datasourc
switch queryType {
case "zabbixAPI":
return zabbixDs.ZabbixAPIQuery(ctx, tsdbReq)
case "zabbixConnectionTest":
case "connectionTest":
return zabbixDs.TestConnection(ctx, tsdbReq)
default:
return nil, errors.New("Query is not implemented yet")
err = errors.New("Query not implemented")
return BuildErrorResponse(err), nil
}
}
@@ -73,3 +75,32 @@ func GetQueryType(tsdbReq *datasource.DatasourceRequest) (string, error) {
}
return queryType, nil
}
// BuildResponse transforms a Zabbix API response to a DatasourceResponse
func BuildResponse(responseData interface{}) (*datasource.DatasourceResponse, error) {
jsonBytes, err := json.Marshal(responseData)
if err != nil {
return nil, err
}
return &datasource.DatasourceResponse{
Results: []*datasource.QueryResult{
&datasource.QueryResult{
RefId: "zabbixAPI",
MetaJson: string(jsonBytes),
},
},
}, nil
}
// BuildErrorResponse creates a QueryResult that forwards an error to the front-end
func BuildErrorResponse(err error) *datasource.DatasourceResponse {
return &datasource.DatasourceResponse{
Results: []*datasource.QueryResult{
&datasource.QueryResult{
RefId: "zabbixAPI",
Error: err.Error(),
},
},
}
}

View File

@@ -3,10 +3,12 @@ package main
import (
"testing"
simplejson "github.com/bitly/go-simplejson"
"github.com/grafana/grafana_plugin_model/go/datasource"
hclog "github.com/hashicorp/go-hclog"
cache "github.com/patrickmn/go-cache"
"gotest.tools/assert"
"gotest.tools/assert/cmp"
)
func TestZabbixBackend_getCachedDatasource(t *testing.T) {
@@ -79,3 +81,63 @@ func TestZabbixBackend_getCachedDatasource(t *testing.T) {
})
}
}
func TestBuildResponse(t *testing.T) {
jsonData := simplejson.New()
jsonData.Set("testing", []int{5, 12, 75})
tests := []struct {
name string
responseData interface{}
want *datasource.DatasourceResponse
wantErr string
}{
{
name: "simplejson Response",
responseData: jsonData,
want: &datasource.DatasourceResponse{
Results: []*datasource.QueryResult{
&datasource.QueryResult{
RefId: "zabbixAPI",
MetaJson: `{"testing":[5,12,75]}`,
},
},
},
},
{
name: "Connetion Status Response",
responseData: connectionTestResponse{
ZabbixVersion: "2.4",
DbConnectorStatus: &dbConnectionStatus{
DsType: "mysql",
DsName: "MyDatabase",
},
},
want: &datasource.DatasourceResponse{
Results: []*datasource.QueryResult{
&datasource.QueryResult{
RefId: "zabbixAPI",
MetaJson: `{"zabbixVersion":"2.4","dbConnectorStatus":{"dsType":"mysql","dsName":"MyDatabase"}}`,
},
},
},
},
{
name: "Unmarshalable",
responseData: 2i,
wantErr: "json: unsupported type: complex128",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := BuildResponse(tt.responseData)
if tt.wantErr != "" {
assert.Error(t, err, tt.wantErr)
assert.Assert(t, cmp.Nil(got))
return
}
assert.NilError(t, err)
assert.DeepEqual(t, got, tt.want)
})
}
}

View File

@@ -110,7 +110,7 @@ func (ds *ZabbixDatasource) ZabbixAPIQuery(ctx context.Context, tsdbReq *datasou
resultByte, _ := result.(*simplejson.Json).MarshalJSON()
ds.logger.Debug("ZabbixAPIQuery", "result", string(resultByte))
return ds.BuildResponse(result)
return BuildResponse(result)
}
// TestConnection checks authentication and version of the Zabbix API and returns that info
@@ -119,14 +119,14 @@ func (ds *ZabbixDatasource) TestConnection(ctx context.Context, tsdbReq *datasou
auth, err := ds.loginWithDs(ctx, dsInfo)
if err != nil {
return nil, err
return BuildErrorResponse(fmt.Errorf("Authentication failed: %w", err)), nil
}
ds.authToken = auth
response, err := ds.zabbixAPIRequest(ctx, dsInfo.GetUrl(), "apiinfo.version", map[string]interface{}{}, "")
if err != nil {
ds.logger.Debug("TestConnection", "error", err)
return nil, err
return BuildErrorResponse(fmt.Errorf("Version check failed: %w", err)), nil
}
resultByte, _ := response.MarshalJSON()
@@ -136,24 +136,7 @@ func (ds *ZabbixDatasource) TestConnection(ctx context.Context, tsdbReq *datasou
ZabbixVersion: response.MustString(),
}
return ds.BuildResponse(testResponse)
}
// BuildResponse transforms a Zabbix API response to a DatasourceResponse
func (ds *ZabbixDatasource) BuildResponse(responseData interface{}) (*datasource.DatasourceResponse, error) {
jsonBytes, err := json.Marshal(responseData)
if err != nil {
return nil, err
}
return &datasource.DatasourceResponse{
Results: []*datasource.QueryResult{
&datasource.QueryResult{
RefId: "zabbixAPI",
MetaJson: string(jsonBytes),
},
},
}, nil
return BuildResponse(testResponse)
}
// ZabbixRequest checks authentication and makes a request to the Zabbix API

View File

@@ -1,71 +1 @@
package main
import (
"testing"
simplejson "github.com/bitly/go-simplejson"
"github.com/grafana/grafana_plugin_model/go/datasource"
"gotest.tools/assert"
"gotest.tools/assert/cmp"
)
func TestZabbixDatasource_BuildResponse(t *testing.T) {
jsonData := simplejson.New()
jsonData.Set("testing", []int{5, 12, 75})
tests := []struct {
name string
responseData interface{}
want *datasource.DatasourceResponse
wantErr string
}{
{
name: "simplejson Response",
responseData: jsonData,
want: &datasource.DatasourceResponse{
Results: []*datasource.QueryResult{
&datasource.QueryResult{
RefId: "zabbixAPI",
MetaJson: `{"testing":[5,12,75]}`,
},
},
},
},
{
name: "Connetion Status Response",
responseData: connectionTestResponse{
ZabbixVersion: "2.4",
DbConnectorStatus: &dbConnectionStatus{
DsType: "mysql",
DsName: "MyDatabase",
},
},
want: &datasource.DatasourceResponse{
Results: []*datasource.QueryResult{
&datasource.QueryResult{
RefId: "zabbixAPI",
MetaJson: `{"zabbixVersion":"2.4","dbConnectorStatus":{"dsType":"mysql","dsName":"MyDatabase"}}`,
},
},
},
},
{
name: "Unmarshalable",
responseData: 2i,
wantErr: "json: unsupported type: complex128",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ds := NewZabbixDatasource()
got, err := ds.BuildResponse(tt.responseData)
if tt.wantErr != "" {
assert.Error(t, err, tt.wantErr)
assert.Assert(t, cmp.Nil(got))
return
}
assert.NilError(t, err)
assert.DeepEqual(t, got, tt.want)
})
}
}