Skip to content

Commit

Permalink
feat: support rule-engine commands
Browse files Browse the repository at this point in the history
  • Loading branch information
kulti committed Dec 24, 2024
1 parent 13a7520 commit 089b1a3
Show file tree
Hide file tree
Showing 30 changed files with 912 additions and 2 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.vscode
^enapter3$
enapter3
dist
.DS_Store
.env
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ linters:
# - deadcode
# - depguard
- dogsled
- dupl
# - dupl # some commands are looks very similar in implementation
- errcheck
- errorlint
- exhaustive
Expand Down
35 changes: 35 additions & 0 deletions internal/app/enaptercli/cmd_rule_engine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package enaptercli

import (
"context"
"fmt"
"net/url"

"github.com/urfave/cli/v2"
)

type cmdRuleEngine struct {
cmdBase
}

func buildCmdRuleEngine() *cli.Command {
return &cli.Command{
Name: "rule-engine",
Usage: "Manage the rule engine",
Subcommands: []*cli.Command{
buildCmdRuleEngineInspect(),
buildCmdRuleEngineSuspend(),
buildCmdRuleEngineResume(),
buildCmdRuleEngineRule(),
},
}
}

func (c *cmdRuleEngine) doHTTPRequest(ctx context.Context, p doHTTPRequestParams) error {
path, err := url.JoinPath("/site/rule_engine", p.Path)
if err != nil {
return fmt.Errorf("join path: %w", err)
}
p.Path = path
return c.cmdBase.doHTTPRequest(ctx, p)
}
33 changes: 33 additions & 0 deletions internal/app/enaptercli/cmd_rule_engine_inspect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package enaptercli

import (
"context"
"net/http"

"github.com/urfave/cli/v2"
)

type cmdRuleEngineInspect struct {
cmdRuleEngine
}

func buildCmdRuleEngineInspect() *cli.Command {
cmd := &cmdRuleEngineInspect{}
return &cli.Command{
Name: "inspect",
Usage: "Inspect the rule engine",
CustomHelpTemplate: cmd.HelpTemplate(),
Flags: cmd.Flags(),
Before: cmd.Before,
Action: func(cliCtx *cli.Context) error {
return cmd.do(cliCtx.Context)
},
}
}

func (c *cmdRuleEngineInspect) do(ctx context.Context) error {
return c.doHTTPRequest(ctx, doHTTPRequestParams{
Method: http.MethodGet,
Path: "",
})
}
33 changes: 33 additions & 0 deletions internal/app/enaptercli/cmd_rule_engine_resume.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package enaptercli

import (
"context"
"net/http"

"github.com/urfave/cli/v2"
)

type cmdRuleEngineResume struct {
cmdRuleEngine
}

func buildCmdRuleEngineResume() *cli.Command {
cmd := &cmdRuleEngineResume{}
return &cli.Command{
Name: "resume",
Usage: "Resume execution of rules",
CustomHelpTemplate: cmd.HelpTemplate(),
Flags: cmd.Flags(),
Before: cmd.Before,
Action: func(cliCtx *cli.Context) error {
return cmd.do(cliCtx.Context)
},
}
}

func (c *cmdRuleEngineResume) do(ctx context.Context) error {
return c.doHTTPRequest(ctx, doHTTPRequestParams{
Method: http.MethodPost,
Path: "/resume",
})
}
44 changes: 44 additions & 0 deletions internal/app/enaptercli/cmd_rule_engine_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package enaptercli

import (
"context"
"fmt"
"net/url"

"github.com/urfave/cli/v2"
)

const (
ruleRuntimeVersion1 = 1
ruleRuntimeVersion3 = 3
)

type cmdRuleEngineRule struct {
cmdRuleEngine
}

func buildCmdRuleEngineRule() *cli.Command {
return &cli.Command{
Name: "rule",
Usage: "Manage rules",
Subcommands: []*cli.Command{
buildCmdRuleEngineRuleCreate(),
buildCmdRuleEngineRuleDelete(),
buildCmdRuleEngineRuleDisable(),
buildCmdRuleEngineRuleEnable(),
buildCmdRuleEngineRuleInspect(),
buildCmdRuleEngineRuleList(),
buildCmdRuleEngineRuleUpdate(),
buildCmdRuleEngineRuleUpdateScript(),
},
}
}

func (c *cmdRuleEngineRule) doHTTPRequest(ctx context.Context, p doHTTPRequestParams) error {
path, err := url.JoinPath("/rules", p.Path)
if err != nil {
return fmt.Errorf("join path: %w", err)
}
p.Path = path
return c.cmdRuleEngine.doHTTPRequest(ctx, p)
}
108 changes: 108 additions & 0 deletions internal/app/enaptercli/cmd_rule_engine_rule_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package enaptercli

import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"os"
"time"

"github.com/urfave/cli/v2"
)

type cmdRuleEngineRuleCreate struct {
cmdRuleEngineRule
slug string
name string
scriptPath string
runtimeVersion int
execInterval time.Duration
disable bool
}

func buildCmdRuleEngineRuleCreate() *cli.Command {
cmd := &cmdRuleEngineRuleCreate{}
return &cli.Command{
Name: "create",
Usage: "Create a new rule",
CustomHelpTemplate: cmd.HelpTemplate(),
Flags: cmd.Flags(),
Before: cmd.Before,
Action: func(cliCtx *cli.Context) error {
return cmd.do(cliCtx.Context)
},
}
}

