-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dashboard): Add support for Observability custom dashboards. (#1357
) * Scaffold out custom dashboard base commands * Implement dashboard print funcs * Implement dashboard list command * Implement dashboard describe command * Implement dashboard delete command * Implement dashboard create command * Implement dashboard update command * Scaffold dashboard/item command package * Implement dashboard item create command * Implement dashboard item describe command * Implement dashboard item delete command * Implement dashboard item update command * Improve/fix JSON printing for dashboard commands * Update dashboard print funcs/commands to behave consistently with other resources * Add tests for dashboard commands * Fix app.Run test * Remove unnecessary mock fns * Add tests for dashboard item commands * Apply suggestions from code review Co-authored-by: Kevin P. Fleming <[email protected]> * Address feedback * gofmt * Fix linting errors * Fix dashboard item output assertions --------- Co-authored-by: Kevin P. Fleming <[email protected]>
- Loading branch information
Showing
21 changed files
with
1,663 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -68,6 +68,7 @@ compute | |
config | ||
config-store | ||
config-store-entry | ||
dashboard | ||
dictionary | ||
dictionary-entry | ||
domain | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Package common contains functions used by both dashboard and dashboard/item packages | ||
package common | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"strings" | ||
|
||
"github.com/fastly/go-fastly/v9/fastly" | ||
|
||
"github.com/fastly/cli/pkg/text" | ||
) | ||
|
||
// PrintSummary displays the information returned from the API in a summarised | ||
// format. | ||
func PrintSummary(out io.Writer, ds []fastly.ObservabilityCustomDashboard) { | ||
t := text.NewTable(out) | ||
t.AddHeader("DASHBOARD ID", "NAME", "DESCRIPTION", "# ITEMS") | ||
for _, d := range ds { | ||
t.AddLine( | ||
d.ID, | ||
d.Name, | ||
d.Description, | ||
len(d.Items), | ||
) | ||
} | ||
t.Print() | ||
} | ||
|
||
// PrintVerbose displays the information returned from the API in a verbose | ||
// format. | ||
func PrintVerbose(out io.Writer, ds []fastly.ObservabilityCustomDashboard) { | ||
for _, d := range ds { | ||
PrintDashboard(out, 0, &d) | ||
fmt.Fprintf(out, "\n") | ||
} | ||
} | ||
|
||
// PrintDashboard displays the Dashboard returned from the API in a human- | ||
// readable format. | ||
func PrintDashboard(out io.Writer, indent uint, dashboard *fastly.ObservabilityCustomDashboard) { | ||
indentStep := uint(4) | ||
level := indent | ||
text.Indent(out, level, "Name: %s", dashboard.Name) | ||
text.Indent(out, level, "Description: %s", dashboard.Description) | ||
text.Indent(out, level, "Items:") | ||
|
||
level += indentStep | ||
for i, di := range dashboard.Items { | ||
text.Indent(out, level, "[%d]:", i) | ||
level += indentStep | ||
PrintItem(out, level, &di) | ||
level -= indentStep | ||
} | ||
level -= indentStep | ||
|
||
text.Indent(out, level, "Meta:") | ||
level += indentStep | ||
text.Indent(out, level, "Created at: %s", dashboard.CreatedAt) | ||
text.Indent(out, level, "Updated at: %s", dashboard.UpdatedAt) | ||
text.Indent(out, level, "Created by: %s", dashboard.CreatedBy) | ||
text.Indent(out, level, "Updated by: %s", dashboard.UpdatedBy) | ||
} | ||
|
||
// PrintItem displays a single DashboardItem in a human-readable format. | ||
func PrintItem(out io.Writer, indent uint, item *fastly.DashboardItem) { | ||
indentStep := uint(4) | ||
level := indent | ||
if item != nil { | ||
text.Indent(out, level, "ID: %s", item.ID) | ||
text.Indent(out, level, "Title: %s", item.Title) | ||
text.Indent(out, level, "Subtitle: %s", item.Subtitle) | ||
text.Indent(out, level, "Span: %d", item.Span) | ||
|
||
text.Indent(out, level, "Data Source:") | ||
level += indentStep | ||
text.Indent(out, level, "Type: %s", item.DataSource.Type) | ||
text.Indent(out, level, "Metrics: %s", strings.Join(item.DataSource.Config.Metrics, ", ")) | ||
level -= indentStep | ||
|
||
text.Indent(out, level, "Visualization:") | ||
level += indentStep | ||
text.Indent(out, level, "Type: %s", item.Visualization.Type) | ||
text.Indent(out, level, "Plot Type: %s", item.Visualization.Config.PlotType) | ||
if item.Visualization.Config.CalculationMethod != nil { | ||
text.Indent(out, level, "Calculation Method: %s", *item.Visualization.Config.CalculationMethod) | ||
} | ||
if item.Visualization.Config.Format != nil { | ||
text.Indent(out, level, "Format: %s", *item.Visualization.Config.Format) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package dashboard | ||
|
||
import ( | ||
"io" | ||
|
||
"github.com/fastly/go-fastly/v9/fastly" | ||
|
||
"github.com/fastly/cli/pkg/argparser" | ||
fsterr "github.com/fastly/cli/pkg/errors" | ||
"github.com/fastly/cli/pkg/global" | ||
"github.com/fastly/cli/pkg/text" | ||
) | ||
|
||
// NewCreateCommand returns a usable command registered under the parent. | ||
func NewCreateCommand(parent argparser.Registerer, globals *global.Data) *CreateCommand { | ||
var c CreateCommand | ||
c.CmdClause = parent.Command("create", "Create a custom dashboard").Alias("add") | ||
c.Globals = globals | ||
|
||
// Required flags | ||
c.CmdClause.Flag("name", "A human-readable name for the dashboard").Short('n').Required().StringVar(&c.name) // --name | ||
|
||
// Optional flags | ||
c.RegisterFlagBool(c.JSONFlag()) // --json | ||
c.CmdClause.Flag("description", "A short description of the dashboard").Action(c.description.Set).StringVar(&c.description.Value) // --description | ||
|
||
return &c | ||
} | ||
|
||
// CreateCommand calls the Fastly API to create an appropriate resource. | ||
type CreateCommand struct { | ||
argparser.Base | ||
argparser.JSONOutput | ||
|
||
name string | ||
description argparser.OptionalString | ||
} | ||
|
||
// Exec invokes the application logic for the command. | ||
func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error { | ||
if c.Globals.Verbose() && c.JSONOutput.Enabled { | ||
return fsterr.ErrInvalidVerboseJSONCombo | ||
} | ||
|
||
input := c.constructInput() | ||
dashboard, err := c.Globals.APIClient.CreateObservabilityCustomDashboard(input) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if ok, err := c.WriteJSON(out, dashboard); ok { | ||
return err | ||
} | ||
|
||
text.Success(out, `Created Custom Dashboard "%s" (id: %s)`, dashboard.Name, dashboard.ID) | ||
return nil | ||
} | ||
|
||
// constructInput transforms values parsed from CLI flags into an object to be used by the API client library. | ||
func (c *CreateCommand) constructInput() *fastly.CreateObservabilityCustomDashboardInput { | ||
input := fastly.CreateObservabilityCustomDashboardInput{ | ||
Name: c.name, | ||
Items: []fastly.DashboardItem{}, | ||
} | ||
|
||
if c.description.WasSet { | ||
input.Description = &c.description.Value | ||
} | ||
|
||
return &input | ||
} |
Oops, something went wrong.