Skip to content

Commit

Permalink
logging: adds DigitalOcean Spaces logging endpoint support
Browse files Browse the repository at this point in the history
Signed-off-by: Colton McCurdy <cmccurdy@fastly.com>
  • Loading branch information
mccurdyc committed May 21, 2020
1 parent 41d214a commit 035015d
Show file tree
Hide file tree
Showing 13 changed files with 1,484 additions and 0 deletions.
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

0 comments on commit 035015d

Please sign in to comment.