215 lines
5.2 KiB
Go
215 lines
5.2 KiB
Go
package stacks
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
|
|
"github.com/influxdata/influx-cli/v2/api"
|
|
"github.com/influxdata/influx-cli/v2/clients"
|
|
"github.com/influxdata/influx-cli/v2/pkg/template"
|
|
)
|
|
|
|
type Client struct {
|
|
clients.CLI
|
|
api.StacksApi
|
|
api.OrganizationsApi
|
|
api.TemplatesApi
|
|
}
|
|
|
|
type ListParams struct {
|
|
clients.OrgParams
|
|
|
|
StackIds []string
|
|
StackNames []string
|
|
}
|
|
|
|
func (c Client) List(ctx context.Context, params *ListParams) error {
|
|
orgId, err := params.GetOrgID(ctx, c.ActiveConfig, c.OrganizationsApi)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
res, err := c.ListStacks(ctx).OrgID(orgId).Name(params.StackNames).StackID(params.StackIds).Execute()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to list stacks: %w", err)
|
|
}
|
|
|
|
return c.printStacks(stackPrintOptions{stacks: res.Stacks})
|
|
}
|
|
|
|
type InitParams struct {
|
|
clients.OrgParams
|
|
|
|
Name string
|
|
Description string
|
|
URLs []string
|
|
}
|
|
|
|
func (c Client) Init(ctx context.Context, params *InitParams) error {
|
|
orgId, err := params.GetOrgID(ctx, c.ActiveConfig, c.OrganizationsApi)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
req := api.StackPostRequest{
|
|
OrgID: orgId,
|
|
Name: params.Name,
|
|
Urls: params.URLs,
|
|
}
|
|
if params.Description != "" {
|
|
req.Description = ¶ms.Description
|
|
}
|
|
|
|
stack, err := c.CreateStack(ctx).StackPostRequest(req).Execute()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create stack %q: %w", params.Name, err)
|
|
}
|
|
|
|
return c.printStacks(stackPrintOptions{stack: &stack})
|
|
}
|
|
|
|
type RemoveParams struct {
|
|
clients.OrgParams
|
|
|
|
Ids []string
|
|
Force bool
|
|
}
|
|
|
|
func (c Client) Remove(ctx context.Context, params *RemoveParams) error {
|
|
orgId, err := params.GetOrgID(ctx, c.ActiveConfig, c.OrganizationsApi)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
stacks, err := c.ListStacks(ctx).OrgID(orgId).StackID(params.Ids).Execute()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to look up stacks: %w", err)
|
|
}
|
|
|
|
for _, stack := range stacks.Stacks {
|
|
if err := c.printStacks(stackPrintOptions{stack: &stack}); err != nil {
|
|
return err
|
|
}
|
|
if !params.Force && !c.StdIO.GetConfirm(fmt.Sprintf("Confirm removal of the stack[%s] and all associated resources", stack.Id)) {
|
|
continue
|
|
}
|
|
if err := c.DeleteStack(ctx, stack.Id).OrgID(orgId).Execute(); err != nil {
|
|
return fmt.Errorf("failed to delete stack %q: %w", stack.Id, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type AddedResource struct {
|
|
Kind string
|
|
Id string
|
|
}
|
|
|
|
type UpdateParams struct {
|
|
Id string
|
|
|
|
Name *string
|
|
Description *string
|
|
URLs []string
|
|
AddedResources []AddedResource
|
|
|
|
template.OutParams
|
|
}
|
|
|
|
func (c Client) Update(ctx context.Context, params *UpdateParams) error {
|
|
req := api.StackPatchRequest{
|
|
Name: params.Name,
|
|
Description: params.Description,
|
|
TemplateURLs: params.URLs,
|
|
AdditionalResources: make([]api.StackPatchRequestResource, len(params.AddedResources)),
|
|
}
|
|
for i, r := range params.AddedResources {
|
|
req.AdditionalResources[i] = api.StackPatchRequestResource{
|
|
ResourceID: r.Id,
|
|
Kind: r.Kind,
|
|
}
|
|
}
|
|
|
|
stack, err := c.UpdateStack(ctx, params.Id).StackPatchRequest(req).Execute()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to update stack %q: %w", params.Id, err)
|
|
}
|
|
if err := c.printStacks(stackPrintOptions{stack: &stack}); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Can skip exporting the updated template if no resources were added.
|
|
if len(params.AddedResources) == 0 {
|
|
return nil
|
|
}
|
|
|
|
if !c.StdIO.GetConfirm(`Your stack now differs from your template. Applying an outdated template will revert these updates.
|
|
Export a new template with these updates to prevent accidental changes?`) {
|
|
return nil
|
|
}
|
|
|
|
exportReq := api.TemplateExport{StackID: &stack.Id}
|
|
tmpl, err := c.ExportTemplate(ctx).TemplateExport(exportReq).Execute()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to export stack %q: %w", stack.Id, err)
|
|
}
|
|
if err := params.OutParams.WriteTemplate(tmpl); err != nil {
|
|
return fmt.Errorf("failed to write exported template: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type stackPrintOptions struct {
|
|
stack *api.Stack
|
|
stacks []api.Stack
|
|
}
|
|
|
|
func (c Client) printStacks(options stackPrintOptions) error {
|
|
if c.PrintAsJSON {
|
|
var v interface{}
|
|
if options.stack != nil {
|
|
v = options.stack
|
|
} else {
|
|
v = options.stacks
|
|
}
|
|
return c.PrintJSON(v)
|
|
}
|
|
|
|
headers := []string{"ID", "OrgID", "Active", "Name", "Description", "Num Resources", "Sources", "URLs", "Created At", "Updated At"}
|
|
stacks := options.stacks
|
|
if options.stack != nil {
|
|
stacks = append(stacks, *options.stack)
|
|
}
|
|
|
|
var rows []map[string]interface{}
|
|
for _, s := range stacks {
|
|
var latestEvent api.StackEvent
|
|
if len(s.Events) > 0 {
|
|
sort.Slice(s.Events, func(i, j int) bool {
|
|
return s.Events[i].UpdatedAt.Before(s.Events[j].UpdatedAt)
|
|
})
|
|
latestEvent = s.Events[len(s.Events)-1]
|
|
}
|
|
var desc string
|
|
if latestEvent.Description != nil {
|
|
desc = *latestEvent.Description
|
|
}
|
|
row := map[string]interface{}{
|
|
"ID": s.Id,
|
|
"OrgID": s.OrgID,
|
|
"Active": latestEvent.EventType != "uninstall",
|
|
"Name": latestEvent.Name,
|
|
"Description": desc,
|
|
"Num Resources": len(latestEvent.Resources),
|
|
"Sources": latestEvent.Sources,
|
|
"URLs": latestEvent.Urls,
|
|
"Created At": s.CreatedAt,
|
|
"Updated At": latestEvent.UpdatedAt,
|
|
}
|
|
rows = append(rows, row)
|
|
}
|
|
return c.PrintTable(headers, rows...)
|
|
}
|