Skip to content

Commit 6fff856

Browse files
authored
feat: Initial support for Dashboards v3 (#46)
1 parent 6d8b71a commit 6fff856

File tree

8 files changed

+885
-0
lines changed

8 files changed

+885
-0
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/draios/terraform-provider-sysdig
33
go 1.12
44

55
require (
6+
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
67
github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.3
78
github.com/spf13/cast v1.3.1
89
)

sysdig/helpers.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package sysdig
2+
3+
import (
4+
"fmt"
5+
"github.com/hashicorp/go-cty/cty"
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
)
9+
10+
// Temporary wrapper for validate functions.
11+
//
12+
// Deprecated: use your own functions, this wrapper will be removed as
13+
// soon as the new validate functions are supported by the SDK
14+
func validateDiagFunc(validateFunc func(interface{}, string) ([]string, []error)) schema.SchemaValidateDiagFunc {
15+
return func(i interface{}, path cty.Path) diag.Diagnostics {
16+
warnings, errs := validateFunc(i, fmt.Sprintf("%+v", path))
17+
var diags diag.Diagnostics
18+
for _, warning := range warnings {
19+
diags = append(diags, diag.Diagnostic{
20+
Severity: diag.Warning,
21+
Summary: warning,
22+
})
23+
}
24+
for _, err := range errs {
25+
diags = append(diags, diag.Diagnostic{
26+
Severity: diag.Error,
27+
Summary: err.Error(),
28+
})
29+
}
30+
return diags
31+
}
32+
}

sysdig/monitor/client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ type SysdigMonitorClient interface {
2525
GetNotificationChannelByName(context.Context, string) (NotificationChannel, error)
2626
DeleteNotificationChannel(context.Context, int) error
2727
UpdateNotificationChannel(context.Context, NotificationChannel) (NotificationChannel, error)
28+
29+
GetDashboardByID(context.Context, int) (Dashboard, error)
30+
CreateDashboard(context.Context, Dashboard) (Dashboard, error)
31+
UpdateDashboard(context.Context, Dashboard) (Dashboard, error)
32+
DeleteDashboard(context.Context, int) error
2833
}
2934

3035
func WithExtraHeaders(client SysdigMonitorClient, extraHeaders map[string]string) SysdigMonitorClient {

sysdig/monitor/dashboards.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package monitor
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"io/ioutil"
7+
"net/http"
8+
)
9+
10+
func (client *sysdigMonitorClient) GetDashboardByID(ctx context.Context, ID int) (Dashboard, error) {
11+
res, err := client.doSysdigMonitorRequest(ctx, http.MethodGet, client.getDashboardUrl(ID), nil)
12+
if err != nil {
13+
return Dashboard{}, err
14+
}
15+
defer res.Body.Close()
16+
17+
body, err := ioutil.ReadAll(res.Body)
18+
if err != nil {
19+
return Dashboard{}, nil
20+
}
21+
22+
if res.StatusCode != http.StatusOK {
23+
return Dashboard{}, fmt.Errorf(string(body))
24+
}
25+
26+
return DashboardFromJSON(body), nil
27+
}
28+
29+
func (client *sysdigMonitorClient) CreateDashboard(ctx context.Context, dashboard Dashboard) (Dashboard, error) {
30+
res, err := client.doSysdigMonitorRequest(ctx, http.MethodPost, client.getDashboardsUrl(), dashboard.ToJSON())
31+
if err != nil {
32+
return Dashboard{}, err
33+
}
34+
defer res.Body.Close()
35+
36+
body, err := ioutil.ReadAll(res.Body)
37+
if err != nil {
38+
return Dashboard{}, err
39+
}
40+
41+
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated {
42+
return Dashboard{}, fmt.Errorf(string(body))
43+
}
44+
45+
return DashboardFromJSON(body), nil
46+
}
47+
48+
func (client *sysdigMonitorClient) UpdateDashboard(ctx context.Context, dashboard Dashboard) (Dashboard, error) {
49+
res, err := client.doSysdigMonitorRequest(ctx, http.MethodPut, client.getDashboardUrl(dashboard.ID), dashboard.ToJSON())
50+
if err != nil {
51+
return Dashboard{}, err
52+
}
53+
defer res.Body.Close()
54+
55+
body, err := ioutil.ReadAll(res.Body)
56+
if err != nil {
57+
return Dashboard{}, err
58+
}
59+
60+
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated {
61+
return Dashboard{}, fmt.Errorf(string(body))
62+
}
63+
64+
return DashboardFromJSON(body), nil
65+
}
66+
67+
func (client *sysdigMonitorClient) DeleteDashboard(ctx context.Context, ID int) error {
68+
res, err := client.doSysdigMonitorRequest(ctx, http.MethodDelete, client.getDashboardUrl(ID), nil)
69+
if err != nil {
70+
return err
71+
}
72+
defer res.Body.Close()
73+
74+
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusNoContent {
75+
body, err := ioutil.ReadAll(res.Body)
76+
if err != nil {
77+
return err
78+
}
79+
80+
return fmt.Errorf(string(body))
81+
}
82+
83+
return nil
84+
}
85+
86+
func (client *sysdigMonitorClient) getDashboardsUrl() string {
87+
return fmt.Sprintf("%s/api/v3/dashboards", client.URL)
88+
}
89+
90+
func (client *sysdigMonitorClient) getDashboardUrl(id int) string {
91+
return fmt.Sprintf("%s/api/v3/dashboards/%d", client.URL, id)
92+
}

sysdig/monitor/models.go

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,221 @@ type notificationChannelListWrapper struct {
203203
type notificationChannelWrapper struct {
204204
NotificationChannel NotificationChannel `json:"notificationChannel"`
205205
}
206+
207+
// ---- Dashboards -----
208+
209+
type Layout struct {
210+
X int `json:"x"`
211+
Y int `json:"y"`
212+
W int `json:"w"`
213+
H int `json:"h"`
214+
PanelID int `json:"panelId"`
215+
}
216+
type QueryParams struct {
217+
Severities []interface{} `json:"severities"`
218+
AlertStatuses []interface{} `json:"alertStatuses"`
219+
Categories []interface{} `json:"categories"`
220+
Filter string `json:"filter"`
221+
TeamScope bool `json:"teamScope"`
222+
}
223+
type EventDisplaySettings struct {
224+
Enabled bool `json:"enabled"`
225+
QueryParams QueryParams `json:"queryParams"`
226+
}
227+
type Bottom struct {
228+
Enabled bool `json:"enabled"`
229+
}
230+
type Left struct {
231+
Enabled bool `json:"enabled"`
232+
DisplayName interface{} `json:"displayName"`
233+
Unit string `json:"unit"`
234+
DisplayFormat string `json:"displayFormat"`
235+
Decimals interface{} `json:"decimals"`
236+
MinValue int `json:"minValue"`
237+
MaxValue interface{} `json:"maxValue"`
238+
MinInputFormat string `json:"minInputFormat"`
239+
MaxInputFormat string `json:"maxInputFormat"`
240+
Scale string `json:"scale"`
241+
}
242+
type Right struct {
243+
Enabled bool `json:"enabled"`
244+
DisplayName interface{} `json:"displayName"`
245+
Unit string `json:"unit"`
246+
DisplayFormat string `json:"displayFormat"`
247+
Decimals interface{} `json:"decimals"`
248+
MinValue int `json:"minValue"`
249+
MaxValue interface{} `json:"maxValue"`
250+
MinInputFormat string `json:"minInputFormat"`
251+
MaxInputFormat string `json:"maxInputFormat"`
252+
Scale string `json:"scale"`
253+
}
254+
type AxesConfiguration struct {
255+
Bottom Bottom `json:"bottom"`
256+
Left Left `json:"left"`
257+
Right Right `json:"right"`
258+
}
259+
type LegendConfiguration struct {
260+
Enabled bool `json:"enabled"`
261+
Position string `json:"position"`
262+
Layout string `json:"layout"`
263+
ShowCurrent bool `json:"showCurrent"`
264+
Width interface{} `json:"width"`
265+
Height interface{} `json:"height"`
266+
}
267+
type DisplayInfo struct {
268+
DisplayName string `json:"displayName"`
269+
TimeSeriesDisplayNameTemplate string `json:"timeSeriesDisplayNameTemplate"`
270+
Type string `json:"type"`
271+
Color string `json:"color,omitempty"`
272+
LineWidth int `json:"lineWidth,omitempty"`
273+
}
274+
type Format struct {
275+
Unit string `json:"unit"`
276+
InputFormat string `json:"inputFormat"`
277+
DisplayFormat string `json:"displayFormat"`
278+
Decimals interface{} `json:"decimals"`
279+
YAxis string `json:"yAxis"`
280+
}
281+
282+
func NewPercentFormat() Format {
283+
return Format{
284+
Unit: "%",
285+
InputFormat: "0-100",
286+
DisplayFormat: "auto",
287+
Decimals: nil,
288+
YAxis: "auto",
289+
}
290+
}
291+
292+
func NewDataFormat() Format {
293+
return Format{
294+
Unit: "byte",
295+
InputFormat: "B",
296+
DisplayFormat: "auto",
297+
Decimals: nil,
298+
YAxis: "auto",
299+
}
300+
}
301+
302+
func NewDataRateFormat() Format {
303+
return Format{
304+
Unit: "byteRate",
305+
InputFormat: "B/s",
306+
DisplayFormat: "auto",
307+
Decimals: nil,
308+
YAxis: "auto",
309+
}
310+
}
311+
312+
func NewNumberFormat() Format {
313+
return Format{
314+
Unit: "number",
315+
InputFormat: "1",
316+
DisplayFormat: "auto",
317+
Decimals: nil,
318+
YAxis: "auto",
319+
}
320+
}
321+
322+
func NewNumberRateFormat() Format {
323+
return Format{
324+
Unit: "numberRate",
325+
InputFormat: "/s",
326+
DisplayFormat: "auto",
327+
Decimals: nil,
328+
YAxis: "auto",
329+
}
330+
}
331+
332+
func NewTimeFormat() Format {
333+
return Format{
334+
Unit: "relativeTime",
335+
InputFormat: "ns",
336+
DisplayFormat: "auto",
337+
Decimals: nil,
338+
YAxis: "auto",
339+
}
340+
}
341+
342+
type AdvancedQueries struct {
343+
Enabled bool `json:"enabled"`
344+
DisplayInfo DisplayInfo `json:"displayInfo"`
345+
Format Format `json:"format"`
346+
Query string `json:"query"`
347+
ID int `json:"id"`
348+
}
349+
type Panels struct {
350+
ID int `json:"id"`
351+
Name string `json:"name"`
352+
Description string `json:"description"`
353+
AxesConfiguration AxesConfiguration `json:"axesConfiguration"`
354+
LegendConfiguration LegendConfiguration `json:"legendConfiguration"`
355+
ApplyScopeToAll bool `json:"applyScopeToAll"`
356+
ApplySegmentationToAll bool `json:"applySegmentationToAll"`
357+
AdvancedQueries []AdvancedQueries `json:"advancedQueries"`
358+
NumberThresholds NumberThresholds `json:"numberThresholds"`
359+
MarkdownSource interface{} `json:"markdownSource"`
360+
PanelTitleVisible bool `json:"panelTitleVisible"`
361+
TextAutosized bool `json:"textAutosized"`
362+
TransparentBackground bool `json:"transparentBackground"`
363+
Type string `json:"type"`
364+
}
365+
366+
type NumberThresholds struct {
367+
Base Base `json:"base"`
368+
Values []interface{} `json:"values"`
369+
}
370+
371+
type Base struct {
372+
DisplayText string `json:"displayText"`
373+
Severity string `json:"severity"`
374+
}
375+
376+
type TeamSharingOptions struct {
377+
Type string `json:"type"`
378+
UserTeamsRole string `json:"userTeamsRole"`
379+
SelectedTeams []interface{} `json:"selectedTeams"`
380+
}
381+
type Dashboard struct {
382+
Version int `json:"version,omitempty"`
383+
CustomerID interface{} `json:"customerId"`
384+
TeamID int `json:"teamId"`
385+
Schema int `json:"schema"`
386+
AutoCreated bool `json:"autoCreated"`
387+
PublicToken string `json:"publicToken"`
388+
ScopeExpressionList interface{} `json:"scopeExpressionList"`
389+
Layout []Layout `json:"layout"`
390+
TeamScope interface{} `json:"teamScope"`
391+
EventDisplaySettings EventDisplaySettings `json:"eventDisplaySettings"`
392+
ID int `json:"id,omitempty"`
393+
Name string `json:"name"`
394+
Description string `json:"description"`
395+
Username string `json:"username"`
396+
Shared bool `json:"shared"`
397+
SharingSettings []interface{} `json:"sharingSettings"`
398+
Public bool `json:"public"`
399+
Favorite bool `json:"favorite"`
400+
CreatedOn int64 `json:"createdOn"`
401+
ModifiedOn int64 `json:"modifiedOn"`
402+
Panels []Panels `json:"panels"`
403+
TeamScopeExpressionList []interface{} `json:"teamScopeExpressionList"`
404+
CreatedOnDate string `json:"createdOnDate"`
405+
ModifiedOnDate string `json:"modifiedOnDate"`
406+
TeamSharingOptions TeamSharingOptions `json:"teamSharingOptions"`
407+
}
408+
409+
type dashboardWrapper struct {
410+
Dashboard Dashboard `json:"dashboard"`
411+
}
412+
413+
func (db *Dashboard) ToJSON() io.Reader {
414+
payload, _ := json.Marshal(dashboardWrapper{*db})
415+
return bytes.NewBuffer(payload)
416+
}
417+
418+
func DashboardFromJSON(body []byte) Dashboard {
419+
var result dashboardWrapper
420+
json.Unmarshal(body, &result)
421+
422+
return result.Dashboard
423+
}

sysdig/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ func Provider() *schema.Provider {
7373
"sysdig_monitor_alert_event": resourceSysdigMonitorAlertEvent(),
7474
"sysdig_monitor_alert_anomaly": resourceSysdigMonitorAlertAnomaly(),
7575
"sysdig_monitor_alert_group_outlier": resourceSysdigMonitorAlertGroupOutlier(),
76+
"sysdig_monitor_dashboard": resourceSysdigMonitorDashboard(),
7677
"sysdig_monitor_notification_channel_email": resourceSysdigMonitorNotificationChannelEmail(),
7778
"sysdig_monitor_notification_channel_opsgenie": resourceSysdigMonitorNotificationChannelOpsGenie(),
7879
"sysdig_monitor_notification_channel_pagerduty": resourceSysdigMonitorNotificationChannelPagerduty(),

0 commit comments

Comments
 (0)