Skip to content

Commit 70c7a26

Browse files
committed
WIP: Patch multiple firewall rules
1 parent e0e69d1 commit 70c7a26

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

cloudamqp/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ func Provider(v string) *schema.Provider {
6767
"cloudamqp_rabbitmq_configuration": resourceRabbitMqConfiguration(),
6868
"cloudamqp_security_firewall": resourceSecurityFirewall(),
6969
"cloudamqp_security_firewall_rule": resourceSecurityFirewallRule(),
70+
"cloudamqp_security_firewall_rules": resourceSecurityFirewallRules(),
7071
"cloudamqp_upgrade_rabbitmq": resourceUpgradeRabbitMQ(),
7172
"cloudamqp_vpc_gcp_peering": resourceVpcGcpPeering(),
7273
"cloudamqp_vpc_peering": resourceVpcPeering(),
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
package cloudamqp
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net"
7+
"strconv"
8+
9+
"github.com/84codes/go-api/api"
10+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
11+
)
12+
13+
func resourceSecurityFirewallRules() *schema.Resource {
14+
return &schema.Resource{
15+
Create: resourceSecurityFirewallRulesCreate,
16+
Read: resourceSecurityFirewallRulesRead,
17+
Update: resourceSecurityFirewallRulesUpdate,
18+
Delete: resourceSecurityFirewallRulesDelete,
19+
Schema: map[string]*schema.Schema{
20+
"instance_id": {
21+
Type: schema.TypeInt,
22+
Required: true,
23+
Description: "Instance identifier",
24+
},
25+
"rules": {
26+
Type: schema.TypeSet,
27+
Required: true,
28+
Elem: &schema.Resource{
29+
Schema: map[string]*schema.Schema{
30+
"services": {
31+
Type: schema.TypeList,
32+
Optional: true,
33+
Elem: &schema.Schema{
34+
Type: schema.TypeString,
35+
ValidateFunc: validateServices(),
36+
},
37+
Description: "Pre-defined services 'AMQP', 'AMQPS', 'HTTPS', 'MQTT', 'MQTTS', 'STOMP', 'STOMPS', " +
38+
"'STREAM', 'STREAM_SSL'",
39+
},
40+
"ports": {
41+
Type: schema.TypeList,
42+
Optional: true,
43+
Elem: &schema.Schema{
44+
Type: schema.TypeInt,
45+
ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) {
46+
v := val.(int)
47+
if v < 0 || v > 65554 {
48+
errs = append(errs, fmt.Errorf("%q must be between 0 and 65554, got: %d", key, v))
49+
} else if validateServicePort(v) {
50+
warns = append(warns, fmt.Sprintf("Port %d found in \"ports\", needs to be added as %q in \"services\" instead", v, portToService(v)))
51+
}
52+
return
53+
},
54+
},
55+
Description: "Custom ports between 0 - 65554",
56+
},
57+
"ip": {
58+
Type: schema.TypeString,
59+
Required: true,
60+
ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) {
61+
v := val.(string)
62+
_, _, err := net.ParseCIDR(v)
63+
if err != nil {
64+
errs = append(errs, fmt.Errorf("%v", err))
65+
}
66+
return
67+
},
68+
Description: "CIDR address: IP address with CIDR notation (e.g. 10.56.72.0/24)",
69+
},
70+
"description": {
71+
Type: schema.TypeString,
72+
Optional: true,
73+
Description: "Naming descripton e.g. 'Default'",
74+
},
75+
},
76+
},
77+
},
78+
"sleep": {
79+
Type: schema.TypeInt,
80+
Optional: true,
81+
Default: 30,
82+
Description: "Configurable sleep time in seconds between retries for firewall configuration",
83+
},
84+
"timeout": {
85+
Type: schema.TypeInt,
86+
Optional: true,
87+
Default: 1800,
88+
Description: "Configurable timeout time in seconds for firewall configuration",
89+
},
90+
},
91+
}
92+
}
93+
94+
func resourceSecurityFirewallRulesCreate(d *schema.ResourceData, meta interface{}) error {
95+
var (
96+
api = meta.(*api.API)
97+
instanceID = d.Get("instance_id").(int)
98+
localFirewalls = d.Get("rules").(*schema.Set).List()
99+
params []map[string]interface{}
100+
sleep = d.Get("sleep").(int)
101+
timeout = d.Get("timeout").(int)
102+
)
103+
104+
for _, k := range localFirewalls {
105+
params = append(params, k.(map[string]interface{}))
106+
}
107+
108+
err := api.PatchFirewallSettings(instanceID, params, sleep, timeout)
109+
if err != nil {
110+
return fmt.Errorf("error setting security firewall for resource %s: %s", d.Id(), err)
111+
}
112+
113+
d.SetId("na")
114+
return nil
115+
}
116+
117+
func resourceSecurityFirewallRulesRead(d *schema.ResourceData, meta interface{}) error {
118+
var (
119+
api = meta.(*api.API)
120+
ip = d.Get("ip").(string)
121+
instanceID = d.Get("instance_id").(int)
122+
)
123+
124+
data, err := api.ReadFirewallRule(instanceID, ip)
125+
log.Printf("[DEBUG] security firewall rule: %v", data)
126+
if err != nil {
127+
return err
128+
}
129+
130+
for k, v := range data {
131+
if v != nil {
132+
d.Set(k, v)
133+
}
134+
}
135+
136+
return nil
137+
}
138+
139+
func resourceSecurityFirewallRulesUpdate(d *schema.ResourceData, meta interface{}) error {
140+
var (
141+
api = meta.(*api.API)
142+
instanceID = d.Get("instance_id").(int)
143+
params []map[string]interface{}
144+
sleep = d.Get("sleep").(int)
145+
timeout = d.Get("timeout").(int)
146+
)
147+
148+
// if d.HasChange("rules") {
149+
// localFirewalls := d.Get("rules").(*schema.Set).List()
150+
// for k, v := range localFirewalls {
151+
152+
// }
153+
154+
// }
155+
156+
err := api.PatchFirewallSettings(instanceID, params, sleep, timeout)
157+
if err != nil {
158+
return fmt.Errorf("error setting security firewall for resource %s: %s", d.Id(), err)
159+
}
160+
161+
d.SetId(strconv.Itoa(instanceID))
162+
return nil
163+
}
164+
165+
func resourceSecurityFirewallRulesDelete(d *schema.ResourceData, meta interface{}) error {
166+
var (
167+
api = meta.(*api.API)
168+
instanceID = d.Get("instance_id").(int)
169+
rule = make(map[string]interface{})
170+
params []map[string]interface{}
171+
sleep = d.Get("sleep").(int)
172+
timeout = d.Get("timeout").(int)
173+
)
174+
175+
// Skip if faster instance destroy enabled
176+
if enableFasterInstanceDestroy == true {
177+
log.Printf("[DEBUG] cloudamqp::resource::security_firewall::delete skip calling backend.")
178+
return nil
179+
}
180+
181+
// Only set ip with correct value to make the PATCH request remove the rule
182+
rule["ip"] = d.Id()
183+
rule["services"] = []string{}
184+
rule["ports"] = []int{}
185+
params = append(params, rule)
186+
err := api.PatchFirewallSettings(instanceID, params, sleep, timeout)
187+
if err != nil {
188+
return fmt.Errorf("failed to remove firewall rule for IP %s: %s", d.Id(), err)
189+
}
190+
191+
return nil
192+
}

0 commit comments

Comments
 (0)