firewall_rulesets.go raw
1 package linodego
2
3 import (
4 "context"
5 "encoding/json"
6 "time"
7
8 "github.com/linode/linodego/internal/parseabletime"
9 )
10
11 // FirewallRuleSetType represents the type of rules a Rule Set contains.
12 // Valid values are "inbound" and "outbound".
13 type FirewallRuleSetType string
14
15 const (
16 FirewallRuleSetTypeInbound FirewallRuleSetType = "inbound"
17 FirewallRuleSetTypeOutbound FirewallRuleSetType = "outbound"
18 )
19
20 // RuleSet represents the Rule Set resource.
21 // Note: created/updated/deleted are parsed via UnmarshalJSON into time.Time pointers.
22 type RuleSet struct {
23 ID int `json:"id"`
24 Label string `json:"label"`
25 Description string `json:"description,omitempty"`
26 Type FirewallRuleSetType `json:"type"`
27 Rules []FirewallRule `json:"rules"`
28 IsServiceDefined bool `json:"is_service_defined"`
29 Version int `json:"version"`
30
31 Created *time.Time `json:"-"`
32 Updated *time.Time `json:"-"`
33 Deleted *time.Time `json:"-"`
34 }
35
36 // UnmarshalJSON implements custom timestamp parsing for RuleSet.
37 func (r *RuleSet) UnmarshalJSON(b []byte) error {
38 type Mask RuleSet
39
40 aux := struct {
41 *Mask
42
43 Created *parseabletime.ParseableTime `json:"created"`
44 Updated *parseabletime.ParseableTime `json:"updated"`
45 Deleted *parseabletime.ParseableTime `json:"deleted"`
46 }{
47 Mask: (*Mask)(r),
48 }
49
50 if err := json.Unmarshal(b, &aux); err != nil {
51 return err
52 }
53
54 if aux.Created != nil {
55 r.Created = (*time.Time)(aux.Created)
56 }
57
58 if aux.Updated != nil {
59 r.Updated = (*time.Time)(aux.Updated)
60 }
61
62 if aux.Deleted != nil {
63 r.Deleted = (*time.Time)(aux.Deleted)
64 }
65
66 return nil
67 }
68
69 // RuleSetCreateOptions fields accepted by CreateRuleSet.
70 type RuleSetCreateOptions struct {
71 Label string `json:"label"`
72 Description string `json:"description,omitempty"`
73 Type FirewallRuleSetType `json:"type"`
74 Rules []FirewallRule `json:"rules"`
75 }
76
77 // RuleSetUpdateOptions fields accepted by UpdateRuleSet.
78 // Omit a top-level field to leave it unchanged. If Rules is provided, it
79 // replaces the entire ordered rules array.
80 type RuleSetUpdateOptions struct {
81 Label *string `json:"label,omitempty"`
82 Description *string `json:"description,omitempty"`
83 Rules *[]FirewallRule `json:"rules,omitempty"`
84 }
85
86 // ListFirewallRuleSets returns a paginated list of Rule Sets.
87 // Supports filtering (e.g., by label) via ListOptions.Filter.
88 func (c *Client) ListFirewallRuleSets(ctx context.Context, opts *ListOptions) ([]RuleSet, error) {
89 return getPaginatedResults[RuleSet](ctx, c, "networking/firewalls/rulesets", opts)
90 }
91
92 // CreateFirewallRuleSet creates a new Rule Set.
93 func (c *Client) CreateFirewallRuleSet(ctx context.Context, opts RuleSetCreateOptions) (*RuleSet, error) {
94 return doPOSTRequest[RuleSet](ctx, c, "networking/firewalls/rulesets", opts)
95 }
96
97 // GetFirewallRuleSet fetches a Rule Set by ID.
98 func (c *Client) GetFirewallRuleSet(ctx context.Context, rulesetID int) (*RuleSet, error) {
99 e := formatAPIPath("networking/firewalls/rulesets/%d", rulesetID)
100 return doGETRequest[RuleSet](ctx, c, e)
101 }
102
103 // UpdateFirewallRuleSet updates a Rule Set by ID.
104 func (c *Client) UpdateFirewallRuleSet(ctx context.Context, rulesetID int, opts RuleSetUpdateOptions) (*RuleSet, error) {
105 e := formatAPIPath("networking/firewalls/rulesets/%d", rulesetID)
106 return doPUTRequest[RuleSet](ctx, c, e, opts)
107 }
108
109 // DeleteFirewallRuleSet deletes a Rule Set by ID.
110 func (c *Client) DeleteFirewallRuleSet(ctx context.Context, rulesetID int) error {
111 e := formatAPIPath("networking/firewalls/rulesets/%d", rulesetID)
112 return doDELETERequest(ctx, c, e)
113 }
114