Skip to content

Commit

Permalink
refactor: change structure of domains v1 commands
Browse files Browse the repository at this point in the history
  • Loading branch information
Integralist committed Jan 21, 2025
1 parent 66bdc9d commit 78f2bfc
Show file tree
Hide file tree
Showing 7 changed files with 284 additions and 5 deletions.
15 changes: 14 additions & 1 deletion pkg/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/fastly/cli/pkg/commands/dictionary"
"github.com/fastly/cli/pkg/commands/dictionaryentry"
"github.com/fastly/cli/pkg/commands/domain"
"github.com/fastly/cli/pkg/commands/domainv1"
"github.com/fastly/cli/pkg/commands/healthcheck"
"github.com/fastly/cli/pkg/commands/install"
"github.com/fastly/cli/pkg/commands/ip"
Expand Down Expand Up @@ -86,7 +87,7 @@ import (
)

// Define constructs all the commands exposed by the CLI.
func Define(
func Define( // nolint:revive // function-length
app *kingpin.Application,
data *global.Data,
) []argparser.Command {
Expand Down Expand Up @@ -186,6 +187,12 @@ func Define(
domainList := domain.NewListCommand(domainCmdRoot.CmdClause, data)
domainUpdate := domain.NewUpdateCommand(domainCmdRoot.CmdClause, data)
domainValidate := domain.NewValidateCommand(domainCmdRoot.CmdClause, data)
domainv1CmdRoot := domainv1.NewRootCommand(app, data)
domainv1Create := domainv1.NewCreateCommand(domainv1CmdRoot.CmdClause, data)
domainv1Delete := domainv1.NewDeleteCommand(domainv1CmdRoot.CmdClause, data)
domainv1Describe := domainv1.NewDescribeCommand(domainv1CmdRoot.CmdClause, data)
domainv1List := domainv1.NewListCommand(domainv1CmdRoot.CmdClause, data)
domainv1Update := domainv1.NewUpdateCommand(domainv1CmdRoot.CmdClause, data)
healthcheckCmdRoot := healthcheck.NewRootCommand(app, data)
healthcheckCreate := healthcheck.NewCreateCommand(healthcheckCmdRoot.CmdClause, data)
healthcheckDelete := healthcheck.NewDeleteCommand(healthcheckCmdRoot.CmdClause, data)
Expand Down Expand Up @@ -578,6 +585,12 @@ func Define(
domainList,
domainUpdate,
domainValidate,
domainv1CmdRoot,
domainv1Create,
domainv1Delete,
domainv1Describe,
domainv1List,
domainv1Update,
healthcheckCmdRoot,
healthcheckCreate,
healthcheckDelete,
Expand Down
4 changes: 0 additions & 4 deletions pkg/commands/domain/enums.go

This file was deleted.

40 changes: 40 additions & 0 deletions pkg/commands/domainv1/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package domainv1

import (
"fmt"
"io"

v1 "github.com/fastly/go-fastly/v9/fastly/domains/v1"

"github.com/fastly/cli/pkg/text"
)

// printSummary displays the information returned from the API in a summarised
// format.
func printSummary(out io.Writer, data []v1.Data) {
t := text.NewTable(out)
t.AddHeader("FQDN", "DOMAIN ID", "SERVICE ID", "CREATED AT", "UPDATED AT")
for _, d := range data {
var sid string
if d.ServiceID != nil {
sid = *d.ServiceID
}
t.AddLine(d.FQDN, d.DomainID, sid, d.CreatedAt, d.UpdatedAt)
}
t.Print()
}

// printSummary displays the information returned from the API in a verbose
// format.
func printVerbose(out io.Writer, data []v1.Data) {
for _, d := range data {
fmt.Fprintf(out, "FQDN: %s\n", d.FQDN)
fmt.Fprintf(out, "Domain ID: %s\n", d.DomainID)
if d.ServiceID != nil {
fmt.Fprintf(out, "Service ID: %s\n", *d.ServiceID)
}
fmt.Fprintf(out, "Created at: %s\n", d.CreatedAt)
fmt.Fprintf(out, "Updated at: %s\n", d.UpdatedAt)
fmt.Fprintf(out, "\n")
}
}
75 changes: 75 additions & 0 deletions pkg/commands/domainv1/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package domainv1

import (
"errors"
"fmt"
"io"

"github.com/fastly/go-fastly/v9/fastly"
v1 "github.com/fastly/go-fastly/v9/fastly/domains/v1"

"github.com/fastly/cli/pkg/argparser"
"github.com/fastly/cli/pkg/global"
"github.com/fastly/cli/pkg/text"
)

// CreateCommand calls the Fastly API to create domains.
type CreateCommand struct {
argparser.Base

// Required.
fqdn string
serviceID string
}

// NewCreateCommand returns a usable command registered under the parent.
func NewCreateCommand(parent argparser.Registerer, g *global.Data) *CreateCommand {
c := CreateCommand{
Base: argparser.Base{
Globals: g,
},
}
c.CmdClause = parent.Command("create", "Create a domain").Alias("add")

// Optional.
c.CmdClause.Flag("fqdn", "The fully qualified domain name").Required().StringVar(&c.fqdn)
c.RegisterFlag(argparser.StringFlagOpts{
Name: argparser.FlagServiceIDName,
Description: "The service_id associated with your domain",
Dst: &c.serviceID,
Short: 's',
})
return &c
}

// Exec invokes the application logic for the command.
func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error {
input := &v1.CreateInput{
FQDN: &c.fqdn,
}
if c.serviceID != "" {
input.ServiceID = &c.serviceID
}

fc, ok := c.Globals.APIClient.(*fastly.Client)
if !ok {
return errors.New("failed to convert interface to a fastly client")
}

d, err := v1.Create(fc, input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]any{
"FQDN": c.fqdn,
"Service ID": c.serviceID,
})
return err
}

serviceOutput := ""
if d.ServiceID != nil {
serviceOutput = fmt.Sprintf(" (service-id: %s)", *d.ServiceID)
}

text.Success(out, "Created domain '%s' (domain-id: %s)%s", d.FQDN, d.DomainID, serviceOutput)
return nil
}
2 changes: 2 additions & 0 deletions pkg/commands/domainv1/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package domain contains commands to inspect and manipulate Fastly domains.
package domainv1
122 changes: 122 additions & 0 deletions pkg/commands/domainv1/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package domainv1

import (
"errors"
"io"

"github.com/fastly/go-fastly/v9/fastly"
v1 "github.com/fastly/go-fastly/v9/fastly/domains/v1"

"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"
)

// ListCommand calls the Fastly API to list domains.
type ListCommand struct {
argparser.Base
argparser.JSONOutput

cursor argparser.OptionalString
fqdn argparser.OptionalString
limit argparser.OptionalInt
serviceID argparser.OptionalString
sort argparser.OptionalString
}

// NewListCommand returns a usable command registered under the parent.
func NewListCommand(parent argparser.Registerer, g *global.Data) *ListCommand {
c := ListCommand{
Base: argparser.Base{
Globals: g,
},
}
c.CmdClause = parent.Command("list", "List domains")

// Optional.
c.CmdClause.Flag("cursor", "Cursor value from the next_cursor field of a previous response, used to retrieve the next page").Action(c.cursor.Set).StringVar(&c.cursor.Value)
c.CmdClause.Flag("fqdn", "Filters results by the FQDN using a fuzzy/partial match").Action(c.fqdn.Set).StringVar(&c.fqdn.Value)
c.RegisterFlagBool(c.JSONFlag()) // --json
c.CmdClause.Flag("limit", "Limit how many results are returned").Action(c.limit.Set).IntVar(&c.limit.Value)
c.RegisterFlag(argparser.StringFlagOpts{
Action: c.serviceID.Set,
Name: argparser.FlagServiceIDName,
Description: "Filter results based on a service_id",
Dst: &c.serviceID.Value,
Short: 's',
})
c.CmdClause.Flag("sort", "The order in which to list the results").Action(c.sort.Set).StringVar(&c.sort.Value)
return &c
}

// Exec invokes the application logic for the command.
func (c *ListCommand) Exec(in io.Reader, out io.Writer) error {
if c.Globals.Verbose() && c.JSONOutput.Enabled {
return fsterr.ErrInvalidVerboseJSONCombo
}

input := &v1.ListInput{}

if c.serviceID.WasSet {
input.ServiceID = &c.serviceID.Value
}
if c.cursor.WasSet {
input.Cursor = &c.cursor.Value
}
if c.fqdn.WasSet {
input.FQDN = &c.fqdn.Value
}
if c.limit.WasSet {
input.Limit = &c.limit.Value
}
if c.sort.WasSet {
input.Sort = &c.sort.Value
}

fc, ok := c.Globals.APIClient.(*fastly.Client)
if !ok {
return errors.New("failed to convert interface to a fastly client")
}

for {
cl, err := v1.List(fc, input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]any{
"Cursor": c.cursor.Value,
"FQDN": c.fqdn.Value,
"Limit": c.limit.Value,
"Service ID": c.serviceID.Value,
"Sort": c.sort.Value,
})
return err
}

if ok, err := c.WriteJSON(out, cl); ok {
// No pagination prompt w/ JSON output.
return err
}

if c.Globals.Verbose() {
printVerbose(out, cl.Data)
} else {
printSummary(out, cl.Data)
}

if cl != nil && cl.Meta.NextCursor != "" {
// Check if 'out' is interactive before prompting.
if !c.Globals.Flags.NonInteractive && !c.Globals.Flags.AutoYes && text.IsTTY(out) {
printNext, err := text.AskYesNo(out, "Print next page [y/N]: ", in)
if err != nil {
return err
}
if printNext {
input.Cursor = &cl.Meta.NextCursor
continue
}
}
}

return nil
}
}
31 changes: 31 additions & 0 deletions pkg/commands/domainv1/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package domainv1

import (
"io"

"github.com/fastly/cli/pkg/argparser"
"github.com/fastly/cli/pkg/global"
)

// RootCommand is the parent command for all subcommands in this package.
// It should be installed under the primary root command.
type RootCommand struct {
argparser.Base
// no flags
}

// CommandName is the string to be used to invoke this command.
const CommandName = "domain-v1"

// NewRootCommand returns a new command registered in the parent.
func NewRootCommand(parent argparser.Registerer, g *global.Data) *RootCommand {
var c RootCommand
c.Globals = g
c.CmdClause = parent.Command(CommandName, "Manipulate Fastly domains")
return &c
}

// Exec implements the command interface.
func (c *RootCommand) Exec(_ io.Reader, _ io.Writer) error {
panic("unreachable")
}

0 comments on commit 78f2bfc

Please sign in to comment.