package govultr import ( "context" "fmt" "net/http" "github.com/google/go-querystring/query" ) // FireWallRuleService is the interface to interact with the firewall rule endpoints on the Vultr API // Link : https://www.vultr.com/api/#tag/firewall type FireWallRuleService interface { Create(ctx context.Context, fwGroupID string, fwRuleReq *FirewallRuleReq) (*FirewallRule, error) Get(ctx context.Context, fwGroupID string, fwRuleID int) (*FirewallRule, error) Delete(ctx context.Context, fwGroupID string, fwRuleID int) error List(ctx context.Context, fwGroupID string, options *ListOptions) ([]FirewallRule, *Meta, error) } // FireWallRuleServiceHandler handles interaction with the firewall rule methods for the Vultr API type FireWallRuleServiceHandler struct { client *Client } // FirewallRule represents a Vultr firewall rule type FirewallRule struct { ID int `json:"id"` Action string `json:"action"` // Deprecated: Type should no longer be used. Instead, use IPType. Type string `json:"type"` IPType string `json:"ip_type"` Protocol string `json:"protocol"` Port string `json:"port"` Subnet string `json:"subnet"` SubnetSize int `json:"subnet_size"` Source string `json:"source"` Notes string `json:"notes"` } // FirewallRuleReq struct used to create a FirewallRule. type FirewallRuleReq struct { IPType string `json:"ip_type"` Protocol string `json:"protocol"` Subnet string `json:"subnet"` SubnetSize int `json:"subnet_size"` Port string `json:"port,omitempty"` Source string `json:"source,omitempty"` Notes string `json:"notes,omitempty"` } type firewallRulesBase struct { FirewallRules []FirewallRule `json:"firewall_rules"` Meta *Meta `json:"meta"` } type firewallRuleBase struct { FirewallRule *FirewallRule `json:"firewall_rule"` } // Create will create a rule in a firewall group. func (f *FireWallRuleServiceHandler) Create(ctx context.Context, fwGroupID string, fwRuleReq *FirewallRuleReq) (*FirewallRule, error) { uri := fmt.Sprintf("/v2/firewalls/%s/rules", fwGroupID) req, err := f.client.NewRequest(ctx, http.MethodPost, uri, fwRuleReq) if err != nil { return nil, err } firewallRule := new(firewallRuleBase) if err = f.client.DoWithContext(ctx, req, firewallRule); err != nil { return nil, err } return firewallRule.FirewallRule, nil } // Get will get a rule in a firewall group. func (f *FireWallRuleServiceHandler) Get(ctx context.Context, fwGroupID string, fwRuleID int) (*FirewallRule, error) { uri := fmt.Sprintf("/v2/firewalls/%s/rules/%d", fwGroupID, fwRuleID) req, err := f.client.NewRequest(ctx, http.MethodGet, uri, nil) if err != nil { return nil, err } firewallRule := new(firewallRuleBase) if err = f.client.DoWithContext(ctx, req, firewallRule); err != nil { return nil, err } return firewallRule.FirewallRule, nil } // Delete will delete a firewall rule on your Vultr account func (f *FireWallRuleServiceHandler) Delete(ctx context.Context, fwGroupID string, fwRuleID int) error { uri := fmt.Sprintf("/v2/firewalls/%s/rules/%d", fwGroupID, fwRuleID) req, err := f.client.NewRequest(ctx, http.MethodDelete, uri, nil) if err != nil { return err } return f.client.DoWithContext(ctx, req, nil) } // List will return both ipv4 an ipv6 firewall rules that are defined within a firewall group func (f *FireWallRuleServiceHandler) List(ctx context.Context, fwGroupID string, options *ListOptions) ([]FirewallRule, *Meta, error) { uri := fmt.Sprintf("/v2/firewalls/%s/rules", fwGroupID) req, err := f.client.NewRequest(ctx, http.MethodGet, uri, nil) if err != nil { return nil, nil, err } newValues, err := query.Values(options) if err != nil { return nil, nil, err } req.URL.RawQuery = newValues.Encode() firewallRule := new(firewallRulesBase) if err = f.client.DoWithContext(ctx, req, firewallRule); err != nil { return nil, nil, err } return firewallRule.FirewallRules, firewallRule.Meta, nil }