Skip to content

Commit

Permalink
logging: adds splunk 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 19, 2020
1 parent c93b204 commit c9c25eb
Show file tree
Hide file tree
Showing 12 changed files with 935 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 @@ -100,6 +100,12 @@ type Interface interface {
UpdateFTP(*fastly.UpdateFTPInput) (*fastly.FTP, error)
DeleteFTP(*fastly.DeleteFTPInput) error

CreateSplunk(*fastly.CreateSplunkInput) (*fastly.Splunk, error)
ListSplunks(*fastly.ListSplunksInput) ([]*fastly.Splunk, error)
GetSplunk(*fastly.GetSplunkInput) (*fastly.Splunk, error)
UpdateSplunk(*fastly.UpdateSplunkInput) (*fastly.Splunk, error)
DeleteSplunk(*fastly.DeleteSplunkInput) 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 @@ -25,6 +25,7 @@ import (
"github.com/fastly/cli/pkg/logging/logentries"
"github.com/fastly/cli/pkg/logging/papertrail"
"github.com/fastly/cli/pkg/logging/s3"
"github.com/fastly/cli/pkg/logging/splunk"
"github.com/fastly/cli/pkg/logging/sumologic"
"github.com/fastly/cli/pkg/logging/syslog"
"github.com/fastly/cli/pkg/service"
Expand Down Expand Up @@ -183,6 +184,13 @@ func Run(args []string, env config.Environment, file config.File, configFilePath
ftpUpdate := ftp.NewUpdateCommand(ftpRoot.CmdClause, &globals)
ftpDelete := ftp.NewDeleteCommand(ftpRoot.CmdClause, &globals)

splunkRoot := splunk.NewRootCommand(loggingRoot.CmdClause, &globals)
splunkCreate := splunk.NewCreateCommand(splunkRoot.CmdClause, &globals)
splunkList := splunk.NewListCommand(splunkRoot.CmdClause, &globals)
splunkDescribe := splunk.NewDescribeCommand(splunkRoot.CmdClause, &globals)
splunkUpdate := splunk.NewUpdateCommand(splunkRoot.CmdClause, &globals)
splunkDelete := splunk.NewDeleteCommand(splunkRoot.CmdClause, &globals)

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

splunkRoot,
splunkCreate,
splunkList,
splunkDescribe,
splunkUpdate,
splunkDelete,

statsRoot,
statsRegions,
statsHistorical,
Expand Down
81 changes: 81 additions & 0 deletions pkg/app/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,87 @@ COMMANDS
--version=VERSION Number of service version
-n, --name=NAME The name of the FTP logging object
logging splunk create --name=NAME --version=VERSION --url=URL [<flags>]
Create a Splunk logging endpoint on a Fastly service version
-n, --name=NAME The name of the Splunk logging object. Used
as a primary key for API access
-s, --service-id=SERVICE-ID Service ID
--version=VERSION Number of service version
--url=URL The URL to POST to
--tls-ca-cert=TLS-CA-CERT A secure certificate to authenticate the
server with. Must be in PEM format
--tls-hostname=TLS-HOSTNAME
The hostname used to verify the server's
certificate. It can either be the Common Name
or a Subject Alternative Name (SAN)
--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
--placement=PLACEMENT Where in the generated VCL the logging call
should be placed, overriding any
format_version default. Can be none or
waf_debug
--auth-token=AUTH-TOKEN A Splunk token for use in posting logs over
HTTP to your collector
logging splunk list --version=VERSION [<flags>]
List Splunk endpoints on a Fastly service version
-s, --service-id=SERVICE-ID Service ID
--version=VERSION Number of service version
logging splunk describe --version=VERSION --name=NAME [<flags>]
Show detailed information about a Splunk 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 Splunk logging object
logging splunk update --version=VERSION --name=NAME [<flags>]
Update a Splunk 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 Splunk logging object
--new-name=NEW-NAME New name of the Splunk logging object
--url=URL The URL to POST to.
--tls-ca-cert=TLS-CA-CERT A secure certificate to authenticate the
server with. Must be in PEM format
--tls-hostname=TLS-HOSTNAME
The hostname used to verify the server's
certificate. It can either be the Common Name
or a Subject Alternative Name (SAN)
--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
--placement=PLACEMENT Where in the generated VCL the logging call
should be placed, overriding any
format_version default. Can be none or
waf_debug. This field is not required and has
no default value
--auth-token=AUTH-TOKEN
logging splunk delete --version=VERSION --name=NAME [<flags>]
Delete a Splunk 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 Splunk logging object
stats regions
List stats regions
Expand Down
60 changes: 60 additions & 0 deletions pkg/logging/splunk/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package splunk

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 Splunk logging endpoints.
type CreateCommand struct {
common.Base
manifest manifest.Data
Input fastly.CreateSplunkInput
}

// 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 Splunk logging endpoint on a Fastly service version").Alias("add")

c.CmdClause.Flag("name", "The name of the Splunk logging object. Used as a primary key for API access").Short('n').Required().StringVar(&c.Input.Name)
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("url", "The URL to POST to").Required().StringVar(&c.Input.URL)

c.CmdClause.Flag("tls-ca-cert", "A secure certificate to authenticate the server with. Must be in PEM format").StringVar(&c.Input.TLSCACert)
c.CmdClause.Flag("tls-hostname", "The hostname used to verify the server's certificate. It can either be the Common Name or a Subject Alternative Name (SAN)").StringVar(&c.Input.TLSHostname)
c.CmdClause.Flag("format", "Apache style log formatting").StringVar(&c.Input.Format)
c.CmdClause.Flag("format-version", "The version of the custom logging format used for the configured endpoint. Can be either 2 (default) or 1").UintVar(&c.Input.FormatVersion)
c.CmdClause.Flag("response-condition", "The name of an existing condition in the configured endpoint, or leave blank to always execute").StringVar(&c.Input.ResponseCondition)
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").StringVar(&c.Input.Placement)
c.CmdClause.Flag("auth-token", "A Splunk token for use in posting logs over HTTP to your collector").StringVar(&c.Input.Token)

return &c
}

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

d, err := c.Globals.Client.CreateSplunk(&c.Input)
if err != nil {
return err
}

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

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 Splunk logging endpoints.
type DeleteCommand struct {
common.Base
manifest manifest.Data
Input fastly.DeleteSplunkInput
}

// 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 Splunk 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 Splunk 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.DeleteSplunk(&c.Input); err != nil {
return err
}

text.Success(out, "Deleted Splunk logging endpoint %s (service %s version %d)", c.Input.Name, c.Input.Service, c.Input.Version)
return nil
}
59 changes: 59 additions & 0 deletions pkg/logging/splunk/describe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package splunk

