8000 feat(domain discovery): add support for Domain Discovery commands by FarhanSajid1 · Pull Request #1482 · fastly/cli · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat(domain discovery): add support for Domain Discovery commands #1482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Jun 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a33c0d8
feat(domain discovery): add commands for domain discovery tools
FarhanSajid1 May 14, 2025
3174542
update fastly provider
FarhanSajid1 May 21, 2025
eaa6077
cleanup: add comments and rename variables
FarhanSajid1 May 21, 2025
0109e94
Merge branch 'main' into farhansajid1/domain-tools
FarhanSajid1 May 21, 2025
4f3526c
fix: add changelog, rename function, and update comments
FarhanSajid1 May 21, 2025
0307e07
fix: address PR feedback, clean error message, test inputs
FarhanSajid1 May 22, 2025
8aa1b0f
fix: gofmt file
FarhanSajid1 May 22, 2025
3d31eda
fix: update remediation to include better formatting for scope flag
FarhanSajid1 May 22, 2025
18936be
fix: address pr feedback
FarhanSajid1 May 29, 2025
cfbf53c
fix: use arg instead flag for required args
FarhanSajid1 May 29, 2025
d59e1e3
fix update query to include comma-separated
FarhanSajid1 May 29, 2025
6a7b767
fix: allow multiple positional arguments
FarhanSajid1 May 29, 2025
a6c27f3
fix: incorporate feedback on structuring of tools
FarhanSajid1 May 30, 2025
283cc6e
fix: update comment for domain suggestions command
FarhanSajid1 May 30, 2025
878df08
fix: update shell completion test
FarhanSajid1 May 30, 2025
f02c758
fix: remove extra space
FarhanSajid1 Jun 4, 2025
9ff773e
Update suggest.go
case-fastly Jun 4, 2025
efa50bf
merge upstream
FarhanSajid1 Jun 4, 2025
95e9503
Suggest subcommand: description text edits
case-fastly Jun 4, 2025
287aa93
Domain Discovery -> tools/domain
case-fastly Jun 6, 2025
6f5a5a3
fix: move client initialization after input validation
FarhanSajid1 Jun 9, 2025
5ddff13
Merge branch 'main' into farhansajid1/domain-tools
kpfleming Jun 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

