Skip to content
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

Implement Compute@Edge Free Trial Activation #531

Merged
merged 5 commits into from
Feb 9, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
4 changes: 2 additions & 2 deletions cmd/fastly/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func main() {
var (
args = os.Args[1:]
clientFactory = app.FastlyAPIClient
httpClient = http.DefaultClient
httpClient = &http.Client{Timeout: time.Second * 5}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't use the golang default http client as it doesn't provide preconfigured timeouts.

For some reason I had previously used a strange pattern of using it with a context object for handling timeouts. The implementation worked but it's a non-standard pattern to use so I've cleaned this up.

in io.Reader = os.Stdin
out io.Writer = sync.NewWriter(color.Output)
versionerCLI = update.NewGitHub(update.GitHubOpts{
Expand Down Expand Up @@ -143,7 +143,7 @@ Compatibility and versioning information for the Fastly CLI is being updated in
// NOTE: we no longer use the hardcoded config.RemoteEndpoint constant.
// Instead we rely on the values inside of the application
// configuration file to determine where to load the config from.
err := file.Load(file.CLI.RemoteConfig, httpClient, config.ConfigRequestTimeout, config.FilePath)
err := file.Load(file.CLI.RemoteConfig, config.FilePath, httpClient)
if err != nil {
errLoadConfig = fsterr.RemediationError{
Inner: fmt.Errorf("there was a problem updating the versioning information for the Fastly CLI:\n\n%w", err),
Expand Down
57 changes: 57 additions & 0 deletions pkg/api/undocumented/undocumented.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package undocumented
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new package that provides an abstraction for making API calls for undocumented endpoints.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For whatever reason I'm not overly keen on the name undocumented, even though it's an accurate description of the functionality. So I'm open to suggestions.

I tried using internal prior to this, but the go compiler recognises that name, and will force certain structural constraints that didn't really work for this use case.


import (
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"

"github.com/fastly/cli/pkg/api"
fsterr "github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/useragent"
)

// EdgeComputeTrial is the API endpoint for activating a compute trial.
const EdgeComputeTrial = "/customer/%s/edge-compute-trial"

// RequestTimeout is the timeout for the API network request.
const RequestTimeout = 5 * time.Second

// Get calls the given API endpoint and returns its response data.
func Get(host, path, token string, c api.HTTPClient) (data []byte, statusCode int, err error) {
host = strings.TrimSuffix(host, "/")
endpoint := fmt.Sprintf("%s%s", host, path)

req, err := http.NewRequest(http.MethodPost, endpoint, nil)
if err != nil {
return data, statusCode, err
}

req.Header.Set("Fastly-Key", token)
req.Header.Set("User-Agent", useragent.Name)

res, err := c.Do(req)
if err != nil {
if urlErr, ok := err.(*url.Error); ok && urlErr.Timeout() {
return data, statusCode, fsterr.RemediationError{
Inner: err,
Remediation: fsterr.NetworkRemediation,
}
}
return data, statusCode, err
}
defer res.Body.Close()

if res.StatusCode != http.StatusOK {
return data, res.StatusCode, fmt.Errorf("error from API: '%s'", res.Status)
}

data, err = io.ReadAll(res.Body)
if err != nil {
return data, res.StatusCode, err
}

return data, res.StatusCode, nil
}
12 changes: 6 additions & 6 deletions pkg/app/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ func defineCommands(
backendList := backend.NewListCommand(backendCmdRoot.CmdClause, globals, data)
backendUpdate := backend.NewUpdateCommand(backendCmdRoot.CmdClause, globals, data)
computeCmdRoot := compute.NewRootCommand(app, globals)
computeBuild := compute.NewBuildCommand(computeCmdRoot.CmdClause, opts.HTTPClient, globals, data)
computeDeploy := compute.NewDeployCommand(computeCmdRoot.CmdClause, opts.HTTPClient, globals, data)
computeInit := compute.NewInitCommand(computeCmdRoot.CmdClause, opts.HTTPClient, globals, data)
computeBuild := compute.NewBuildCommand(computeCmdRoot.CmdClause, globals, data)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bunch of commands were explicitly passing in a HTTP client and then not using it.

I additionally (see below in pkg/app/run.go) decided to embed the HTTP client into the globals object so it wouldn't be necessary to have to pass it explicitly into the remaining commands, as we already are passing in the global object.

computeDeploy := compute.NewDeployCommand(computeCmdRoot.CmdClause, globals, data)
computeInit := compute.NewInitCommand(computeCmdRoot.CmdClause, globals, data)
computePack := compute.NewPackCommand(computeCmdRoot.CmdClause, globals, data)
computePublish := compute.NewPublishCommand(computeCmdRoot.CmdClause, globals, computeBuild, computeDeploy, data)
computeServe := compute.NewServeCommand(computeCmdRoot.CmdClause, globals, computeBuild, opts.Versioners.Viceroy, data)
computeUpdate := compute.NewUpdateCommand(computeCmdRoot.CmdClause, opts.HTTPClient, globals, data)
computeUpdate := compute.NewUpdateCommand(computeCmdRoot.CmdClause, globals, data)
computeValidate := compute.NewValidateCommand(computeCmdRoot.CmdClause, globals)
configureCmdRoot := configure.NewRootCommand(app, opts.ConfigPath, configure.APIClientFactory(opts.APIClient), globals)
dictionaryCmdRoot := dictionary.NewRootCommand(app, globals)
Expand Down Expand Up @@ -302,7 +302,7 @@ func defineCommands(
statsHistorical := stats.NewHistoricalCommand(statsCmdRoot.CmdClause, globals, data)
statsRealtime := stats.NewRealtimeCommand(statsCmdRoot.CmdClause, globals, data)
statsRegions := stats.NewRegionsCommand(statsCmdRoot.CmdClause, globals)
updateRoot := update.NewRootCommand(app, opts.ConfigPath, opts.Versioners.CLI, opts.HTTPClient, globals)
updateRoot := update.NewRootCommand(app, opts.ConfigPath, opts.Versioners.CLI, globals)
userCmdRoot := user.NewRootCommand(app, globals)
userCreate := user.NewCreateCommand(userCmdRoot.CmdClause, globals, data)
userDelete := user.NewDeleteCommand(userCmdRoot.CmdClause, globals, data)
Expand All @@ -323,7 +323,7 @@ func defineCommands(
vclSnippetList := snippet.NewListCommand(vclSnippetCmdRoot.CmdClause, globals, data)
vclSnippetUpdate := snippet.NewUpdateCommand(vclSnippetCmdRoot.CmdClause, globals, data)
versionCmdRoot := version.NewRootCommand(app, opts.Versioners.Viceroy)
whoamiCmdRoot := whoami.NewRootCommand(app, opts.HTTPClient, globals)
whoamiCmdRoot := whoami.NewRootCommand(app, globals)

return []cmd.Command{
shellcompleteCmdRoot,
Expand Down
13 changes: 7 additions & 6 deletions pkg/app/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,12 @@ func Run(opts RunOpts) error {
// The globals will hold generally-applicable configuration parameters
// from a variety of sources, and is provided to each concrete command.
globals := config.Data{
File: opts.ConfigFile,
Path: opts.ConfigPath,
Env: opts.Env,
Output: opts.Stdout,
ErrLog: opts.ErrLog,
File: opts.ConfigFile,
Path: opts.ConfigPath,
Env: opts.Env,
Output: opts.Stdout,
ErrLog: opts.ErrLog,
HTTPClient: opts.HTTPClient,
}

// Set up the main application root, including global flags, and then each
Expand Down Expand Up @@ -148,7 +149,7 @@ func Run(opts RunOpts) error {
}
}

globals.Client, err = opts.APIClient(token, endpoint)
globals.APIClient, err = opts.APIClient(token, endpoint)
Copy link
Collaborator Author

@Integralist Integralist Feb 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of Client was becoming ambiguous due to us passing around both an API client and a standard HTTP client, so I made it clearer by renaming the field across the code base. Most of the file churn comes from this change.

if err != nil {
globals.ErrLog.Add(err)
return fmt.Errorf("error constructing Fastly API client: %w", err)
Expand Down
8 changes: 4 additions & 4 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ type OptionalInt struct {
type ServiceDetailsOpts struct {
AllowActiveLocked bool
AutoCloneFlag OptionalAutoClone
Client api.Interface
APIClient api.Interface
Manifest manifest.Data
Out io.Writer
ServiceNameFlag OptionalServiceNameID
Expand All @@ -126,22 +126,22 @@ type ServiceDetailsOpts struct {

// ServiceDetails returns the Service ID and Service Version.
func ServiceDetails(opts ServiceDetailsOpts) (serviceID string, serviceVersion *fastly.Version, err error) {
serviceID, source, flag, err := ServiceID(opts.ServiceNameFlag, opts.Manifest, opts.Client, opts.ErrLog)
serviceID, source, flag, err := ServiceID(opts.ServiceNameFlag, opts.Manifest, opts.APIClient, opts.ErrLog)
if err != nil {
return serviceID, serviceVersion, err
}
if opts.VerboseMode {
DisplayServiceID(serviceID, flag, source, opts.Out)
}

v, err := opts.ServiceVersionFlag.Parse(serviceID, opts.Client)
v, err := opts.ServiceVersionFlag.Parse(serviceID, opts.APIClient)
if err != nil {
return serviceID, serviceVersion, err
}

if opts.AutoCloneFlag.WasSet {
currentVersion := v
v, err = opts.AutoCloneFlag.Parse(currentVersion, serviceID, opts.VerboseMode, opts.Out, opts.Client)
v, err = opts.AutoCloneFlag.Parse(currentVersion, serviceID, opts.VerboseMode, opts.Out, opts.APIClient)
if err != nil {
return serviceID, currentVersion, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/commands/acl/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type CreateCommand struct {
func (c *CreateCommand) Exec(in io.Reader, out io.Writer) error {
serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{
AutoCloneFlag: c.autoClone,
Client: c.Globals.Client,
APIClient: c.Globals.APIClient,
ErrLog: c.Globals.ErrLog,
Manifest: c.manifest,
Out: out,
Expand All @@ -81,7 +81,7 @@ func (c *CreateCommand) Exec(in io.Reader, out io.Writer) error {

input := c.constructInput(serviceID, serviceVersion.Number)

a, err := c.Globals.Client.CreateACL(input)
a, err := c.Globals.APIClient.CreateACL(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand Down
4 changes: 2 additions & 2 deletions pkg/commands/acl/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type DeleteCommand struct {
func (c *DeleteCommand) Exec(in io.Reader, out io.Writer) error {
serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{
AutoCloneFlag: c.autoClone,
Client: c.Globals.Client,
APIClient: c.Globals.APIClient,
Manifest: c.manifest,
Out: out,
ServiceNameFlag: c.serviceName,
Expand All @@ -80,7 +80,7 @@ func (c *DeleteCommand) Exec(in io.Reader, out io.Writer) error {

input := c.constructInput(serviceID, serviceVersion.Number)

err = c.Globals.Client.DeleteACL(input)
err = c.Globals.APIClient.DeleteACL(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand Down
4 changes: 2 additions & 2 deletions pkg/commands/acl/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (c *DescribeCommand) Exec(in io.Reader, out io.Writer) error {

serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{
AllowActiveLocked: true,
Client: c.Globals.Client,
APIClient: c.Globals.APIClient,
Manifest: c.manifest,
Out: out,
ServiceNameFlag: c.serviceName,
Expand All @@ -87,7 +87,7 @@ func (c *DescribeCommand) Exec(in io.Reader, out io.Writer) error {

input := c.constructInput(serviceID, serviceVersion.Number)

a, err := c.Globals.Client.GetACL(input)
a, err := c.Globals.APIClient.GetACL(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand Down
4 changes: 2 additions & 2 deletions pkg/commands/acl/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (c *ListCommand) Exec(in io.Reader, out io.Writer) error {

serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{
AllowActiveLocked: true,
Client: c.Globals.Client,
APIClient: c.Globals.APIClient,
Manifest: c.manifest,
Out: out,
ServiceNameFlag: c.serviceName,
Expand All @@ -86,7 +86,7 @@ func (c *ListCommand) Exec(in io.Reader, out io.Writer) error {

input := c.constructInput(serviceID, serviceVersion.Number)

as, err := c.Globals.Client.ListACLs(input)
as, err := c.Globals.APIClient.ListACLs(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand Down
4 changes: 2 additions & 2 deletions pkg/commands/acl/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type UpdateCommand struct {
func (c *UpdateCommand) Exec(in io.Reader, out io.Writer) error {
serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{
AutoCloneFlag: c.autoClone,
Client: c.Globals.Client,
APIClient: c.Globals.APIClient,
Manifest: c.manifest,
Out: out,
ServiceNameFlag: c.serviceName,
Expand All @@ -82,7 +82,7 @@ func (c *UpdateCommand) Exec(in io.Reader, out io.Writer) error {

input := c.constructInput(serviceID, serviceVersion.Number)

a, err := c.Globals.Client.UpdateACL(input)
a, err := c.Globals.APIClient.UpdateACL(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand Down
4 changes: 2 additions & 2 deletions pkg/commands/aclentry/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ type CreateCommand struct {

// Exec invokes the application logic for the command.
func (c *CreateCommand) Exec(in io.Reader, out io.Writer) error {
serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.Client, c.Globals.ErrLog)
serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.APIClient, c.Globals.ErrLog)
if err != nil {
return err
}
Expand All @@ -66,7 +66,7 @@ func (c *CreateCommand) Exec(in io.Reader, out io.Writer) error {

input := c.constructInput(serviceID)

a, err := c.Globals.Client.CreateACLEntry(input)
a, err := c.Globals.APIClient.CreateACLEntry(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand Down
4 changes: 2 additions & 2 deletions pkg/commands/aclentry/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type DeleteCommand struct {

// Exec invokes the application logic for the command.
func (c *DeleteCommand) Exec(in io.Reader, out io.Writer) error {
serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.Client, c.Globals.ErrLog)
serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.APIClient, c.Globals.ErrLog)
if err != nil {
return err
}
Expand All @@ -60,7 +60,7 @@ func (c *DeleteCommand) Exec(in io.Reader, out io.Writer) error {

input := c.constructInput(serviceID)

err = c.Globals.Client.DeleteACLEntry(input)
err = c.Globals.APIClient.DeleteACLEntry(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand Down
4 changes: 2 additions & 2 deletions pkg/commands/aclentry/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (c *DescribeCommand) Exec(in io.Reader, out io.Writer) error {
return fsterr.ErrInvalidVerboseJSONCombo
}

serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.Client, c.Globals.ErrLog)
serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.APIClient, c.Globals.ErrLog)
if err != nil {
return err
}
Expand All @@ -73,7 +73,7 @@ func (c *DescribeCommand) Exec(in io.Reader, out io.Writer) error {

input := c.constructInput(serviceID)

a, err := c.Globals.Client.GetACLEntry(input)
a, err := c.Globals.APIClient.GetACLEntry(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand Down
4 changes: 2 additions & 2 deletions pkg/commands/aclentry/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (c *ListCommand) Exec(in io.Reader, out io.Writer) error {
return fsterr.ErrInvalidVerboseJSONCombo
}

serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.Client, c.Globals.ErrLog)
serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.APIClient, c.Globals.ErrLog)
if err != nil {
return err
}
Expand All @@ -79,7 +79,7 @@ func (c *ListCommand) Exec(in io.Reader, out io.Writer) error {
}

input := c.constructInput(serviceID)
paginator := c.Globals.Client.NewListACLEntriesPaginator(input)
paginator := c.Globals.APIClient.NewListACLEntriesPaginator(input)

// TODO: Use generics support in go 1.18 to replace this almost identical
// logic inside of 'dictionary-item list' and 'service list'.
Expand Down
6 changes: 3 additions & 3 deletions pkg/commands/aclentry/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type UpdateCommand struct {

// Exec invokes the application logic for the command.
func (c *UpdateCommand) Exec(in io.Reader, out io.Writer) error {
serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.Client, c.Globals.ErrLog)
serviceID, source, flag, err := cmd.ServiceID(c.serviceName, c.manifest, c.Globals.APIClient, c.Globals.ErrLog)
if err != nil {
return err
}
Expand All @@ -77,7 +77,7 @@ func (c *UpdateCommand) Exec(in io.Reader, out io.Writer) error {
return err
}

err = c.Globals.Client.BatchModifyACLEntries(input)
err = c.Globals.APIClient.BatchModifyACLEntries(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand All @@ -94,7 +94,7 @@ func (c *UpdateCommand) Exec(in io.Reader, out io.Writer) error {
return err
}

a, err := c.Globals.Client.UpdateACLEntry(input)
a, err := c.Globals.APIClient.UpdateACLEntry(input)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]interface{}{
"Service ID": serviceID,
Expand Down
2 changes: 1 addition & 1 deletion pkg/commands/authtoken/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (c *CreateCommand) Exec(in io.Reader, out io.Writer) error {

input := c.constructInput()

r, err := c.Globals.Client.CreateToken(input)
r, err := c.Globals.APIClient.CreateToken(input)
if err != nil {
c.Globals.ErrLog.Add(err)
return err
Expand Down
6 changes: 3 additions & 3 deletions pkg/commands/authtoken/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (c *DeleteCommand) Exec(in io.Reader, out io.Writer) error {
}

if c.current {
err := c.Globals.Client.DeleteTokenSelf()
err := c.Globals.APIClient.DeleteTokenSelf()
if err != nil {
c.Globals.ErrLog.Add(err)
return err
Expand All @@ -66,7 +66,7 @@ func (c *DeleteCommand) Exec(in io.Reader, out io.Writer) error {
return err
}

err = c.Globals.Client.BatchDeleteTokens(input)
err = c.Globals.APIClient.BatchDeleteTokens(input)
if err != nil {
c.Globals.ErrLog.Add(err)
return err
Expand All @@ -82,7 +82,7 @@ func (c *DeleteCommand) Exec(in io.Reader, out io.Writer) error {
if c.id != "" {
input := c.constructInput()

err := c.Globals.Client.DeleteToken(input)
err := c.Globals.APIClient.DeleteToken(input)
if err != nil {
c.Globals.ErrLog.Add(err)
return err
Expand Down
Loading