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

Adds DigitalOcean Spaces logging endpoint support #80

Merged
merged 1 commit into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions pkg/api/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ type Interface interface {
UpdateCloudfiles(*fastly.UpdateCloudfilesInput) (*fastly.Cloudfiles, error)
DeleteCloudfiles(*fastly.DeleteCloudfilesInput) error

CreateDigitalOcean(*fastly.CreateDigitalOceanInput) (*fastly.DigitalOcean, error)
ListDigitalOceans(*fastly.ListDigitalOceansInput) ([]*fastly.DigitalOcean, error)
GetDigitalOcean(*fastly.GetDigitalOceanInput) (*fastly.DigitalOcean, error)
UpdateDigitalOcean(*fastly.UpdateDigitalOceanInput) (*fastly.DigitalOcean, error)
DeleteDigitalOcean(*fastly.DeleteDigitalOceanInput) error

GetUser(*fastly.GetUserInput) (*fastly.User, error)

GetRegions() (*fastly.RegionsResponse, error)
Expand Down
15 changes: 15 additions & 0 deletions pkg/app/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/fastly/cli/pkg/logging"
"github.com/fastly/cli/pkg/logging/bigquery"
"github.com/fastly/cli/pkg/logging/cloudfiles"
"github.com/fastly/cli/pkg/logging/digitalocean"
"github.com/fastly/cli/pkg/logging/ftp"
"github.com/fastly/cli/pkg/logging/gcs"
"github.com/fastly/cli/pkg/logging/heroku"
Expand Down Expand Up @@ -247,6 +248,13 @@ func Run(args []string, env config.Environment, file config.File, configFilePath
cloudfilesUpdate := cloudfiles.NewUpdateCommand(cloudfilesRoot.CmdClause, &globals)
cloudfilesDelete := cloudfiles.NewDeleteCommand(cloudfilesRoot.CmdClause, &globals)

digitaloceanRoot := digitalocean.NewRootCommand(loggingRoot.CmdClause, &globals)
digitaloceanCreate := digitalocean.NewCreateCommand(digitaloceanRoot.CmdClause, &globals)
digitaloceanList := digitalocean.NewListCommand(digitaloceanRoot.CmdClause, &globals)
digitaloceanDescribe := digitalocean.NewDescribeCommand(digitaloceanRoot.CmdClause, &globals)
digitaloceanUpdate := digitalocean.NewUpdateCommand(digitaloceanRoot.CmdClause, &globals)
digitaloceanDelete := digitalocean.NewDeleteCommand(digitaloceanRoot.CmdClause, &globals)

statsRoot := stats.NewRootCommand(app, &globals)
statsRegions := stats.NewRegionsCommand(statsRoot.CmdClause, &globals)
statsHistorical := stats.NewHistoricalCommand(statsRoot.CmdClause, &globals)
Expand Down Expand Up @@ -415,6 +423,13 @@ func Run(args []string, env config.Environment, file config.File, configFilePath
cloudfilesUpdate,
cloudfilesDelete,

digitaloceanRoot,
digitaloceanCreate,
digitaloceanList,
digitaloceanDescribe,
digitaloceanUpdate,
digitaloceanDelete,

statsRoot,
statsRegions,
statsHistorical,
Expand Down
105 changes: 105 additions & 0 deletions pkg/app/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1910,6 +1910,111 @@ COMMANDS
--version=VERSION Number of service version
-n, --name=NAME The name of the Cloudfiles logging object

logging digitalocean create --name=NAME --version=VERSION --bucket=BUCKET --access-key=ACCESS-KEY --secret-key=SECRET-KEY [<flags>]
Create a DigitalOcean Spaces logging endpoint on a Fastly service version

-n, --name=NAME The name of the DigitalOcean Spaces logging
object. Used as a primary key for API access
-s, --service-id=SERVICE-ID Service ID
--version=VERSION Number of service version
--bucket=BUCKET The name of the DigitalOcean Space
--access-key=ACCESS-KEY Your DigitalOcean Spaces account access key
--secret-key=SECRET-KEY Your DigitalOcean Spaces account secret key
--domain=DOMAIN The domain of the DigitalOcean Spaces endpoint
(default 'nyc3.digitaloceanspaces.com')
--path=PATH The path to upload logs to
--period=PERIOD How frequently log files are finalized so they
can be available for reading (in seconds,
default 3600)
--gzip-level=GZIP-LEVEL What level of GZIP encoding to have when
dumping logs (default 0, no compression)
--format=FORMAT Apache style log formatting
--message-type=MESSAGE-TYPE
How the message should be formatted. One of:
classic (default), loggly, logplex or blank
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(default) or 1
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
--timestamp-format=TIMESTAMP-FORMAT
strftime specified timestamp formatting
(default "%Y-%m-%dT%H:%M:%S.000")
--placement=PLACEMENT Where in the generated VCL the logging call
should be placed, overriding any format_version
default. Can be none or waf_debug
--public-key=PUBLIC-KEY A PGP public key that Fastly will use to
encrypt your log files before writing them to
disk

logging digitalocean list --version=VERSION [<flags>]
List DigitalOcean Spaces logging endpoints on a Fastly service version

-s, --service-id=SERVICE-ID Service ID
--version=VERSION Number of service version

logging digitalocean describe --version=VERSION --name=NAME [<flags>]
Show detailed information about a DigitalOcean Spaces logging endpoint on a
Fastly service version

-s, --service-id=SERVICE-ID Service ID
--version=VERSION Number of service version
-d, --name=NAME The name of the DigitalOcean Spaces logging
object

logging digitalocean update --version=VERSION --name=NAME [<flags>]
Update a DigitalOcean Spaces logging endpoint on a Fastly service version

-s, --service-id=SERVICE-ID Service ID
--version=VERSION Number of service version
-n, --name=NAME The name of the DigitalOcean Spaces logging
object
--new-name=NEW-NAME New name of the DigitalOcean Spaces logging
object
--bucket=BUCKET The name of the DigitalOcean Space
--domain=DOMAIN The domain of the DigitalOcean Spaces endpoint
(default 'nyc3.digitaloceanspaces.com')
--access-key=ACCESS-KEY Your DigitalOcean Spaces account access key
--secret-key=SECRET-KEY Your DigitalOcean Spaces account secret key
--path=PATH The path to upload logs to
--period=PERIOD How frequently log files are finalized so they
can be available for reading (in seconds,
default 3600)
--gzip-level=GZIP-LEVEL What level of GZIP encoding to have when
dumping logs (default 0, no compression)
--format=FORMAT Apache style log formatting
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(default) or 1
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
--message-type=MESSAGE-TYPE
How the message should be formatted. One of:
classic (default), loggly, logplex or blank
--timestamp-format=TIMESTAMP-FORMAT
strftime specified timestamp formatting
(default "%Y-%m-%dT%H:%M:%S.000")
--placement=PLACEMENT Where in the generated VCL the logging call
should be placed, overriding any format_version
default. Can be none or waf_debug
--public-key=PUBLIC-KEY A PGP public key that Fastly will use to
encrypt your log files before writing them to
disk

logging digitalocean delete --version=VERSION --name=NAME [<flags>]
Delete a DigitalOcean Spaces logging endpoint on a Fastly service version

-s, --service-id=SERVICE-ID Service ID
--version=VERSION Number of service version
-n, --name=NAME The name of the DigitalOcean Spaces logging
object

stats regions
List stats regions

Expand Down
147 changes: 147 additions & 0 deletions pkg/logging/digitalocean/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package digitalocean

import (
"io"

"github.com/fastly/cli/pkg/common"
"github.com/fastly/cli/pkg/compute/manifest"
"github.com/fastly/cli/pkg/config"
"github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/text"
"github.com/fastly/go-fastly/fastly"
)

// CreateCommand calls the Fastly API to create DigitalOcean Spaces logging endpoints.
type CreateCommand struct {
common.Base
manifest manifest.Data

// required
EndpointName string // Can't shaddow common.Base method Name().
Version int
BucketName string
AccessKey string
SecretKey string

// optional
Domain common.OptionalString
Path common.OptionalString
Period common.OptionalUint
GzipLevel common.OptionalUint
MessageType common.OptionalString
Format common.OptionalString
FormatVersion common.OptionalUint
ResponseCondition common.OptionalString
TimestampFormat common.OptionalString
Placement common.OptionalString
PublicKey common.OptionalString
}

// NewCreateCommand returns a usable command registered under the parent.
func NewCreateCommand(parent common.Registerer, globals *config.Data) *CreateCommand {
var c CreateCommand
c.Globals = globals
c.manifest.File.Read(manifest.Filename)
c.CmdClause = parent.Command("create", "Create a DigitalOcean Spaces logging endpoint on a Fastly service version").Alias("add")

c.CmdClause.Flag("name", "The name of the DigitalOcean Spaces logging object. Used as a primary key for API access").Short('n').Required().StringVar(&c.EndpointName)
c.CmdClause.Flag("service-id", "Service ID").Short('s').StringVar(&c.manifest.Flag.ServiceID)
c.CmdClause.Flag("version", "Number of service version").Required().IntVar(&c.Version)

c.CmdClause.Flag("bucket", "The name of the DigitalOcean Space").Required().StringVar(&c.BucketName)
c.CmdClause.Flag("access-key", "Your DigitalOcean Spaces account access key").Required().StringVar(&c.AccessKey)
c.CmdClause.Flag("secret-key", "Your DigitalOcean Spaces account secret key").Required().StringVar(&c.SecretKey)

c.CmdClause.Flag("domain", "The domain of the DigitalOcean Spaces endpoint (default 'nyc3.digitaloceanspaces.com')").Action(c.Domain.Set).StringVar(&c.Domain.Value)
c.CmdClause.Flag("path", "The path to upload logs to").Action(c.Path.Set).StringVar(&c.Path.Value)
c.CmdClause.Flag("period", "How frequently log files are finalized so they can be available for reading (in seconds, default 3600)").Action(c.Period.Set).UintVar(&c.Period.Value)
c.CmdClause.Flag("gzip-level", "What level of GZIP encoding to have when dumping logs (default 0, no compression)").Action(c.GzipLevel.Set).UintVar(&c.GzipLevel.Value)
c.CmdClause.Flag("format", "Apache style log formatting").Action(c.Format.Set).StringVar(&c.Format.Value)
c.CmdClause.Flag("message-type", "How the message should be formatted. One of: classic (default), loggly, logplex or blank").Action(c.MessageType.Set).StringVar(&c.MessageType.Value)
c.CmdClause.Flag("format-version", "The version of the custom logging format used for the configured endpoint. Can be either 2 (default) or 1").Action(c.FormatVersion.Set).UintVar(&c.FormatVersion.Value)
c.CmdClause.Flag("response-condition", "The name of an existing condition in the configured endpoint, or leave blank to always execute").Action(c.ResponseCondition.Set).StringVar(&c.ResponseCondition.Value)
c.CmdClause.Flag("timestamp-format", `strftime specified timestamp formatting (default "%Y-%m-%dT%H:%M:%S.000")`).Action(c.TimestampFormat.Set).StringVar(&c.TimestampFormat.Value)
c.CmdClause.Flag("placement", "Where in the generated VCL the logging call should be placed, overriding any format_version default. Can be none or waf_debug").Action(c.Placement.Set).StringVar(&c.Placement.Value)
c.CmdClause.Flag("public-key", "A PGP public key that Fastly will use to encrypt your log files before writing them to disk").Action(c.PublicKey.Set).StringVar(&c.PublicKey.Value)

return &c
}

// createInput transforms values parsed from CLI flags into an object to be used by the API client library.
func (c *CreateCommand) createInput() (*fastly.CreateDigitalOceanInput, error) {
var input fastly.CreateDigitalOceanInput

serviceID, source := c.manifest.ServiceID()
if source == manifest.SourceUndefined {
return nil, errors.ErrNoServiceID
}

input.Service = serviceID
input.Version = c.Version
input.Name = fastly.String(c.EndpointName)
input.BucketName = fastly.String(c.BucketName)
input.AccessKey = fastly.String(c.AccessKey)
input.SecretKey = fastly.String(c.SecretKey)

if c.Domain.Valid {
input.Domain = fastly.String(c.Domain.Value)
}

if c.Path.Valid {
input.Path = fastly.String(c.Path.Value)
}

if c.Period.Valid {
input.Period = fastly.Uint(c.Period.Value)
}

if c.GzipLevel.Valid {
input.GzipLevel = fastly.Uint(c.GzipLevel.Value)
}

if c.Format.Valid {
input.Format = fastly.String(c.Format.Value)
}

if c.FormatVersion.Valid {
input.FormatVersion = fastly.Uint(c.FormatVersion.Value)
}

if c.ResponseCondition.Valid {
input.ResponseCondition = fastly.String(c.ResponseCondition.Value)
}

if c.MessageType.Valid {
input.MessageType = fastly.String(c.MessageType.Value)
}

if c.TimestampFormat.Valid {
input.TimestampFormat = fastly.String(c.TimestampFormat.Value)
}

if c.Placement.Valid {
input.Placement = fastly.String(c.Placement.Value)
}

if c.PublicKey.Valid {
input.PublicKey = fastly.String(c.PublicKey.Value)
}

return &input, nil
}

// Exec invokes the application logic for the command.
func (c *CreateCommand) Exec(in io.Reader, out io.Writer) error {
input, err := c.createInput()
if err != nil {
return err
}

d, err := c.Globals.Client.CreateDigitalOcean(input)
if err != nil {
return err
}

text.Success(out, "Created DigitalOcean Spaces logging endpoint %s (service %s version %d)", d.Name, d.ServiceID, d.Version)
return nil
}
47 changes: 47 additions & 0 deletions pkg/logging/digitalocean/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package digitalocean

import (
"io"

"github.com/fastly/cli/pkg/common"
"github.com/fastly/cli/pkg/compute/manifest"
"github.com/fastly/cli/pkg/config"
"github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/text"
"github.com/fastly/go-fastly/fastly"
)

// DeleteCommand calls the Fastly API to delete DigitalOcean Spaces logging endpoints.
type DeleteCommand struct {
common.Base
manifest manifest.Data
Input fastly.DeleteDigitalOceanInput
}

// NewDeleteCommand returns a usable command registered under the parent.
func NewDeleteCommand(parent common.Registerer, globals *config.Data) *DeleteCommand {
var c DeleteCommand
c.Globals = globals
c.manifest.File.Read(manifest.Filename)
c.CmdClause = parent.Command("delete", "Delete a DigitalOcean Spaces logging endpoint on a Fastly service version").Alias("remove")
c.CmdClause.Flag("service-id", "Service ID").Short('s').StringVar(&c.manifest.Flag.ServiceID)
c.CmdClause.Flag("version", "Number of service version").Required().IntVar(&c.Input.Version)
c.CmdClause.Flag("name", "The name of the DigitalOcean Spaces logging object").Short('n').Required().StringVar(&c.Input.Name)
return &c
}

// Exec invokes the application logic for the command.
func (c *DeleteCommand) Exec(in io.Reader, out io.Writer) error {
serviceID, source := c.manifest.ServiceID()
if source == manifest.SourceUndefined {
return errors.ErrNoServiceID
}
c.Input.Service = serviceID

if err := c.Globals.Client.DeleteDigitalOcean(&c.Input); err != nil {
return err
}

text.Success(out, "Deleted DigitalOcean Spaces logging endpoint %s (service %s version %d)", c.Input.Name, c.Input.Service, c.Input.Version)
return nil
}
Loading