import (
"fmt"
"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/go-fastly/fastly"
)

// DescribeCommand calls the Fastly API to describe a Splunk logging endpoint.
type DescribeCommand struct {
common.Base
manifest manifest.Data
Input fastly.GetSplunkInput
}

// NewDescribeCommand returns a usable command registered under the parent.
func NewDescribeCommand(parent common.Registerer, globals *config.Data) *DescribeCommand {
var c DescribeCommand
c.Globals = globals
c.manifest.File.Read(manifest.Filename)
c.CmdClause = parent.Command("describe", "Show detailed information about a Splunk logging endpoint on a Fastly service version").Alias("get")
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 Splunk logging object").Short('d').Required().StringVar(&c.Input.Name)
return &c
}

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

splunk, err := c.Globals.Client.GetSplunk(&c.Input)
if err != nil {
return err
}

fmt.Fprintf(out, "Service ID: %s\n", splunk.ServiceID)
fmt.Fprintf(out, "Version: %d\n", splunk.Version)
fmt.Fprintf(out, "Name: %s\n", splunk.Name)
fmt.Fprintf(out, "URL: %s\n", splunk.URL)
fmt.Fprintf(out, "Token: %s\n", splunk.Token)
fmt.Fprintf(out, "TLS CA certificate: %s\n", splunk.TLSCACert)
fmt.Fprintf(out, "TLS hostname: %s\n", splunk.TLSHostname)
fmt.Fprintf(out, "Format: %s\n", splunk.Format)
fmt.Fprintf(out, "Format version: %d\n", splunk.FormatVersion)
fmt.Fprintf(out, "Response condition: %s\n", splunk.ResponseCondition)
fmt.Fprintf(out, "Placement: %s\n", splunk.Placement)

return nil
}
3 changes: 3 additions & 0 deletions pkg/logging/splunk/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package splunk contains commands to inspect and manipulate Fastly service Splunk
// logging endpoints.
package splunk
75 changes: 75 additions & 0 deletions pkg/logging/splunk/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package splunk

import (
"fmt"
"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"
)

// ListCommand calls the Fastly API to list Splunk logging endpoints.
type ListCommand struct {
common.Base
manifest manifest.Data
Input fastly.ListSplunksInput
}

// NewListCommand returns a usable command registered under the parent.
func NewListCommand(parent common.Registerer, globals *config.Data) *ListCommand {
var c ListCommand
c.Globals = globals
c.manifest.File.Read(manifest.Filename)
c.CmdClause = parent.Command("list", "List Splunk endpoints on a Fastly service version")
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)
return &c
}

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

splunks, err := c.Globals.Client.ListSplunks(&c.Input)
if err != nil {
return err
}

if !c.Globals.Verbose() {
tw := text.NewTable(out)
tw.AddHeader("SERVICE", "VERSION", "NAME")
for _, splunk := range splunks {
tw.AddLine(splunk.ServiceID, splunk.Version, splunk.Name)
}
tw.Print()
return nil
}

fmt.Fprintf(out, "Service ID: %s\n", c.Input.Service)
fmt.Fprintf(out, "Version: %d\n", c.Input.Version)
for i, splunk := range splunks {
fmt.Fprintf(out, "\tSplunk %d/%d\n", i+1, len(splunks))
fmt.Fprintf(out, "\t\tService ID: %s\n", splunk.ServiceID)
fmt.Fprintf(out, "\t\tVersion: %d\n", splunk.Version)
fmt.Fprintf(out, "\t\tName: %s\n", splunk.Name)
fmt.Fprintf(out, "\t\tURL: %s\n", splunk.URL)
fmt.Fprintf(out, "\t\tToken: %s\n", splunk.Token)
fmt.Fprintf(out, "\t\tTLS CA certificate: %s\n", splunk.TLSCACert)
fmt.Fprintf(out, "\t\tTLS hostname: %s\n", splunk.TLSHostname)
fmt.Fprintf(out, "\t\tFormat: %s\n", splunk.Format)
fmt.Fprintf(out, "\t\tFormat version: %d\n", splunk.FormatVersion)
fmt.Fprintf(out, "\t\tResponse condition: %s\n", splunk.ResponseCondition)
fmt.Fprintf(out, "\t\tPlacement: %s\n", splunk.Placement)
}
fmt.Fprintln(out)

return nil
}
Loading

0 comments on commit c9c25eb

Please sign in to comment.