-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(service-resource): Add Service Resource commands
https://developer.fastly.com/reference/api/services/resource/ This adds a `service-resource` sub-command which has associated create, delete, list, and update commands. Some of the names in the API may be confusing. I've done my best to add clarification whenever possible. Specifically: - A resource, as named by the API, is truly a _link_ between a service and a resource (e.g. an Object Store), not the resource itself - In some places, the API mixes `id` and `resource_id` which both refer to the ID of the resource _link_, and not the resource itself. - It's possible to provide a resource link name. If set, this is an alias for the resource. Otherwise, whatever name was used when creating the resource itself will be the name to reference from the service for the resource.
- Loading branch information
1 parent
894a1f3
commit ac4b804
Showing
14 changed files
with
1,345 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
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,120 @@ | ||
package serviceresource | ||
|
||
import ( | ||
"io" | ||
|
||
"github.com/fastly/cli/pkg/cmd" | ||
fsterr "github.com/fastly/cli/pkg/errors" | ||
"github.com/fastly/cli/pkg/global" | ||
"github.com/fastly/cli/pkg/manifest" | ||
"github.com/fastly/cli/pkg/text" | ||
"github.com/fastly/go-fastly/v7/fastly" | ||
) | ||
|
||
// CreateCommand calls the Fastly API to create a resource link. | ||
type CreateCommand struct { | ||
cmd.Base | ||
jsonOutput | ||
|
||
autoClone cmd.OptionalAutoClone | ||
input fastly.CreateResourceInput | ||
manifest manifest.Data | ||
serviceVersion cmd.OptionalServiceVersion | ||
} | ||
|
||
// NewCreateCommand returns a usable command registered under the parent. | ||
func NewCreateCommand(parent cmd.Registerer, globals *global.Data, data manifest.Data) *CreateCommand { | ||
c := CreateCommand{ | ||
Base: cmd.Base{ | ||
Globals: globals, | ||
}, | ||
manifest: data, | ||
input: fastly.CreateResourceInput{ | ||
// Kingpin requires the following to be initialized. | ||
ResourceID: new(string), | ||
Name: new(string), | ||
}, | ||
} | ||
c.CmdClause = parent.Command("create", "Create a Fastly service resource link").Alias("link") | ||
|
||
// Required. | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: "resource-id", | ||
Short: 'r', | ||
Description: "Resource ID", | ||
Dst: c.input.ResourceID, | ||
Required: true, | ||
}) | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: cmd.FlagServiceIDName, | ||
Short: 's', | ||
Description: cmd.FlagServiceIDDesc, | ||
Dst: &c.manifest.Flag.ServiceID, | ||
Required: true, | ||
}) | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: cmd.FlagVersionName, | ||
Description: cmd.FlagVersionDesc, | ||
Dst: &c.serviceVersion.Value, | ||
Required: true, | ||
}) | ||
|
||
// Optional. | ||
c.RegisterAutoCloneFlag(cmd.AutoCloneFlagOpts{ | ||
Action: c.autoClone.Set, | ||
Dst: &c.autoClone.Value, | ||
}) | ||
c.RegisterFlagBool(c.jsonFlag()) // --json | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: "name", | ||
Short: 'n', | ||
Description: "Resource alias. Defaults to name of resource", | ||
Dst: c.input.Name, | ||
}) | ||
|
||
return &c | ||
} | ||
|
||
// 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 | ||
} | ||
|
||
serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{ | ||
AutoCloneFlag: c.autoClone, | ||
APIClient: c.Globals.APIClient, | ||
Manifest: c.manifest, | ||
Out: out, | ||
ServiceNameFlag: cmd.OptionalServiceNameID{}, // ServiceID flag is required, no need to lookup service by name. | ||
ServiceVersionFlag: c.serviceVersion, | ||
VerboseMode: c.Globals.Flags.Verbose, | ||
}) | ||
if err != nil { | ||
c.Globals.ErrLog.AddWithContext(err, map[string]any{ | ||
"Service ID": c.manifest.Flag.ServiceID, | ||
"Service Version": fsterr.ServiceVersion(serviceVersion), | ||
}) | ||
return err | ||
} | ||
|
||
c.input.ServiceID = serviceID | ||
c.input.ServiceVersion = serviceVersion.Number | ||
|
||
resource, err := c.Globals.APIClient.CreateResource(&c.input) | ||
if err != nil { | ||
c.Globals.ErrLog.AddWithContext(err, map[string]any{ | ||
"ID": c.input.ResourceID, | ||
"Service ID": c.input.ServiceID, | ||
"Service Version": c.input.ServiceVersion, | ||
}) | ||
return err | ||
} | ||
|
||
if ok, err := c.WriteJSON(out, resource); ok { | ||
return err | ||
} | ||
|
||
text.Success(out, "Created service resource link %s on service %s version %s", resource.ID, resource.ServiceID, resource.ServiceVersion) | ||
return nil | ||
} |
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,120 @@ | ||
package serviceresource | ||
|
||
import ( | ||
"io" | ||
|
||
"github.com/fastly/cli/pkg/cmd" | ||
fsterr "github.com/fastly/cli/pkg/errors" | ||
"github.com/fastly/cli/pkg/global" | ||
"github.com/fastly/cli/pkg/manifest" | ||
"github.com/fastly/cli/pkg/text" | ||
"github.com/fastly/go-fastly/v7/fastly" | ||
) | ||
|
||
// DeleteCommand calls the Fastly API to delete service resource links. | ||
type DeleteCommand struct { | ||
cmd.Base | ||
jsonOutput | ||
|
||
autoClone cmd.OptionalAutoClone | ||
input fastly.DeleteResourceInput | ||
manifest manifest.Data | ||
serviceVersion cmd.OptionalServiceVersion | ||
} | ||
|
||
// NewDeleteCommand returns a usable command registered under the parent. | ||
func NewDeleteCommand(parent cmd.Registerer, globals *global.Data, data manifest.Data) *DeleteCommand { | ||
c := DeleteCommand{ | ||
Base: cmd.Base{ | ||
Globals: globals, | ||
}, | ||
manifest: data, | ||
} | ||
c.CmdClause = parent.Command("delete", "Delete a resource link for a Fastly service version").Alias("remove") | ||
|
||
// Required. | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: "id", | ||
Description: "ID of resource link", | ||
Dst: &c.input.ResourceID, | ||
Required: true, | ||
}) | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: cmd.FlagServiceIDName, | ||
Short: 's', | ||
Description: cmd.FlagServiceIDDesc, | ||
Dst: &c.manifest.Flag.ServiceID, | ||
Required: true, | ||
}) | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: cmd.FlagVersionName, | ||
Description: cmd.FlagVersionDesc, | ||
Dst: &c.serviceVersion.Value, | ||
Required: true, | ||
}) | ||
|
||
// Optional. | ||
c.RegisterAutoCloneFlag(cmd.AutoCloneFlagOpts{ | ||
Action: c.autoClone.Set, | ||
Dst: &c.autoClone.Value, | ||
}) | ||
c.RegisterFlagBool(c.jsonFlag()) // --json | ||
|
||
return &c | ||
} | ||
|
||
// Exec invokes the application logic for the command. | ||
func (c *DeleteCommand) Exec(_ io.Reader, out io.Writer) error { | ||
if c.Globals.Verbose() && c.jsonOutput.enabled { | ||
return fsterr.ErrInvalidVerboseJSONCombo | ||
} | ||
|
||
serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{ | ||
AutoCloneFlag: c.autoClone, | ||
APIClient: c.Globals.APIClient, | ||
Manifest: c.manifest, | ||
Out: out, | ||
ServiceNameFlag: cmd.OptionalServiceNameID{}, // ServiceID flag is required, no need to lookup service by name. | ||
ServiceVersionFlag: c.serviceVersion, | ||
VerboseMode: c.Globals.Flags.Verbose, | ||
}) | ||
if err != nil { | ||
c.Globals.ErrLog.AddWithContext(err, map[string]any{ | ||
"Service ID": c.manifest.Flag.ServiceID, | ||
"Service Version": fsterr.ServiceVersion(serviceVersion), | ||
}) | ||
return err | ||
} | ||
|
||
c.input.ServiceID = serviceID | ||
c.input.ServiceVersion = serviceVersion.Number | ||
|
||
err = c.Globals.APIClient.DeleteResource(&c.input) | ||
if err != nil { | ||
c.Globals.ErrLog.AddWithContext(err, map[string]any{ | ||
"ID": c.input.ResourceID, | ||
"Service ID": c.input.ServiceID, | ||
"Service Version": c.input.ServiceVersion, | ||
}) | ||
return err | ||
} | ||
|
||
if c.jsonOutput.enabled { | ||
o := struct { | ||
ResourceID string `json:"id"` | ||
ServiceID string `json:"service_id"` | ||
ServiceVersion int `json:"service_version"` | ||
Deleted bool `json:"deleted"` | ||
}{ | ||
c.input.ResourceID, | ||
c.input.ServiceID, | ||
c.input.ServiceVersion, | ||
true, | ||
} | ||
_, err := c.WriteJSON(out, o) | ||
return err | ||
} | ||
|
||
text.Success(out, "Deleted service resource link %s from service %s version %d", c.input.ResourceID, c.input.ServiceID, c.input.ServiceVersion) | ||
return nil | ||
} |
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,104 @@ | ||
package serviceresource | ||
|
||
import ( | ||
"io" | ||
|
||
"github.com/fastly/cli/pkg/cmd" | ||
fsterr "github.com/fastly/cli/pkg/errors" | ||
"github.com/fastly/cli/pkg/global" | ||
"github.com/fastly/cli/pkg/manifest" | ||
"github.com/fastly/cli/pkg/text" | ||
"github.com/fastly/go-fastly/v7/fastly" | ||
) | ||
|
||
// DescribeCommand calls the Fastly API to describe a service resource link. | ||
type DescribeCommand struct { | ||
cmd.Base | ||
jsonOutput | ||
|
||
input fastly.GetResourceInput | ||
manifest manifest.Data | ||
serviceVersion cmd.OptionalServiceVersion | ||
} | ||
|
||
// NewDescribeCommand returns a usable command registered under the parent. | ||
func NewDescribeCommand(parent cmd.Registerer, globals *global.Data, data manifest.Data) *DescribeCommand { | ||
c := DescribeCommand{ | ||
Base: cmd.Base{ | ||
Globals: globals, | ||
}, | ||
manifest: data, | ||
} | ||
c.CmdClause = parent.Command("describe", "Show detailed information about a Fastly service resource link").Alias("get") | ||
|
||
// Required. | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: "id", | ||
Description: "ID of resource link", | ||
Dst: &c.input.ResourceID, | ||
Required: true, | ||
}) | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: cmd.FlagServiceIDName, | ||
Short: 's', | ||
Description: cmd.FlagServiceIDDesc, | ||
Dst: &c.manifest.Flag.ServiceID, | ||
Required: true, | ||
}) | ||
c.RegisterFlag(cmd.StringFlagOpts{ | ||
Name: cmd.FlagVersionName, | ||
Description: cmd.FlagVersionDesc, | ||
Dst: &c.serviceVersion.Value, | ||
Required: true, | ||
}) | ||
|
||
// Optional. | ||
c.RegisterFlagBool(c.jsonFlag()) // --json | ||
|
||
return &c | ||
} | ||
|
||
// Exec invokes the application logic for the command. | ||
func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { | ||
if c.Globals.Verbose() && c.jsonOutput.enabled { | ||
return fsterr.ErrInvalidVerboseJSONCombo | ||
} | ||
|
||
serviceID, source, flag, err := cmd.ServiceID(cmd.OptionalServiceNameID{}, c.manifest, c.Globals.APIClient, c.Globals.ErrLog) | ||
if err != nil { | ||
return err | ||
} | ||
if c.Globals.Verbose() { | ||
cmd.DisplayServiceID(serviceID, flag, source, out) | ||
} | ||
|
||
serviceVersion, err := c.serviceVersion.Parse(serviceID, c.Globals.APIClient) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
c.input.ServiceID = serviceID | ||
c.input.ServiceVersion = serviceVersion.Number | ||
|
||
resource, err := c.Globals.APIClient.GetResource(&c.input) | ||
if err != nil { | ||
c.Globals.ErrLog.AddWithContext(err, map[string]any{ | ||
"ID": c.input.ResourceID, | ||
"Service ID": c.input.ServiceID, | ||
"Service Version": c.input.ServiceVersion, | ||
}) | ||
return err | ||
} | ||
|
||
if ok, err := c.WriteJSON(out, resource); ok { | ||
return err | ||
} | ||
|
||
if !c.Globals.Verbose() { | ||
text.Output(out, "Service ID: %s", resource.ServiceID) | ||
} | ||
text.Output(out, "Service Version: %s", resource.ServiceVersion) | ||
text.PrintResource(out, "", resource) | ||
|
||
return nil | ||
} |
Oops, something went wrong.