Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- feat(commands/ngwaf/lists): add support for CRUD operations for NGWAF Lists at account and workspace levels ([#1582](https://github.com/fastly/cli/pull/1582))
- feat(commands/ngwaf/workspaces/alerts): add support for operations for NGWAF alerts ([#1589](https://github.com/fastly/cli/pull/1589))
- feat(commands/ngwaf/customsignals): add support for CRUD operations for NGWAF Custom Signals ([#1592](https://github.com/fastly/cli/pull/1592))
- feat(commands/ngwaf/customsignals): add support for CRUD operations for NGWAF Thresholds ([#1595](https://github.com/fastly/cli/pull/1595))

### Bug fixes:
- fix(commands/ngwaf/virtualpatch): ensured a check was in place for the 'update' command that disallowed the --json and --verbose flag to be ran at the same time. ([#1596](https://github.com/fastly/cli/pull/1596))
Expand Down
13 changes: 13 additions & 0 deletions pkg/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import (
"github.com/fastly/cli/pkg/commands/ngwaf/workspace/redaction"
wssignallistlist "github.com/fastly/cli/pkg/commands/ngwaf/workspace/signallist"
wsstringlistlist "github.com/fastly/cli/pkg/commands/ngwaf/workspace/stringlist"
"github.com/fastly/cli/pkg/commands/ngwaf/workspace/threshold"
"github.com/fastly/cli/pkg/commands/ngwaf/workspace/virtualpatch"
wswildcardlistlist "github.com/fastly/cli/pkg/commands/ngwaf/workspace/wildcardlist"
"github.com/fastly/cli/pkg/commands/objectstorage"
Expand Down Expand Up @@ -497,6 +498,12 @@ func Define( // nolint:revive // function-length
ngwafWorkspaceStringListGet := wsstringlistlist.NewGetCommand(ngwafWorkspaceStringListRoot.CmdClause, data)
ngwafWorkspaceStringListList := wsstringlistlist.NewListCommand(ngwafWorkspaceStringListRoot.CmdClause, data)
ngwafWorkspaceStringListUpdate := wsstringlistlist.NewUpdateCommand(ngwafWorkspaceStringListRoot.CmdClause, data)
ngwafWorkspaceThresholdRoot := threshold.NewRootCommand(ngwafWorkspaceRoot.CmdClause, data)
ngwafWorkspaceThresholdCreate := threshold.NewCreateCommand(ngwafWorkspaceThresholdRoot.CmdClause, data)
ngwafWorkspaceThresholdDelete := threshold.NewDeleteCommand(ngwafWorkspaceThresholdRoot.CmdClause, data)
ngwafWorkspaceThresholdGet := threshold.NewGetCommand(ngwafWorkspaceThresholdRoot.CmdClause, data)
ngwafWorkspaceThresholdList := threshold.NewListCommand(ngwafWorkspaceThresholdRoot.CmdClause, data)
ngwafWorkspaceThresholdUpdate := threshold.NewUpdateCommand(ngwafWorkspaceThresholdRoot.CmdClause, data)
ngwafWorkspaceWildcardListRoot := wildcardlist.NewRootCommand(ngwafWorkspaceRoot.CmdClause, data)
ngwafWorkspaceWildcardListCreate := wswildcardlistlist.NewCreateCommand(ngwafWorkspaceWildcardListRoot.CmdClause, data)
ngwafWorkspaceWildcardListDelete := wswildcardlistlist.NewDeleteCommand(ngwafWorkspaceWildcardListRoot.CmdClause, data)
Expand Down Expand Up @@ -1049,6 +1056,12 @@ func Define( // nolint:revive // function-length
ngwafWorkspaceStringListGet,
ngwafWorkspaceStringListList,
ngwafWorkspaceStringListUpdate,
ngwafWorkspaceThresholdRoot,
ngwafWorkspaceThresholdCreate,
ngwafWorkspaceThresholdDelete,
ngwafWorkspaceThresholdGet,
ngwafWorkspaceThresholdList,
ngwafWorkspaceThresholdUpdate,
ngwafWorkspaceWildcardListCreate,
ngwafWorkspaceWildcardListDelete,
ngwafWorkspaceWildcardListGet,
Expand Down
130 changes: 130 additions & 0 deletions pkg/commands/ngwaf/workspace/threshold/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package threshold

import (
"context"
"errors"
"io"

"github.com/fastly/go-fastly/v12/fastly"
"github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/workspaces/thresholds"

"github.com/fastly/cli/pkg/argparser"
fsterr "github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/global"
"github.com/fastly/cli/pkg/text"
)

// CreateCommand calls the Fastly API to create a workspace threshold.
type CreateCommand struct {
argparser.Base
argparser.JSONOutput

// Required.
action string
dontNotify argparser.OptionalString
duration int
enabled argparser.OptionalString
interval int
limit int
name string
signal string
workspaceID argparser.OptionalWorkspaceID

// Optional.
}

// NewCreateCommand returns a usable command registered under the parent.
func NewCreateCommand(parent argparser.Registerer, g *global.Data) *CreateCommand {
c := CreateCommand{
Base: argparser.Base{
Globals: g,
},
}
c.CmdClause = parent.Command("create", "Create a workspace threshold").Alias("add")

// Required.
c.CmdClause.Flag("action", "The action to take when the threshold is exceeded. [block, log]").Required().StringVar(&c.action)
c.CmdClause.Flag("do-not-notify", "Whether to silence notifications when action is taken. [true, false]").Required().Action(c.dontNotify.Set).StringVar(&c.dontNotify.Value)
c.CmdClause.Flag("duration", "The duration the action is in place in seconds. Default duration is 86,400 seconds (1 day).").Required().IntVar(&c.duration)
c.CmdClause.Flag("enabled", "Whether the threshold is active. [true, false]").Required().Action(c.enabled.Set).StringVar(&c.enabled.Value)
c.CmdClause.Flag("interval", "The threshold interval in seconds. The default interval is 3600 seconds (1 hour).").Required().IntVar(&c.interval)
c.CmdClause.Flag("limit", "The threshold limit. Input must be between 1 and 10000. Default limit is 10.").Required().IntVar(&c.limit)
c.CmdClause.Flag("name", "User submitted display name of a signal threshold. Input must be between 3 and 50 characters").Required().StringVar(&c.name)
c.CmdClause.Flag("signal", "The name of the signal this threshold is acting on").Required().StringVar(&c.signal)
c.RegisterFlag(argparser.StringFlagOpts{
Name: argparser.FlagNGWAFWorkspaceID,
Description: argparser.FlagNGWAFWorkspaceIDDesc,
Dst: &c.workspaceID.Value,
Action: c.workspaceID.Set,
})

// Optional.
c.RegisterFlagBool(c.JSONFlag())

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
}
// Call Parse() to ensure that we check if workspaceID
// is set or to throw the appropriate error.
if err := c.workspaceID.Parse(); err != nil {
return err
}

var enabled bool
switch c.enabled.Value {
case "true":
enabled = true
case "false":
enabled = false
default:
err := errors.New("'enabled' flag must be one of the following [true, false]")
c.Globals.ErrLog.Add(err)
return err
}

var dontNotify bool
Comment thread
rcaril marked this conversation as resolved.
switch c.dontNotify.Value {
case "true":
dontNotify = true
case "false":
dontNotify = false
default:
err := errors.New("'do-not-notify' flag must be one of the following [true, false]")
c.Globals.ErrLog.Add(err)
return err
}

input := &thresholds.CreateInput{
Action: &c.action,
Duration: &c.duration,
Enabled: &enabled,
Interval: &c.interval,
Limit: &c.limit,
Name: &c.name,
DontNotify: &dontNotify,
Signal: &c.signal,
WorkspaceID: &c.workspaceID.Value,
}

fc, ok := c.Globals.APIClient.(*fastly.Client)
if !ok {
return errors.New("failed to convert interface to a fastly client")
}

data, err := thresholds.Create(context.TODO(), fc, input)
if err != nil {
return err
}

if ok, err := c.WriteJSON(out, data); ok {
return err
}

text.Success(out, "Created threshold '%s' for workspace '%s'", data.ThresholdID, c.workspaceID.Value)
return nil
}
92 changes: 92 additions & 0 deletions pkg/commands/ngwaf/workspace/threshold/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package threshold

import (
"context"
"errors"
"io"

"github.com/fastly/go-fastly/v12/fastly"
"github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/workspaces/thresholds"

"github.com/fastly/cli/pkg/argparser"
fsterr "github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/global"
"github.com/fastly/cli/pkg/text"
)

// DeleteCommand calls the Fastly API to delete a workspace threshold.
type DeleteCommand struct {
argparser.Base
argparser.JSONOutput

// Required.
thresholdID string
workspaceID argparser.OptionalWorkspaceID

// Optional.
}

// NewDeleteCommand returns a usable command registered under the parent.
func NewDeleteCommand(parent argparser.Registerer, g *global.Data) *DeleteCommand {
c := DeleteCommand{
Base: argparser.Base{
Globals: g,
},
}
c.CmdClause = parent.Command("delete", "Deletes a workspace threshold")

// Required.
c.RegisterFlag(argparser.StringFlagOpts{
Name: argparser.FlagNGWAFWorkspaceID,
Description: argparser.FlagNGWAFWorkspaceIDDesc,
Dst: &c.workspaceID.Value,
Action: c.workspaceID.Set,
})
c.CmdClause.Flag("threshold-id", "Threshold ID").Required().StringVar(&c.thresholdID)

// Optional.
c.RegisterFlagBool(c.JSONFlag())

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
}
// Call Parse() to ensure that we check if workspaceID
// is set or to throw the appropriate error.
if err := c.workspaceID.Parse(); err != nil {
return err
}

fc, ok := c.Globals.APIClient.(*fastly.Client)
if !ok {
return errors.New("failed to convert interface to a fastly client")
}

err := thresholds.Delete(context.TODO(), fc, &thresholds.DeleteInput{
ThresholdID: &c.thresholdID,
WorkspaceID: &c.workspaceID.Value,
})
if err != nil {
c.Globals.ErrLog.Add(err)
return err
}

if c.JSONOutput.Enabled {
o := struct {
ID string `json:"id"`
Deleted bool `json:"deleted"`
}{
c.thresholdID,
true,
}
_, err := c.WriteJSON(out, o)
return err
}

text.Success(out, "Deleted threshold (id: %s)", c.thresholdID)
return nil
}
2 changes: 2 additions & 0 deletions pkg/commands/ngwaf/workspace/threshold/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package threshold contains commands to inspect and manipulate NGWAF workspace thresholds.
package threshold
84 changes: 84 additions & 0 deletions pkg/commands/ngwaf/workspace/threshold/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package threshold

import (
"context"
"errors"
"io"

"github.com/fastly/go-fastly/v12/fastly"
"github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/workspaces/thresholds"

"github.com/fastly/cli/pkg/argparser"
fsterr "github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/global"
"github.com/fastly/cli/pkg/text"
)

// GetCommand calls the Fastly API to get a workspace threshold.
type GetCommand struct {
argparser.Base
argparser.JSONOutput

// Required.
thresholdID string
workspaceID argparser.OptionalWorkspaceID

// Optional.
}

// NewGetCommand returns a usable command registered under the parent.
func NewGetCommand(parent argparser.Registerer, g *global.Data) *GetCommand {
c := GetCommand{
Base: argparser.Base{
Globals: g,
},
}
c.CmdClause = parent.Command("get", "Retrieves a workspace threshold")

// Required.
c.RegisterFlag(argparser.StringFlagOpts{
Name: argparser.FlagNGWAFWorkspaceID,
Description: argparser.FlagNGWAFWorkspaceIDDesc,
Dst: &c.workspaceID.Value,
Action: c.workspaceID.Set,
})
c.CmdClause.Flag("threshold-id", "Threshold ID").Required().StringVar(&c.thresholdID)

// Optional.
c.RegisterFlagBool(c.JSONFlag())

return &c
}

// Exec invokes the application logic for the command.
func (c *GetCommand) Exec(_ io.Reader, out io.Writer) error {
if c.Globals.Verbose() && c.JSONOutput.Enabled {
return fsterr.ErrInvalidVerboseJSONCombo
}
// Call Parse() to ensure that we check if workspaceID
// is set or to throw the appropriate error.
if err := c.workspaceID.Parse(); err != nil {
return err
}
input := &thresholds.GetInput{
ThresholdID: &c.thresholdID,
WorkspaceID: &c.workspaceID.Value,
}

fc, ok := c.Globals.APIClient.(*fastly.Client)
if !ok {
return errors.New("failed to convert interface to a fastly client")
}

data, err := thresholds.Get(context.TODO(), fc, input)
if err != nil {
return err
}

if ok, err := c.WriteJSON(out, data); ok {
return err
}

text.PrintThreshold(out, data)
return nil
}
Loading