func (c *cmdRuleEngineRuleCreate) Flags() []cli.Flag {
return append(c.cmdRuleEngineRule.Flags(),
&cli.StringFlag{
Name: "slug",
Usage: "Slug of a new rule",
Destination: &c.slug,
Required: true,
},
&cli.StringFlag{
Name: "name",
Usage: "Name of a new rule",
Destination: &c.name,
},
&cli.StringFlag{
Name: "script",
Usage: "Path to a file containing the script code",
Destination: &c.scriptPath,
Required: true,
},
&cli.IntFlag{
Name: "runtime-version",
Usage: "Version of a runtime to use for the script execution",
Destination: &c.runtimeVersion,
Value: ruleRuntimeVersion3,
},
&cli.DurationFlag{
Name: "exec-interval",
Usage: "How often to execute the script. This option is only compatible with the runtime version 1",
Destination: &c.execInterval,
},
&cli.BoolFlag{
Name: "disable",
Usage: "Whether to disable a rule upon creation",
Destination: &c.disable,
},
)
}

func (c *cmdRuleEngineRuleCreate) do(ctx context.Context) error {
if c.scriptPath == "-" {
c.scriptPath = "/dev/stdin"
}
scriptBytes, err := os.ReadFile(c.scriptPath)
if err != nil {
return fmt.Errorf("read script code file: %w", err)
}

body, err := json.Marshal(map[string]any{
"rule": map[string]any{
"slug": c.slug,
"name": c.name,
"script": map[string]any{
"code": base64.StdEncoding.EncodeToString(scriptBytes),
"runtime_version": c.runtimeVersion,
"exec_interval": c.execInterval.String(),
},
},
"disable_rule": c.disable,
})
if err != nil {
return fmt.Errorf("build request: %w", err)
}

return c.doHTTPRequest(ctx, doHTTPRequestParams{
Method: http.MethodPost,
Path: "",
Body: bytes.NewReader(body),
})
}
57 changes: 57 additions & 0 deletions internal/app/enaptercli/cmd_rule_engine_rule_delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package enaptercli

import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"

"github.com/urfave/cli/v2"
)

type cmdRuleEngineRuleDelete struct {
cmdRuleEngineRule
ruleIDs []string
}

func buildCmdRuleEngineRuleDelete() *cli.Command {
cmd := &cmdRuleEngineRuleDelete{}
return &cli.Command{
Name: "delete",
Usage: "Delete one or more rules",
CustomHelpTemplate: cmd.HelpTemplate(),
Flags: cmd.Flags(),
Before: cmd.Before,
Action: func(cliCtx *cli.Context) error {
return cmd.do(cliCtx.Context)
},
}
}

func (c *cmdRuleEngineRuleDelete) Flags() []cli.Flag {
return append(c.cmdRuleEngineRule.Flags(),
&cli.MultiStringFlag{
Target: &cli.StringSliceFlag{
Name: "rule-id",
Usage: "Rule IDs or slugs",
Required: true,
},
Destination: &c.ruleIDs,
},
)
}

func (c *cmdRuleEngineRuleDelete) do(ctx context.Context) error {
body, err := json.Marshal(map[string]any{
"rule_ids": c.ruleIDs,
})
if err != nil {
return fmt.Errorf("build request: %w", err)
}
return c.doHTTPRequest(ctx, doHTTPRequestParams{
Method: http.MethodPost,
Path: "/batch_delete",
Body: bytes.NewReader(body),
})
}
59 changes: 59 additions & 0 deletions internal/app/enaptercli/cmd_rule_engine_rule_disable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package enaptercli

import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"

"github.com/urfave/cli/v2"
)

type cmdRuleEngineRuleDisable struct {
cmdRuleEngineRule
ruleIDs []string
}

func buildCmdRuleEngineRuleDisable() *cli.Command {
cmd := &cmdRuleEngineRuleDisable{}
return &cli.Command{
Name: "disable",
Usage: "Disable one or more rules",
CustomHelpTemplate: cmd.HelpTemplate(),
Flags: cmd.Flags(),
Before: cmd.Before,
Action: func(cliCtx *cli.Context) error {
return cmd.do(cliCtx.Context)
},
}
}

func (c *cmdRuleEngineRuleDisable) Flags() []cli.Flag {
return append(c.cmdRuleEngineRule.Flags(),
&cli.MultiStringFlag{
Target: &cli.StringSliceFlag{
Name: "rule-id",
Usage: "Rule IDs or slugs",
Required: true,
},
Destination: &c.ruleIDs,
},
)
}

func (c *cmdRuleEngineRuleDisable) do(ctx context.Context) error {
body, err := json.Marshal(map[string]any{
"rule_ids": c.ruleIDs,
})
if err != nil {
return fmt.Errorf("build request: %w", err)
}

fmt.Println(c.ruleIDs)
return c.doHTTPRequest(ctx, doHTTPRequestParams{
Method: http.MethodPost,
Path: "/batch_disable",
Body: bytes.NewReader(body),
})
}
Loading

0 comments on commit 089b1a3

Please sign in to comment.