Skip to content

Commit 8ea0a3d

Browse files
authored
test: Add Linode Cloud Firewall for all test linode instances (#616)
1 parent e55d93b commit 8ea0a3d

16 files changed

+169
-49
lines changed

tests/integration/conftest.py

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Use random integer as the start point here to avoid
22
# id conflicts when multiple testings are running.
3+
import ipaddress
34
import json
45
import logging
56
import os
@@ -13,6 +14,7 @@
1314
from typing import Callable, Optional
1415

1516
import pytest
17+
import requests
1618

1719
from linodecli import ENV_TOKEN_NAME
1820
from tests.integration.helpers import (
@@ -33,6 +35,83 @@
3335
NODEBALANCER_BASE_CMD = ["linode-cli", "nodebalancers"]
3436

3537

38+
@pytest.fixture(autouse=True, scope="session")
39+
def linode_cloud_firewall():
40+
def is_valid_ipv4(address):
41+
try:
42+
ipaddress.IPv4Address(address)
43+
return True
44+
except ipaddress.AddressValueError:
45+
return False
46+
47+
def is_valid_ipv6(address):
48+
try:
49+
ipaddress.IPv6Address(address)
50+
return True
51+
except ipaddress.AddressValueError:
52+
return False
53+
54+
def get_public_ip(ip_version="ipv4"):
55+
url = (
56+
f"https://api64.ipify.org?format=json"
57+
if ip_version == "ipv6"
58+
else f"https://api.ipify.org?format=json"
59+
)
60+
response = requests.get(url)
61+
return str(response.json()["ip"])
62+
63+
def create_inbound_rule(ipv4_address, ipv6_address):
64+
rule = [
65+
{
66+
"protocol": "TCP",
67+
"ports": "22",
68+
"addresses": {},
69+
"action": "ACCEPT",
70+
}
71+
]
72+
if is_valid_ipv4(ipv4_address):
73+
rule[0]["addresses"]["ipv4"] = [f"{ipv4_address}/32"]
74+
75+
if is_valid_ipv6(ipv6_address):
76+
rule[0]["addresses"]["ipv6"] = [f"{ipv6_address}/128"]
77+
78+
return json.dumps(rule, indent=4)
79+
80+
# Fetch the public IP addresses
81+
ipv4_address = get_public_ip("ipv4")
82+
ipv6_address = get_public_ip("ipv6")
83+
84+
inbound_rule = create_inbound_rule(ipv4_address, ipv6_address)
85+
86+
label = "cloud_firewall_" + str(int(time.time()))
87+
88+
# Base command list
89+
command = [
90+
"linode-cli",
91+
"firewalls",
92+
"create",
93+
"--label",
94+
label,
95+
"--rules.outbound_policy",
96+
"ACCEPT",
97+
"--rules.inbound_policy",
98+
"DROP",
99+
"--text",
100+
"--no-headers",
101+
"--format",
102+
"id",
103+
]
104+
105+
if is_valid_ipv4(ipv4_address) or is_valid_ipv6(ipv6_address):
106+
command.extend(["--rules.inbound", inbound_rule])
107+
108+
firewall_id = exec_test_command(command).stdout.decode().rstrip()
109+
110+
yield firewall_id
111+
112+
delete_target_id(target="firewalls", id=firewall_id)
113+
114+
36115
@pytest.fixture(scope="session")
37116
def _id_generators():
38117
return defaultdict(lambda: count(randint(0, 1000000)))
@@ -185,7 +264,7 @@ def slave_domain():
185264

186265
# Test helpers specific to Linodes test suite
187266
@pytest.fixture
188-
def linode_with_label():
267+
def linode_with_label(linode_cloud_firewall):
189268
timestamp = str(time.time_ns())
190269
label = "cli" + timestamp
191270
result = (
@@ -203,6 +282,8 @@ def linode_with_label():
203282
label,
204283
"--root_pass",
205284
DEFAULT_RANDOM_PASS,
285+
"--firewall_id",
286+
linode_cloud_firewall,
206287
"--text",
207288
"--delimiter",
208289
",",
@@ -223,7 +304,7 @@ def linode_with_label():
223304

224305

225306
@pytest.fixture
226-
def linode_min_req():
307+
def linode_min_req(linode_cloud_firewall):
227308
result = (
228309
exec_test_command(
229310
LINODE_BASE_CMD
@@ -235,6 +316,8 @@ def linode_min_req():
235316
"us-ord",
236317
"--root_pass",
237318
DEFAULT_RANDOM_PASS,
319+
"--firewall_id",
320+
linode_cloud_firewall,
238321
"--no-defaults",
239322
"--text",
240323
"--delimiter",
@@ -256,7 +339,7 @@ def linode_min_req():
256339

257340

258341
@pytest.fixture
259-
def linode_wo_image():
342+
def linode_wo_image(linode_cloud_firewall):
260343
label = "cli" + str(int(time.time()) + randint(10, 1000))
261344
linode_id = (
262345
exec_test_command(
@@ -272,6 +355,8 @@ def linode_wo_image():
272355
DEFAULT_REGION,
273356
"--root_pass",
274357
DEFAULT_RANDOM_PASS,
358+
"--firewall_id",
359+
linode_cloud_firewall,
275360
"--format",
276361
"id",
277362
"--no-headers",
@@ -288,7 +373,7 @@ def linode_wo_image():
288373

289374

290375
@pytest.fixture
291-
def linode_backup_enabled():
376+
def linode_backup_enabled(linode_cloud_firewall):
292377
# create linode with backups enabled
293378
linode_id = (
294379
exec_test_command(
@@ -306,6 +391,8 @@ def linode_backup_enabled():
306391
DEFAULT_TEST_IMAGE,
307392
"--root_pass",
308393
DEFAULT_RANDOM_PASS,
394+
"--firewall_id",
395+
linode_cloud_firewall,
309396
"--text",
310397
"--no-headers",
311398
"--format=id",
@@ -348,14 +435,16 @@ def snapshot_of_linode():
348435

349436
# Test helpers specific to Nodebalancers test suite
350437
@pytest.fixture
351-
def nodebalancer_with_default_conf():
438+
def nodebalancer_with_default_conf(linode_cloud_firewall):
352439
result = (
353440
exec_test_command(
354441
NODEBALANCER_BASE_CMD
355442
+ [
356443
"create",
357444
"--region",
358445
"us-ord",
446+
"--firewall_id",
447+
linode_cloud_firewall,
359448
"--text",
360449
"--delimiter",
361450
",",
@@ -452,10 +541,11 @@ def pytest_configure(config):
452541

453542

454543
@pytest.fixture
455-
def created_linode_id():
544+
def support_test_linode_id(linode_cloud_firewall):
456545
timestamp = str(time.time_ns())
457546
label = "cli" + timestamp
458-
result = (
547+
548+
res = (
459549
exec_test_command(
460550
LINODE_BASE_CMD
461551
+ [
@@ -470,20 +560,23 @@ def created_linode_id():
470560
label,
471561
"--root_pass",
472562
DEFAULT_RANDOM_PASS,
563+
"--firewall_id",
564+
linode_cloud_firewall,
473565
"--text",
474566
"--delimiter",
475567
",",
476568
"--no-headers",
477569
"--format",
478-
"label,region,type,image,id",
570+
"id",
479571
"--no-defaults",
480572
]
481573
)
482574
.stdout.decode()
483575
.rstrip()
484576
)
485577

486-
res_arr = result.split(",")
487-
linode_id = res_arr[4]
578+
linode_id = res
579+
488580
yield linode_id
581+
489582
delete_target_id(target="linodes", id=linode_id)

tests/integration/firewalls/test_firewalls.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
@pytest.fixture
1717
def test_firewall_id():
18-
# Create one domain for some tests in this suite
1918
firewall_id = (
2019
exec_test_command(
2120
BASE_CMD
@@ -38,7 +37,7 @@ def test_firewall_id():
3837
)
3938

4039
yield firewall_id
41-
# teardown - delete all firewalls
40+
4241
delete_target_id(target="firewalls", id=firewall_id)
4342

4443

tests/integration/linodes/helpers_linodes.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def wait_until(linode_id: "str", timeout, status: "str", period=5):
7171
return False
7272

7373

74-
def create_linode(test_region=DEFAULT_REGION):
74+
def create_linode(firewall_id: "str", test_region=DEFAULT_REGION):
7575
# create linode
7676
linode_id = (
7777
exec_test_command(
@@ -87,6 +87,8 @@ def create_linode(test_region=DEFAULT_REGION):
8787
DEFAULT_TEST_IMAGE,
8888
"--root_pass",
8989
DEFAULT_RANDOM_PASS,
90+
"--firewall_id",
91+
firewall_id,
9092
"--format=id",
9193
"--text",
9294
"--no-headers",
@@ -99,7 +101,9 @@ def create_linode(test_region=DEFAULT_REGION):
99101
return linode_id
100102

101103

102-
def create_linode_backup_disabled(test_region=DEFAULT_REGION):
104+
def create_linode_backup_disabled(
105+
firewall_id: "str", test_region=DEFAULT_REGION
106+
):
103107
result = set_backups_enabled_in_account_settings(toggle=False)
104108

105109
# create linode
@@ -117,6 +121,8 @@ def create_linode_backup_disabled(test_region=DEFAULT_REGION):
117121
DEFAULT_TEST_IMAGE,
118122
"--root_pass",
119123
DEFAULT_RANDOM_PASS,
124+
"--firewall_id",
125+
firewall_id,
120126
"--format=id",
121127
"--text",
122128
"--no-headers",
@@ -172,9 +178,10 @@ def remove_linodes():
172178

173179

174180
def create_linode_and_wait(
181+
firewall_id: "str",
182+
ssh_key="",
175183
test_plan=DEFAULT_LINODE_TYPE,
176184
test_image=DEFAULT_TEST_IMAGE,
177-
ssh_key="",
178185
test_region=DEFAULT_REGION,
179186
):
180187
linode_type = test_plan
@@ -200,6 +207,8 @@ def create_linode_and_wait(
200207
DEFAULT_RANDOM_PASS,
201208
"--authorized_keys",
202209
ssh_key,
210+
"--firewall_id",
211+
firewall_id,
203212
"--format=id",
204213
"--backups_enabled",
205214
"true",
@@ -225,6 +234,8 @@ def create_linode_and_wait(
225234
test_image,
226235
"--root_pass",
227236
DEFAULT_RANDOM_PASS,
237+
"--firewall_id",
238+
firewall_id,
228239
"--format=id",
229240
"--backups_enabled",
230241
"true",

tests/integration/linodes/test_backups.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,24 @@
2020

2121

2222
@pytest.fixture
23-
def create_linode_setup():
24-
linode_id = create_linode()
23+
def create_linode_setup(linode_cloud_firewall):
24+
linode_id = create_linode(firewall_id=linode_cloud_firewall)
2525

2626
yield linode_id
2727

2828
delete_target_id("linodes", linode_id)
2929

3030

3131
@pytest.fixture
32-
def create_linode_backup_disabled_setup():
32+
def create_linode_backup_disabled_setup(linode_cloud_firewall):
3333
res = set_backups_enabled_in_account_settings(toggle=False)
3434

3535
if res == "True":
3636
raise ValueError(
3737
"Backups are unexpectedly enabled before setting up the test."
3838
)
3939

40-
linode_id = create_linode_backup_disabled()
40+
linode_id = create_linode_backup_disabled(firewall_id=linode_cloud_firewall)
4141

4242
yield linode_id
4343

tests/integration/linodes/test_interfaces.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919

2020
@pytest.fixture
21-
def linode_with_vpc_interface():
21+
def linode_with_vpc_interface(linode_cloud_firewall):
2222
vpc_json = create_vpc_w_subnet()
2323

2424
vpc_region = vpc_json["region"]
@@ -38,6 +38,8 @@ def linode_with_vpc_interface():
3838
DEFAULT_TEST_IMAGE,
3939
"--root_pass",
4040
DEFAULT_RANDOM_PASS,
41+
"--firewall_id",
42+
linode_cloud_firewall,
4143
"--interfaces.purpose",
4244
"vpc",
4345
"--interfaces.primary",
@@ -67,7 +69,7 @@ def linode_with_vpc_interface():
6769

6870

6971
@pytest.fixture
70-
def linode_with_vpc_interface_as_json():
72+
def linode_with_vpc_interface_as_json(linode_cloud_firewall):
7173
vpc_json = create_vpc_w_subnet()
7274

7375
vpc_region = vpc_json["region"]
@@ -87,6 +89,8 @@ def linode_with_vpc_interface_as_json():
8789
DEFAULT_TEST_IMAGE,
8890
"--root_pass",
8991
DEFAULT_RANDOM_PASS,
92+
"--firewall_id",
93+
linode_cloud_firewall,
9094
"--interfaces",
9195
json.dumps(
9296
[

tests/integration/linodes/test_linodes.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222

2323
@pytest.fixture(scope="package", autouse=True)
24-
def setup_linodes():
24+
def setup_linodes(linode_cloud_firewall):
2525
linode_id = (
2626
exec_test_command(
2727
BASE_CMD
@@ -37,6 +37,8 @@ def setup_linodes():
3737
linode_label,
3838
"--root_pass",
3939
DEFAULT_RANDOM_PASS,
40+
"--firewall_id",
41+
linode_cloud_firewall,
4042
"--text",
4143
"--delimiter",
4244
",",

0 commit comments

Comments
 (0)