Skip to content

Commit

Permalink
feat(influx): add support for dashboards
Browse files Browse the repository at this point in the history
  • Loading branch information
jsteenb2 committed Aug 5, 2020
1 parent e82f2d9 commit efd82a2
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,7 @@

1. [19075](https://github.com/influxdata/influxdb/pull/19075): Add resource links to a stack's resources from public HTTP API list/read calls
1. [19103](https://github.com/influxdata/influxdb/pull/19103): Enhance resource creation experience when limits are reached
1. [19223](https://github.com/influxdata/influxdb/pull/19223): Add dashboards command to influx CLI

### Bug Fixes

Expand Down
154 changes: 154 additions & 0 deletions cmd/influx/dashboard.go
@@ -0,0 +1,154 @@
package main

import (
"context"

"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/cmd/influx/internal"
"github.com/influxdata/influxdb/v2/http"
"github.com/influxdata/influxdb/v2/tenant"
"github.com/spf13/cobra"
)

func cmdDashboard(f *globalFlags, opts genericCLIOpts) *cobra.Command {
return newCmdDashboardBuilder(newDashboardSVCs, f, opts).cmdDashboards()
}

type dashboardSVCsFn func() (influxdb.DashboardService, influxdb.OrganizationService, error)

type cmdDashboardBuilder struct {
genericCLIOpts
*globalFlags

svcFn dashboardSVCsFn

ids []string
org organization
}

func newCmdDashboardBuilder(svcFn dashboardSVCsFn, f *globalFlags, opts genericCLIOpts) *cmdDashboardBuilder {
return &cmdDashboardBuilder{
genericCLIOpts: opts,
globalFlags: f,
svcFn: svcFn,
}
}

func (b *cmdDashboardBuilder) cmdDashboards() *cobra.Command {
cmd := b.newCmd("dashboards", b.listRunE)
cmd.Short = "List Dashboard(s)."
cmd.Long = `
List Dashboard(s).
Examples:
# list all known Dashboards
influx dashboards
# list all known Dashboards matching ids
influx dashboards --id $ID1 --id $ID2
# list all known Dashboards matching ids shorts
influx dashboards -i $ID1 -i $ID2
`

b.org.register(cmd, false)
cmd.Flags().StringArrayVarP(&b.ids, "id", "i", nil, "Dashboard ID to retrieve.")

return cmd
}

func (b *cmdDashboardBuilder) listRunE(cmd *cobra.Command, args []string) error {
svc, orgSVC, err := b.svcFn()
if err != nil {
return err
}

orgID, _ := b.org.getID(orgSVC)
if orgID == 0 && len(b.ids) == 0 {
return &influxdb.Error{
Code: influxdb.EUnprocessableEntity,
Msg: "at least one of org, org-id, or id must be provided",
}
}

var ids []*influxdb.ID
for _, rawID := range b.ids {
id, err := influxdb.IDFromString(rawID)
if err != nil {
return err
}
ids = append(ids, id)
}

var (
out []*influxdb.Dashboard
offset int
)
const limit = 100
for {
dashboards, _, err := svc.FindDashboards(context.Background(), influxdb.DashboardFilter{
IDs: ids,
OrganizationID: &orgID,
}, influxdb.FindOptions{
Limit: limit,
Offset: offset,
})
if err != nil && influxdb.ErrorCode(err) != influxdb.ENotFound {
return err
}
out = append(out, dashboards...)
if len(dashboards) < limit {
break
}
offset += len(dashboards)
}

return b.writeDashboards(out...)
}

func (b *cmdDashboardBuilder) writeDashboards(dashboards ...*influxdb.Dashboard) error {
if b.json {
return b.writeJSON(dashboards)
}

tabW := b.newTabWriter()
defer tabW.Flush()

writeDashboardRows(tabW, dashboards...)
return nil
}

func writeDashboardRows(tabW *internal.TabWriter, dashboards ...*influxdb.Dashboard) {
tabW.WriteHeaders("ID", "OrgID", "Name", "Description", "Num Cells")
for _, d := range dashboards {
tabW.Write(map[string]interface{}{
"ID": d.ID,
"OrgID": d.OrganizationID.String(),
"Name": d.Name,
"Description": d.Description,
"Num Cells": len(d.Cells),
})
}
}

func (b *cmdDashboardBuilder) newCmd(use string, runE func(*cobra.Command, []string) error) *cobra.Command {
cmd := b.genericCLIOpts.newCmd(use, runE, true)
b.genericCLIOpts.registerPrintOptions(cmd)
b.globalFlags.registerFlags(cmd)
return cmd
}

func newDashboardSVCs() (influxdb.DashboardService, influxdb.OrganizationService, error) {
httpClient, err := newHTTPClient()
if err != nil {
return nil, nil, err
}

orgSVC := &tenant.OrgClientService{
Client: httpClient,
}
dashSVC := &http.DashboardService{
Client: httpClient,
}
return dashSVC, orgSVC, nil
}
1 change: 1 addition & 0 deletions cmd/influx/main.go
Expand Up @@ -293,6 +293,7 @@ func influxCmd(opts ...genericCLIOptFn) *cobra.Command {
cmdBackup,
cmdBucket,
cmdConfig,
cmdDashboard,
cmdDelete,
cmdExport,
cmdOrganization,
Expand Down
2 changes: 1 addition & 1 deletion cmd/influx/telegraf.go
Expand Up @@ -280,7 +280,7 @@ func writeTelegrafRows(tabW *internal.TabWriter, cfgs ...*influxdb.TelegrafConfi
for _, cfg := range cfgs {
tabW.Write(map[string]interface{}{
"ID": cfg.ID,
"OrgID": cfg.OrgID,
"OrgID": cfg.OrgID.String(),
"Name": cfg.Name,
"Description": cfg.Description,
})
Expand Down
2 changes: 1 addition & 1 deletion cmd/influxd/launcher/pkger_test.go
Expand Up @@ -3432,7 +3432,7 @@ spec:
}, varArgs.Values)
})

t.Run("error incurs during template application when resources already exist rollsback to prev state", func(t *testing.T) {
t.Run("error incurred during template application when resources already exist rollsback to prev state", func(t *testing.T) {
updatePkg, err := pkger.Parse(pkger.EncodingYAML, pkger.FromString(updatePkgYMLStr))
require.NoError(t, err)

Expand Down

0 comments on commit efd82a2

Please sign in to comment.