Skip to content

Commit

Permalink
logging: adds HTTPS logging endpoint support
Browse files Browse the repository at this point in the history
  • Loading branch information
mccurdyc committed May 28, 2020
1 parent 9e87b29 commit f9d47ef
Show file tree
Hide file tree
Showing 13 changed files with 1,540 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 @@ -172,6 +172,12 @@ type Interface interface {
UpdateDatadog(*fastly.UpdateDatadogInput) (*fastly.Datadog, error)
DeleteDatadog(*fastly.DeleteDatadogInput) error

CreateHTTPS(*fastly.CreateHTTPSInput) (*fastly.HTTPS, error)
ListHTTPS(*fastly.ListHTTPSInput) ([]*fastly.HTTPS, error)
GetHTTPS(*fastly.GetHTTPSInput) (*fastly.HTTPS, error)
UpdateHTTPS(*fastly.UpdateHTTPSInput) (*fastly.HTTPS, error)
DeleteHTTPS(*fastly.DeleteHTTPSInput) 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 @@ -29,6 +29,7 @@ import (
"github.com/fastly/cli/pkg/logging/gcs"
"github.com/fastly/cli/pkg/logging/heroku"
"github.com/fastly/cli/pkg/logging/honeycomb"
"github.com/fastly/cli/pkg/logging/https"
"github.com/fastly/cli/pkg/logging/logentries"
"github.com/fastly/cli/pkg/logging/loggly"
"github.com/fastly/cli/pkg/logging/logshuttle"
Expand Down Expand Up @@ -279,6 +280,13 @@ func Run(args []string, env config.Environment, file config.File, configFilePath
datadogUpdate := datadog.NewUpdateCommand(datadogRoot.CmdClause, &globals)
datadogDelete := datadog.NewDeleteCommand(datadogRoot.CmdClause, &globals)

httpsRoot := https.NewRootCommand(loggingRoot.CmdClause, &globals)
httpsCreate := https.NewCreateCommand(httpsRoot.CmdClause, &globals)
httpsList := https.NewListCommand(httpsRoot.CmdClause, &globals)
httpsDescribe := https.NewDescribeCommand(httpsRoot.CmdClause, &globals)
httpsUpdate := https.NewUpdateCommand(httpsRoot.CmdClause, &globals)
httpsDelete := https.NewDeleteCommand(httpsRoot.CmdClause, &globals)

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

httpsRoot,
httpsCreate,
httpsList,
httpsDescribe,
httpsUpdate,
httpsDelete,

statsRoot,
statsRegions,
statsHistorical,
Expand Down
141 changes: 141 additions & 0 deletions pkg/app/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2334,6 +2334,147 @@ COMMANDS
--version=VERSION Number of service version
-n, --name=NAME The name of the Datadog logging object
logging https create --name=NAME --version=VERSION --url=URL [<flags>]
Create an HTTPS logging endpoint on a Fastly service version
-n, --name=NAME The name of the HTTPS 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 URL that log data will be sent to. Must use
the https protocol
--content-type=CONTENT-TYPE
Content type of the header sent with the
request
--header-name=HEADER-NAME Name of the custom header sent with the
request
--header-value=HEADER-VALUE
Value of the custom header sent with the
request
--method=METHOD HTTP method used for request. Can be POST or
PUT. Defaults to POST if not specified
--json-format=JSON-FORMAT Enforces valid JSON formatting for log
entries. Can be disabled 0, array of json
(wraps JSON log batches in an array) 1, or
newline delimited json (places each JSON log
entry onto a new line in a batch) 2
--tls-ca-cert=TLS-CA-CERT A secure certificate to authenticate the
server with. Must be in PEM format
--tls-client-cert=TLS-CLIENT-CERT
The client certificate used to make
authenticated requests. Must be in PEM format
--tls-client-key=TLS-CLIENT-KEY
The client private key used to make
authenticated requests. 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)
--message-type=MESSAGE-TYPE
How the message should be formatted. One of:
classic (default), loggly, logplex or blank
--format=FORMAT Apache style log formatting. Your log must
produce valid JSON that HTTPS can ingest
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(default) or 1
--placement=PLACEMENT Where in the generated VCL the logging call
should be placed, overriding any
format_version default. Can be none or
waf_debug
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
--request-max-entries=REQUEST-MAX-ENTRIES
Maximum number of logs to append to a batch,
if non-zero. Defaults to 0 for unbounded
--request-max-bytes=REQUEST-MAX-BYTES
Maximum size of log batch, if non-zero.
Defaults to 0 for unbounded
logging https list --version=VERSION [<flags>]
List HTTPS endpoints on a Fastly service version
-s, --service-id=SERVICE-ID Service ID
--version=VERSION Number of service version
logging https describe --version=VERSION --name=NAME [<flags>]
Show detailed information about an HTTPS 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 HTTPS logging object
logging https update --version=VERSION --name=NAME [<flags>]
Update an HTTPS 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 HTTPS logging object
--new-name=NEW-NAME New name of the HTTPS logging object
--url=URL URL that log data will be sent to. Must use
the https protocol
--content-type=CONTENT-TYPE
Content type of the header sent with the
request
--header-name=HEADER-NAME Name of the custom header sent with the
request
--header-value=HEADER-VALUE
Value of the custom header sent with the
request
--method=METHOD HTTP method used for request. Can be POST or
PUT. Defaults to POST if not specified
--json-format=JSON-FORMAT Enforces valid JSON formatting for log
entries. Can be disabled 0, array of json
(wraps JSON log batches in an array) 1, or
newline delimited json (places each JSON log
entry onto a new line in a batch) 2
--tls-ca-cert=TLS-CA-CERT A secure certificate to authenticate the
server with. Must be in PEM format
--tls-client-cert=TLS-CLIENT-CERT
The client certificate used to make
authenticated requests. Must be in PEM format
--tls-client-key=TLS-CLIENT-KEY
The client private key used to make
authenticated requests. 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)
--message-type=MESSAGE-TYPE
How the message should be formatted. One of:
classic (default), loggly, logplex or blank
--format=FORMAT Apache style log formatting. Your log must
produce valid JSON that HTTPS can ingest
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(default) or 1
--placement=PLACEMENT Where in the generated VCL the logging call
should be placed, overriding any
format_version default. Can be none or
waf_debug
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
--request-max-entries=REQUEST-MAX-ENTRIES
Maximum number of logs to append to a batch,
if non-zero. Defaults to 0 for unbounded
--request-max-bytes=REQUEST-MAX-BYTES
Maximum size of log batch, if non-zero.
Defaults to 0 for unbounded
logging https delete --version=VERSION --name=NAME [<flags>]
Delete an HTTPS 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 HTTPS logging object
stats regions
List stats regions
Expand Down
171 changes: 171 additions & 0 deletions pkg/logging/https/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package https

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 HTTPS logging endpoints.
type CreateCommand struct {
common.Base
manifest manifest.Data

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

// optional
RequestMaxEntries common.OptionalUint
RequestMaxBytes common.OptionalUint
TLSCACert common.OptionalString
TLSClientCert common.OptionalString
TLSClientKey common.OptionalString
TLSHostname common.OptionalString
MessageType common.OptionalString
ContentType common.OptionalString
HeaderName common.OptionalString
HeaderValue common.OptionalString
Method common.OptionalString
JSONFormat common.OptionalString
Format common.OptionalString
FormatVersion common.OptionalUint
Placement common.OptionalString
ResponseCondition 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 an HTTPS logging endpoint on a Fastly service version").Alias("add")

c.CmdClause.Flag("name", "The name of the HTTPS 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("url", "URL that log data will be sent to. Must use the https protocol").Required().StringVar(&c.URL)

c.CmdClause.Flag("content-type", "Content type of the header sent with the request").Action(c.ContentType.Set).StringVar(&c.ContentType.Value)
c.CmdClause.Flag("header-name", "Name of the custom header sent with the request").Action(c.HeaderName.Set).StringVar(&c.HeaderName.Value)
c.CmdClause.Flag("header-value", "Value of the custom header sent with the request").Action(c.HeaderValue.Set).StringVar(&c.HeaderValue.Value)
c.CmdClause.Flag("method", "HTTP method used for request. Can be POST or PUT. Defaults to POST if not specified").Action(c.Method.Set).StringVar(&c.Method.Value)
c.CmdClause.Flag("json-format", "Enforces valid JSON formatting for log entries. Can be disabled 0, array of json (wraps JSON log batches in an array) 1, or newline delimited json (places each JSON log entry onto a new line in a batch) 2").Action(c.JSONFormat.Set).StringVar(&c.JSONFormat.Value)
c.CmdClause.Flag("tls-ca-cert", "A secure certificate to authenticate the server with. Must be in PEM format").Action(c.TLSCACert.Set).StringVar(&c.TLSCACert.Value)
c.CmdClause.Flag("tls-client-cert", "The client certificate used to make authenticated requests. Must be in PEM format").Action(c.TLSClientCert.Set).StringVar(&c.TLSClientCert.Value)
c.CmdClause.Flag("tls-client-key", "The client private key used to make authenticated requests. Must be in PEM format").Action(c.TLSClientKey.Set).StringVar(&c.TLSClientKey.Value)
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)").Action(c.TLSHostname.Set).StringVar(&c.TLSHostname.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", "Apache style log formatting. Your log must produce valid JSON that HTTPS can ingest").Action(c.Format.Set).StringVar(&c.Format.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("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("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("request-max-entries", "Maximum number of logs to append to a batch, if non-zero. Defaults to 0 for unbounded").Action(c.RequestMaxEntries.Set).UintVar(&c.RequestMaxEntries.Value)
c.CmdClause.Flag("request-max-bytes", "Maximum size of log batch, if non-zero. Defaults to 0 for unbounded").Action(c.RequestMaxBytes.Set).UintVar(&c.RequestMaxBytes.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.CreateHTTPSInput, error) {
var input fastly.CreateHTTPSInput

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

input.Service = serviceID
input.Version = c.Version
input.Name = c.EndpointName
input.URL = c.URL

if c.ContentType.Valid {
input.ContentType = c.ContentType.Value
}

if c.HeaderName.Valid {
input.HeaderName = c.HeaderName.Value
}

if c.HeaderValue.Valid {
input.HeaderValue = c.HeaderValue.Value
}

if c.Method.Valid {
input.Method = c.Method.Value
}

if c.JSONFormat.Valid {
input.JSONFormat = c.JSONFormat.Value
}

if c.RequestMaxEntries.Valid {
input.RequestMaxEntries = c.RequestMaxEntries.Value
}

if c.RequestMaxBytes.Valid {
input.RequestMaxBytes = c.RequestMaxBytes.Value
}

if c.TLSCACert.Valid {
input.TLSCACert = c.TLSCACert.Value
}

if c.TLSClientCert.Valid {
input.TLSClientCert = c.TLSClientCert.Value
}

if c.TLSClientKey.Valid {
input.TLSClientKey = c.TLSClientKey.Value
}

if c.TLSHostname.Valid {
input.TLSHostname = c.TLSHostname.Value
}

if c.Format.Valid {
input.Format = c.Format.Value
}

if c.FormatVersion.Valid {
input.FormatVersion = c.FormatVersion.Value
}

if c.ResponseCondition.Valid {
input.ResponseCondition = c.ResponseCondition.Value
}

if c.Placement.Valid {
input.Placement = c.Placement.Value
}

if c.MessageType.Valid {
input.MessageType = c.MessageType.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.CreateHTTPS(input)
if err != nil {
return err
}

text.Success(out, "Created HTTPS logging endpoint %s (service %s version %d)", d.Name, d.ServiceID, d.Version)
return nil
}
Loading

0 comments on commit f9d47ef

Please sign in to comment.