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