Skip to content

Commit

Permalink
fix: creating firewall with rules not working correctly
Browse files Browse the repository at this point in the history
Because the Firewall API expects a different JSON formatting than it responds with (some fields must be omitted even though they are included in the response) we have to create another struct to marshal rules properly.

See hetznercloud/cli#725
  • Loading branch information
phm07 committed Apr 19, 2024
1 parent 485f525 commit 19dc460
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 43 deletions.
29 changes: 1 addition & 28 deletions hcloud/firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,34 +298,7 @@ type FirewallSetRulesOpts struct {

// SetRules sets the rules of a Firewall.
func (c *FirewallClient) SetRules(ctx context.Context, firewall *Firewall, opts FirewallSetRulesOpts) ([]*Action, *Response, error) {
s := firewallSetRulesOptsToSchema(opts)

// We can't use the FirewallRule struct here, because unlike in the response some fields must be omitted when empty.
type firewallRule struct {
Direction string `json:"direction"`
SourceIPs []string `json:"source_ips,omitempty"`
DestinationIPs []string `json:"destination_ips,omitempty"`
Protocol string `json:"protocol"`
Port *string `json:"port,omitempty"`
Description *string `json:"description,omitempty"`
}

rules := make([]firewallRule, 0, len(s.Rules))
for _, r := range s.Rules {
rules = append(rules, firewallRule{
Direction: r.Direction,
SourceIPs: r.SourceIPs,
DestinationIPs: r.DestinationIPs,
Protocol: r.Protocol,
Port: r.Port,
Description: r.Description,
})
}
reqBody := struct {
Rules []firewallRule `json:"rules"`
}{
Rules: rules,
}
reqBody := firewallSetRulesOptsToSchema(opts)

reqBodyData, err := json.Marshal(reqBody)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions hcloud/firewall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ func TestFirewallSetRules(t *testing.T) {
{
name: "direction in",
expectedReqBody: schema.FirewallActionSetRulesRequest{
Rules: []schema.FirewallRule{
Rules: []schema.FirewallRuleReq{
{
Direction: "in",
SourceIPs: []string{"10.0.0.5/32", "10.0.0.6/32"},
Expand Down Expand Up @@ -358,7 +358,7 @@ func TestFirewallSetRules(t *testing.T) {
{
name: "direction out",
expectedReqBody: schema.FirewallActionSetRulesRequest{
Rules: []schema.FirewallRule{
Rules: []schema.FirewallRuleReq{
{
Direction: "out",
DestinationIPs: []string{"10.0.0.5/32", "10.0.0.6/32"},
Expand Down Expand Up @@ -388,7 +388,7 @@ func TestFirewallSetRules(t *testing.T) {
{
name: "empty",
expectedReqBody: schema.FirewallActionSetRulesRequest{
Rules: []schema.FirewallRule{},
Rules: []schema.FirewallRuleReq{},
},
opts: FirewallSetRulesOpts{
Rules: []FirewallRule{},
Expand All @@ -397,7 +397,7 @@ func TestFirewallSetRules(t *testing.T) {
{
name: "description",
expectedReqBody: schema.FirewallActionSetRulesRequest{
Rules: []schema.FirewallRule{
Rules: []schema.FirewallRuleReq{
{
Direction: "out",
DestinationIPs: []string{"10.0.0.5/32", "10.0.0.6/32"},
Expand Down
16 changes: 13 additions & 3 deletions hcloud/schema/firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Firewall struct {
AppliedTo []FirewallResource `json:"applied_to"`
}

// FirewallRule defines the schema of a Firewall rule.
// FirewallRule defines the schema of a Firewall rule in responses.
type FirewallRule struct {
Direction string `json:"direction"`
SourceIPs []string `json:"source_ips"`
Expand All @@ -22,6 +22,16 @@ type FirewallRule struct {
Description *string `json:"description"`
}

// FirewallRuleReq defines the schema of a Firewall rule in requests.
type FirewallRuleReq struct {
Direction string `json:"direction"`
SourceIPs []string `json:"source_ips,omitempty"`
DestinationIPs []string `json:"destination_ips,omitempty"`
Protocol string `json:"protocol"`
Port *string `json:"port,omitempty"`
Description *string `json:"description,omitempty"`
}

// FirewallListResponse defines the schema of the response when listing Firewalls.
type FirewallListResponse struct {
Firewalls []Firewall `json:"firewalls"`
Expand All @@ -36,7 +46,7 @@ type FirewallGetResponse struct {
type FirewallCreateRequest struct {
Name string `json:"name"`
Labels *map[string]string `json:"labels,omitempty"`
Rules []FirewallRule `json:"rules,omitempty"`
Rules []FirewallRuleReq `json:"rules,omitempty"`
ApplyTo []FirewallResource `json:"apply_to,omitempty"`
}

Expand Down Expand Up @@ -76,7 +86,7 @@ type FirewallUpdateResponse struct {

// FirewallActionSetRulesRequest defines the schema of the request when setting Firewall rules.
type FirewallActionSetRulesRequest struct {
Rules []FirewallRule `json:"rules"`
Rules []FirewallRuleReq `json:"rules"`
}

// FirewallActionSetRulesResponse defines the schema of the response when setting Firewall rules.
Expand Down
40 changes: 32 additions & 8 deletions hcloud/zz_schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 19dc460

Please sign in to comment.