Skip to content

Commit 43b2bab

Browse files
authored
fix: creating firewall with rules not working correctly (#412)
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. This should be reverted once the Firewall API has consistent response and request schemas. See hetznercloud/cli#725
1 parent 485f525 commit 43b2bab

File tree

4 files changed

+53
-46
lines changed

4 files changed

+53
-46
lines changed

hcloud/firewall.go

+1-28
Original file line numberDiff line numberDiff line change
@@ -298,34 +298,7 @@ type FirewallSetRulesOpts struct {
298298

299299
// SetRules sets the rules of a Firewall.
300300
func (c *FirewallClient) SetRules(ctx context.Context, firewall *Firewall, opts FirewallSetRulesOpts) ([]*Action, *Response, error) {
301-
s := firewallSetRulesOptsToSchema(opts)
302-
303-
// We can't use the FirewallRule struct here, because unlike in the response some fields must be omitted when empty.
304-
type firewallRule struct {
305-
Direction string `json:"direction"`
306-
SourceIPs []string `json:"source_ips,omitempty"`
307-
DestinationIPs []string `json:"destination_ips,omitempty"`
308-
Protocol string `json:"protocol"`
309-
Port *string `json:"port,omitempty"`
310-
Description *string `json:"description,omitempty"`
311-
}
312-
313-
rules := make([]firewallRule, 0, len(s.Rules))
314-
for _, r := range s.Rules {
315-
rules = append(rules, firewallRule{
316-
Direction: r.Direction,
317-
SourceIPs: r.SourceIPs,
318-
DestinationIPs: r.DestinationIPs,
319-
Protocol: r.Protocol,
320-
Port: r.Port,
321-
Description: r.Description,
322-
})
323-
}
324-
reqBody := struct {
325-
Rules []firewallRule `json:"rules"`
326-
}{
327-
Rules: rules,
328-
}
301+
reqBody := firewallSetRulesOptsToSchema(opts)
329302

330303
reqBodyData, err := json.Marshal(reqBody)
331304
if err != nil {

hcloud/firewall_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ func TestFirewallSetRules(t *testing.T) {
328328
{
329329
name: "direction in",
330330
expectedReqBody: schema.FirewallActionSetRulesRequest{
331-
Rules: []schema.FirewallRule{
331+
Rules: []schema.FirewallRuleRequest{
332332
{
333333
Direction: "in",
334334
SourceIPs: []string{"10.0.0.5/32", "10.0.0.6/32"},
@@ -358,7 +358,7 @@ func TestFirewallSetRules(t *testing.T) {
358358
{
359359
name: "direction out",
360360
expectedReqBody: schema.FirewallActionSetRulesRequest{
361-
Rules: []schema.FirewallRule{
361+
Rules: []schema.FirewallRuleRequest{
362362
{
363363
Direction: "out",
364364
DestinationIPs: []string{"10.0.0.5/32", "10.0.0.6/32"},
@@ -388,7 +388,7 @@ func TestFirewallSetRules(t *testing.T) {
388388
{
389389
name: "empty",
390390
expectedReqBody: schema.FirewallActionSetRulesRequest{
391-
Rules: []schema.FirewallRule{},
391+
Rules: []schema.FirewallRuleRequest{},
392392
},
393393
opts: FirewallSetRulesOpts{
394394
Rules: []FirewallRule{},
@@ -397,7 +397,7 @@ func TestFirewallSetRules(t *testing.T) {
397397
{
398398
name: "description",
399399
expectedReqBody: schema.FirewallActionSetRulesRequest{
400-
Rules: []schema.FirewallRule{
400+
Rules: []schema.FirewallRuleRequest{
401401
{
402402
Direction: "out",
403403
DestinationIPs: []string{"10.0.0.5/32", "10.0.0.6/32"},

hcloud/schema/firewall.go

+16-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type Firewall struct {
1212
AppliedTo []FirewallResource `json:"applied_to"`
1313
}
1414

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

25+
// FirewallRuleRequest defines the schema of a Firewall rule in requests.
26+
type FirewallRuleRequest struct {
27+
Direction string `json:"direction"`
28+
SourceIPs []string `json:"source_ips,omitempty"`
29+
DestinationIPs []string `json:"destination_ips,omitempty"`
30+
Protocol string `json:"protocol"`
31+
Port *string `json:"port,omitempty"`
32+
Description *string `json:"description,omitempty"`
33+
}
34+
2535
// FirewallListResponse defines the schema of the response when listing Firewalls.
2636
type FirewallListResponse struct {
2737
Firewalls []Firewall `json:"firewalls"`
@@ -34,10 +44,10 @@ type FirewallGetResponse struct {
3444

3545
// FirewallCreateRequest defines the schema of the request to create a Firewall.
3646
type FirewallCreateRequest struct {
37-
Name string `json:"name"`
38-
Labels *map[string]string `json:"labels,omitempty"`
39-
Rules []FirewallRule `json:"rules,omitempty"`
40-
ApplyTo []FirewallResource `json:"apply_to,omitempty"`
47+
Name string `json:"name"`
48+
Labels *map[string]string `json:"labels,omitempty"`
49+
Rules []FirewallRuleRequest `json:"rules,omitempty"`
50+
ApplyTo []FirewallResource `json:"apply_to,omitempty"`
4151
}
4252

4353
// FirewallResource defines the schema of a resource to apply the new Firewall on.
@@ -76,7 +86,7 @@ type FirewallUpdateResponse struct {
7686

7787
// FirewallActionSetRulesRequest defines the schema of the request when setting Firewall rules.
7888
type FirewallActionSetRulesRequest struct {
79-
Rules []FirewallRule `json:"rules"`
89+
Rules []FirewallRuleRequest `json:"rules"`
8090
}
8191

8292
// FirewallActionSetRulesResponse defines the schema of the response when setting Firewall rules.

hcloud/zz_schema.go

+32-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)