Skip to content

Commit

Permalink
[flarectl] Adds User-Agent blocking to flarectl (cloudflare#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
elithrar authored Oct 6, 2017
1 parent bd2891d commit 14ae67c
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 4 deletions.
108 changes: 105 additions & 3 deletions cmd/flarectl/flarectl.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package main

import (
"errors"
"fmt"
"log"
"os"
"strings"

"github.com/pkg/errors"

"github.com/cloudflare/cloudflare-go"
"github.com/codegangsta/cli"
)
Expand Down Expand Up @@ -75,9 +76,12 @@ func checkFlags(c *cli.Context, flags ...string) error {
for _, flag := range flags {
if c.String(flag) == "" {
cli.ShowSubcommandHelp(c)
return fmt.Errorf("%s not specified", flag)
err := errors.Errorf("error: the required flag %q was empty or not provided", flag)
fmt.Fprintln(os.Stderr, err)
return err
}
}

return nil
}

Expand Down Expand Up @@ -358,7 +362,105 @@ func main() {
},
},
},

{
Name: "user-agents",
Aliases: []string{"ua"},
Usage: "User-Agent blocking",
Subcommands: []cli.Command{
{
Name: "list",
Aliases: []string{"l"},
Action: userAgentList,
Usage: "List User-Agent blocks for a zone",
Flags: []cli.Flag{
cli.StringFlag{
Name: "zone",
Usage: "zone name",
},
cli.IntFlag{
Name: "page",
Usage: "result page to return",
},
},
},
{
Name: "create",
Aliases: []string{"c"},
Action: userAgentCreate,
Usage: "Create a User-Agent blocking rule",
Flags: []cli.Flag{
cli.StringFlag{
Name: "zone",
Usage: "zone name",
},
cli.StringFlag{
Name: "mode",
Usage: "the blocking mode: block, challenge, js_challenge, whitelist",
},
cli.StringFlag{
Name: "value",
Usage: "the exact User-Agent to block",
},
cli.BoolFlag{
Name: "paused",
Usage: "whether the rule should be paused (default: false)",
},
cli.StringFlag{
Name: "description",
Usage: "a description for the rule",
},
},
},
{
Name: "update",
Aliases: []string{"u"},
Action: userAgentUpdate,
Usage: "Update an existing User-Agent block",
Flags: []cli.Flag{
cli.StringFlag{
Name: "zone",
Usage: "zone name",
},
cli.StringFlag{
Name: "id",
Usage: "User-Agent blocking rule ID",
},
cli.StringFlag{
Name: "mode",
Usage: "the blocking mode: block, challenge, js_challenge, whitelist",
},
cli.StringFlag{
Name: "value",
Usage: "the exact User-Agent to block",
},
cli.BoolFlag{
Name: "paused",
Usage: "whether the rule should be paused (default: false)",
},
cli.StringFlag{
Name: "description",
Usage: "a description for the rule",
},
},
},
{
Name: "delete",
Aliases: []string{"d"},
Action: userAgentDelete,
Usage: "Delete a User-Agent block",
Flags: []cli.Flag{
cli.StringFlag{
Name: "zone",
Usage: "zone name",
},
cli.StringFlag{
Name: "id",
Usage: "User-Agent blocking rule ID",
},
},
},
},
},
{
Name: "pagerules",
Aliases: []string{"p"},
Expand Down
158 changes: 158 additions & 0 deletions cmd/flarectl/user_agent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package main

import (
"fmt"
"os"
"strconv"

"github.com/cloudflare/cloudflare-go"
"github.com/codegangsta/cli"
)

func formatUserAgentRule(rule cloudflare.UserAgentRule) table {
return table{
"ID": rule.ID,
"Description": rule.Description,
"Mode": rule.Mode,
"Value": rule.Configuration.Value,
"Paused": strconv.FormatBool(rule.Paused),
}
}

func userAgentCreate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Fprintln(os.Stderr, err)
return
}

if err := checkFlags(c, "zone", "mode", "value"); err != nil {
fmt.Println(err)
return
}

zoneID, err := api.ZoneIDByName(c.String("zone"))
if err != nil {
fmt.Println(err)
return
}

userAgentRule := cloudflare.UserAgentRule{
Description: c.String("description"),
Mode: c.String("mode"),
Paused: c.Bool("paused"),
Configuration: cloudflare.UserAgentRuleConfig{
Target: "ua",
Value: c.String("value"),
},
}

resp, err := api.CreateUserAgentRule(zoneID, userAgentRule)
if err != nil {
fmt.Fprintln(os.Stderr, "Error creating User-Agent block rule: ", err)
return
}

output := []table{
formatUserAgentRule(resp.Result),
}

makeTable(output, "ID", "Description", "Mode", "Value", "Paused")
}

func userAgentUpdate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}

if err := checkFlags(c, "zone", "id", "mode", "value"); err != nil {
return
}

zoneID, err := api.ZoneIDByName(c.String("zone"))
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}

userAgentRule := cloudflare.UserAgentRule{
Description: c.String("description"),
Mode: c.String("mode"),
Paused: c.Bool("paused"),
Configuration: cloudflare.UserAgentRuleConfig{
Target: "ua",
Value: c.String("value"),
},
}

resp, err := api.UpdateUserAgentRule(zoneID, c.String("id"), userAgentRule)
if err != nil {
fmt.Fprintln(os.Stderr, "Error updating User-Agent block rule: ", err)
return
}

output := []table{
formatUserAgentRule(resp.Result),
}

makeTable(output, "ID", "Description", "Mode", "Value", "Paused")
}

func userAgentDelete(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}

if err := checkFlags(c, "zone", "id"); err != nil {
return
}

zoneID, err := api.ZoneIDByName(c.String("zone"))
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}

resp, err := api.DeleteUserAgentRule(zoneID, c.String("id"))
if err != nil {
fmt.Fprintln(os.Stderr, "Error deleting User-Agent block rule: ", err)
return
}

output := []table{
formatUserAgentRule(resp.Result),
}

makeTable(output, "ID", "Description", "Mode", "Value", "Paused")
}

func userAgentList(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}

if err := checkFlags(c, "zone", "page"); err != nil {
return
}

zoneID, err := api.ZoneIDByName(c.String("zone"))
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}

resp, err := api.ListUserAgentRules(zoneID, c.Int("page"))
if err != nil {
fmt.Fprintln(os.Stderr, "Error listing User-Agent block rules: ", err)
return
}

output := make([]table, 0, len(resp.Result))
for _, rule := range resp.Result {
output = append(output, formatUserAgentRule(rule))
}

makeTable(output, "ID", "Description", "Mode", "Value", "Paused")
}
2 changes: 1 addition & 1 deletion user_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (api *API) CreateUserAgentRule(zoneID string, ld UserAgentRule) (*UserAgent
//
// API reference: https://api.cloudflare.com/#user-agent-blocking-rules-update-useragent-rule
func (api *API) UpdateUserAgentRule(zoneID string, id string, ld UserAgentRule) (*UserAgentRuleResponse, error) {
uri := "/zones/" + zoneID + "/firewall/ua_rules"
uri := "/zones/" + zoneID + "/firewall/ua_rules/" + id
res, err := api.makeRequest("PUT", uri, ld)
if err != nil {
return nil, errors.Wrap(err, errMakeRequestError)
Expand Down

0 comments on commit 14ae67c

Please sign in to comment.