WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
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 @@ -6,6 +6,7 @@

### Enhancements:
- feat(rust): Allow testing with prerelease Rust versions ([#1604](https://github.com/fastly/cli/pull/1604))
- feat(commands/ngwaf/rules): add support for CRUD operations for NGWAF rules ([#1578](https://github.com/fastly/cli/pull/1605))

### Bug fixes:

Expand Down
26 changes: 26 additions & 0 deletions pkg/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import (
"github.com/fastly/cli/pkg/commands/ngwaf/countrylist"
"github.com/fastly/cli/pkg/commands/ngwaf/customsignal"
"github.com/fastly/cli/pkg/commands/ngwaf/iplist"
"github.com/fastly/cli/pkg/commands/ngwaf/rule"
"github.com/fastly/cli/pkg/commands/ngwaf/signallist"
"github.com/fastly/cli/pkg/commands/ngwaf/stringlist"
"github.com/fastly/cli/pkg/commands/ngwaf/wildcardlist"
Expand All @@ -76,6 +77,7 @@ import (
wscustomsignal "github.com/fastly/cli/pkg/commands/ngwaf/workspace/customsignal"
wsiplist "github.com/fastly/cli/pkg/commands/ngwaf/workspace/iplist"
"github.com/fastly/cli/pkg/commands/ngwaf/workspace/redaction"
workspaceRule "github.com/fastly/cli/pkg/commands/ngwaf/workspace/rule"
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"
Expand Down Expand Up @@ -450,6 +452,12 @@ func Define( // nolint:revive // function-length
ngwafIPListGet := iplist.NewGetCommand(ngwafIPListRoot.CmdClause, data)
ngwafIPListList := iplist.NewListCommand(ngwafIPListRoot.CmdClause, data)
ngwafIPListUpdate := iplist.NewUpdateCommand(ngwafIPListRoot.CmdClause, data)
ngwafRuleRoot := rule.NewRootCommand(ngwafRoot.CmdClause, data)
ngwafRuleCreate := rule.NewCreateCommand(ngwafRuleRoot.CmdClause, data)
ngwafRuleDelete := rule.NewDeleteCommand(ngwafRuleRoot.CmdClause, data)
ngwafRuleGet := rule.NewGetCommand(ngwafRuleRoot.CmdClause, data)
ngwafRuleList := rule.NewListCommand(ngwafRuleRoot.CmdClause, data)
ngwafRuleUpdate := rule.NewUpdateCommand(ngwafRuleRoot.CmdClause, data)
ngwafSignalListRoot := signallist.NewRootCommand(ngwafRoot.CmdClause, data)
ngwafSignalListCreate := signallist.NewCreateCommand(ngwafSignalListRoot.CmdClause, data)
ngwafSignalListDelete := signallist.NewDeleteCommand(ngwafSignalListRoot.CmdClause, data)
Expand Down Expand Up @@ -486,6 +494,12 @@ func Define( // nolint:revive // function-length
ngwafWorkspaceIPListGet := wsiplist.NewGetCommand(ngwafWorkspaceIPListRoot.CmdClause, data)
ngwafWorkspaceIPListList := wsiplist.NewListCommand(ngwafWorkspaceIPListRoot.CmdClause, data)
ngwafWorkspaceIPListUpdate := wsiplist.NewUpdateCommand(ngwafWorkspaceIPListRoot.CmdClause, data)
ngwafWorkspaceRuleRoot := workspaceRule.NewRootCommand(ngwafWorkspaceRoot.CmdClause, data)
ngwafWorkspaceRuleCreate := workspaceRule.NewCreateCommand(ngwafWorkspaceRuleRoot.CmdClause, data)
ngwafWorkspaceRuleDelete := workspaceRule.NewDeleteCommand(ngwafWorkspaceRuleRoot.CmdClause, data)
ngwafWorkspaceRuleGet := workspaceRule.NewGetCommand(ngwafWorkspaceRuleRoot.CmdClause, data)
ngwafWorkspaceRuleList := workspaceRule.NewListCommand(ngwafWorkspaceRuleRoot.CmdClause, data)
ngwafWorkspaceRuleUpdate := workspaceRule.NewUpdateCommand(ngwafWorkspaceRuleRoot.CmdClause, data)
ngwafWorkspaceSignalListRoot := wssignallistlist.NewRootCommand(ngwafWorkspaceRoot.CmdClause, data)
ngwafWorkspaceSignalListCreate := wssignallistlist.NewCreateCommand(ngwafWorkspaceSignalListRoot.CmdClause, data)
ngwafWorkspaceSignalListDelete := wssignallistlist.NewDeleteCommand(ngwafWorkspaceSignalListRoot.CmdClause, data)
Expand Down Expand Up @@ -1009,6 +1023,12 @@ func Define( // nolint:revive // function-length
ngwafIPListGet,
ngwafIPListList,
ngwafIPListUpdate,
ngwafRuleRoot,
ngwafRuleCreate,
ngwafRuleDelete,
ngwafRuleGet,
ngwafRuleList,
ngwafRuleUpdate,
ngwafSignalListRoot,
ngwafSignalListCreate,
ngwafSignalListDelete,
Expand Down Expand Up @@ -1044,6 +1064,12 @@ func Define( // nolint:revive // function-length
ngwafWorkspaceIPListGet,
ngwafWorkspaceIPListList,
ngwafWorkspaceIPListUpdate,
ngwafWorkspaceRuleRoot,
ngwafWorkspaceRuleCreate,
ngwafWorkspaceRuleDelete,
ngwafWorkspaceRuleGet,
ngwafWorkspaceRuleList,
ngwafWorkspaceRuleUpdate,
ngwafWorkspaceSignalListRoot,
ngwafWorkspaceSignalListCreate,
ngwafWorkspaceSignalListDelete,
Expand Down
98 changes: 98 additions & 0 deletions pkg/commands/ngwaf/rule/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package rule

import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"path/filepath"

"github.com/fastly/go-fastly/v12/fastly"
"github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/rules"
"github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/scope"

"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 account-level rules.
type CreateCommand struct {
argparser.Base
argparser.JSONOutput

// Required.
path string
}

// 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 an account-level rule").Alias("add")

// Required.
c.CmdClause.Flag("path", "Path to a json file that contains the rule schema.").Required().StringVar(&c.path)

// 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
}
var err error
input := &rules.CreateInput{}
if c.path != "" {
path, err := filepath.Abs(c.path)
if err != nil {
return fmt.Errorf("error parsing path '%s': %q", c.path, err)
}

jsonFile, err := os.Open(path)
if err != nil {
return fmt.Errorf("error reading cert-path '%s': %q", c.path, err)
}
defer jsonFile.Close()

byteValue, err := io.ReadAll(jsonFile)
if err != nil {
return fmt.Errorf("failed to read json file: %v", err)
}

if err := json.Unmarshal(byteValue, input); err != nil {
return fmt.Errorf("failed to unmarshal json data: %v", err)
}
}
input.Scope = &scope.Scope{
Type: scope.ScopeTypeAccount,
AppliesTo: []string{"*"},
}

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

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

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

text.Success(out, "Created account-level rule with ID %s", data.RuleID)
return nil
}
84 changes: 84 additions & 0 deletions pkg/commands/ngwaf/rule/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package rule

import (
"context"
"errors"
"io"

"github.com/fastly/go-fastly/v12/fastly"

"github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/rules"
"github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/scope"

"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 an account-level rule.
type DeleteCommand struct {
argparser.Base
argparser.JSONOutput

// Required.
ruleID string
}

// 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", "Delete an account-level rule")

// Required.
c.CmdClause.Flag("rule-id", "Rule ID").Required().StringVar(&c.ruleID)

// 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
}

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

err := rules.Delete(context.TODO(), fc, &rules.DeleteInput{
RuleID: &c.ruleID,
Scope: &scope.Scope{
Type: scope.ScopeTypeAccount,
AppliesTo: []string{"*"},
},
})
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.ruleID,
true,
}
_, err := c.WriteJSON(out, o)
return err
}

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

import (
"context"
"errors"
"io"

"github.com/fastly/go-fastly/v12/fastly"

"github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/rules"
"github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/scope"

"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 an account-level rule.
type GetCommand struct {
argparser.Base
argparser.JSONOutput

// Required.
ruleID string
}

// 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", "Get an account-level rule")

// Required.
c.CmdClause.Flag("rule-id", "Rule ID").Required().StringVar(&c.ruleID)

// 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
}

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

data, err := rules.Get(context.TODO(), fc, &rules.GetInput{
RuleID: &c.ruleID,
Scope: &scope.Scope{
Type: scope.ScopeTypeAccount,
AppliesTo: []string{"*"},
},
})
if err != nil {
c.Globals.ErrLog.Add(err)
return err
}

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

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