### Enhancements:
- feat(config-store): Allow for dynamic limits on Config Store entry lengths [#1485](https://github.com/fastly/cli/pull/1485)

- feat(backend): Add support for 'prefer IPv6' attribute. ([#1487](https://github.com/fastly/cli/pull/1487))
- feat(tools/domain): add `suggest` and `status` domain tools endpoints ([#1482](https://github.com/fastly/cli/pull/1482))

### Bug fixes:

Expand Down
1 change: 1 addition & 0 deletions pkg/app/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ tls-config
tls-custom
tls-platform
tls-subscription
tools
update
user
vcl
Expand Down
10 changes: 10 additions & 0 deletions pkg/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ import (
tlscustomprivatekey "github.com/fastly/cli/pkg/commands/tls/custom/privatekey"
tlsplatform "github.com/fastly/cli/pkg/commands/tls/platform"
tlssubscription "github.com/fastly/cli/pkg/commands/tls/subscription"
"github.com/fastly/cli/pkg/commands/tools"
domainTools "github.com/fastly/cli/pkg/commands/tools/domain"
"github.com/fastly/cli/pkg/commands/update"
"github.com/fastly/cli/pkg/commands/user"
"github.com/fastly/cli/pkg/commands/vcl"
Expand Down Expand Up @@ -486,6 +488,10 @@ func Define( // nolint:revive // function-length
tlsSubscriptionDescribe := tlssubscription.NewDescribeCommand(tlsSubscriptionCmdRoot.CmdClause, data)
tlsSubscriptionList := tlssubscription.NewListCommand(tlsSubscriptionCmdRoot.CmdClause, data)
tlsSubscriptionUpdate := tlssubscription.NewUpdateCommand(tlsSubscriptionCmdRoot.CmdClause, data)
toolsCmdRoot := tools.NewRootCommand(app, data)
toolsDomainCmdRoot := domainTools.NewRootCommand(toolsCmdRoot.CmdClause, data)
toolsDomainStatus := domainTools.NewDomainStatusCommand(toolsDomainCmdRoot.CmdClause, data)
toolsDomainSuggestions := domainTools.NewDomainSuggestionsCommand(toolsDomainCmdRoot.CmdClause, data)
updateRoot := update.NewRootCommand(app, data)
userCmdRoot := user.NewRootCommand(app, data)
userCreate := user.NewCreateCommand(userCmdRoot.CmdClause, data)
Expand Down Expand Up @@ -895,6 +901,10 @@ func Define( // nolint:revive // function-length
tlsSubscriptionDescribe,
tlsSubscriptionList,
tlsSubscriptionUpdate,
toolsCmdRoot,
toolsDomainCmdRoot,
toolsDomainStatus,
toolsDomainSuggestions,
updateRoot,
userCmdRoot,
userCreate,
Expand Down
2 changes: 2 additions & 0 deletions pkg/commands/tools/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package tools contains tools for working with the Fastly platform.
package tools
2 changes: 2 additions & 0 deletions pkg/commands/tools/domain/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package domain contains Domain Discovery API tools.
package domain
31 changes: 31 additions & 0 deletions pkg/commands/tools/domain/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package domain

import (
"io"

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

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

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

// NewRootCommand returns a new tools 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, "Domain Discovery API tools")
return &c
}

// Exec implements the command interface.
func (c *RootCommand) Exec(_ io.Reader, _ io.Writer) error {
panic("unreachable")
}
102 changes: 102 additions & 0 deletions pkg/commands/tools/domain/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package domain

import (
"errors"
"fmt"
"io"

"github.com/fastly/cli/pkg/argparser"
fsterr "github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/global"
"github.com/fastly/go-fastly/v10/fastly"
"github.com/fastly/go-fastly/v10/fastly/domains/v1/tools/status"
)

// GetDomainStatusCommand calls the Fastly API to check the availability of a domain name.
type GetDomainStatusCommand struct {
argparser.Base
argparser.JSONOutput
// Required.
domain string
// Optional.
scope argparser.OptionalString
}

// NewDomainStatusCommand returns a usable DomainStatusCommand registered under the parent.
func NewDomainStatusCommand(parent argparser.Registerer, g *global.Data) *GetDomainStatusCommand {
cmd := GetDomainStatusCommand{
Base: argparser.Base{
Globals: g,
},
}

cmd.CmdClause = parent.Command("status", "Check domain name availability")
// Required.
cmd.CmdClause.Arg("domain", "Domain name to check").Required().StringVar(&cmd.domain)
// Optional.
cmd.RegisterFlagBool(cmd.JSONFlag())
cmd.CmdClause.Flag("scope", "Specify `--scope=estimate` to perform an “estimated” availability check, which checks the DNS and domain aftermarkets, not domain registries").Action(cmd.scope.Set).StringVar(&cmd.scope.Value)

return &cmd
}

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

input := &status.GetInput{
Domain: g.domain,
}

if g.scope.WasSet {
scope := status.Scope(g.scope.Value)
if scope != status.ScopeEstimate {
return fsterr.RemediationError{
Inner: errors.New("invalid scope provided"),
Remediation: "Use `--scope=estimate` for an estimated status check",
}
}
input.Scope = fastly.ToPointer(scope)
}

fc, ok := g.Globals.APIClient.(*fastly.Client)
if !ok {
return errors.New("failed to acquire the Fastly API client")
}

st, err := status.Get(fc, input)
if err != nil {
g.Globals.ErrLog.Add(err)
return err
}

if ok, err := g.WriteJSON(out, st); ok {
return err
}

printStatusSummary(out, st)
return nil
}

// printStatusSummary displays the information returned from the API in a summarized format.
func printStatusSummary(w io.Writer, st *status.Status) {
fmt.Fprintf(w, "Domain: %s\n", st.Domain)
fmt.Fprintf(w, "Zone: %s\n", st.Zone)
fmt.Fprintf(w, "Status: %s\n", st.Status)
fmt.Fprintf(w, "Tags: %s\n", st.Tags)

if st.Scope != nil {
fmt.Fprintf(w, "Scope: %s\n", *st.Scope)
}

if len(st.Offers) > 0 {
fmt.Fprintf(w, "Offers:\n")
for _, o := range st.Offers {
fmt.Fprintf(w, " - Vendor: %s\n", o.Vendor)
fmt.Fprintf(w, " Currency: %s\n", o.Currency)
fmt.Fprintf(w, " Price: %s\n", o.Price)
}
}
}
125 changes: 125 additions & 0 deletions pkg/commands/tools/domain/status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package domain_test

import (
"bytes"
"io"
"net/http"
"testing"

"github.com/fastly/cli/pkg/commands/tools"
"github.com/fastly/cli/pkg/commands/tools/domain"
"github.com/fastly/cli/pkg/testutil"
"github.com/fastly/go-fastly/v10/fastly"
"github.com/fastly/go-fastly/v10/fastly/domains/v1/tools/status"
)

func TestNewDomainsV1ToolsStatusCommand(t *testing.T) {
scenarios := []testutil.CLIScenario{
{
Args: "",
WantError: "error parsing arguments: required argument 'domain' not provided",
},
{
Args: "fastly-cli-testing.com --scope not-estimate",
WantError: "invalid scope provided",
},
{
Args: "fastly-cli-testing.com",
Client: &http.Client{
Transport: &testutil.MockRoundTripper{
Response: &http.Response{
StatusCode: http.StatusOK,
Status: http.StatusText(http.StatusOK),
Body: io.NopCloser(bytes.NewReader(testutil.GenJSON(status.Status{
Domain: "fastly-cli-testing.com",
Zone: "com",
Status: "undelegated inactive",
Tags: "generic",
}))),
},
},
},
WantOutput: `Domain: fastly-cli-testing.com
Zone: com
Status: undelegated inactive
Tags: generic
`,
},
{
Args: "--scope estimate fastly-cli-testing-offers.com",
Client: &http.Client{
Transport: &testutil.MockRoundTripper{
Response: &http.Response{
StatusCode: http.StatusOK,
Status: http.StatusText(http.StatusOK),
Body: io.NopCloser(bytes.NewReader(testutil.GenJSON(status.Status{
Domain: "fastly-cli-testing-offers.com",
Zone: "com",
Status: "marketed priced transferable active",
Tags: "generic",
Scope: fastly.ToPointer(status.ScopeEstimate),
Offers: []status.Offer{
{
Vendor: "example.com",
Currency: "USD",
Price: "20000.00",
},
},
}))),
},
},
},
WantOutput: `Domain: fastly-cli-testing-offers.com
Zone: com
Status: marketed priced transferable active
Tags: generic
Scope: estimate
Offers:
- Vendor: example.com
Currency: USD
Price: 20000.00
`,
},
{
Args: "-j --scope estimate fastly-cli-testing-offers.com",
Client: &http.Client{
Transport: &testutil.MockRoundTripper{
Response: &http.Response{
StatusCode: http.StatusOK,
Status: http.StatusText(http.StatusOK),
Body: io.NopCloser(bytes.NewReader(testutil.GenJSON(status.Status{
Domain: "fastly-cli-testing-offers.com",
Zone: "com",
Status: "marketed priced transferable active",
Tags: "generic",
Scope: fastly.ToPointer(status.ScopeEstimate),
Offers: []status.Offer{
{
Vendor: "example.com",
Currency: "USD",
Price: "20000.00",
},
},
}))),
},
},
},
WantOutput: `{
"domain": "fastly-cli-testing-offers.com",
"zone": "com",
"status": "marketed priced transferable active",
"scope": "estimate",
"tags": "generic",
"offers": [
{
"vendor": "example.com",
"price": "20000.00",
"currency": "USD"
}
]
}
`,
},
}
testutil.RunCLIScenarios(t, []string{tools.CommandName, domain.CommandName, "status"}, scenarios)
}
Loading
0