Skip to content

Commit d68d542

Browse files
author
Jonathan Visser
committed
add bin/delete_whitelist_rule
1 parent 3db39b3 commit d68d542

5 files changed

Lines changed: 157 additions & 0 deletions

File tree

bin/delete_whitelist_rule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
command

hypernode_api_python/client.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,29 @@ def add_whitelist_rule(self, app_name, data):
624624
"POST", HYPERNODE_API_WHITELIST_ENDPOINT.format(app_name), data=data
625625
)
626626

627+
def delete_whitelist_rule(self, app_name, data):
628+
"""
629+
Remove a whitelist rule for the specified app. See get_whitelist_rules
630+
for the currently configured whitelist rules. On success the response
631+
will have status_code 204 and no content.
632+
Example:
633+
> client.delete_whitelist_rule(
634+
> 'yourhypernodeappname',
635+
> data={'ip': '1.2.3.4', 'type': 'database'}
636+
> ).status_code
637+
> 204
638+
639+
:param str app_name: The name of the Hypernode to remove the whitelist
640+
rule for
641+
:param dict data: Data describing the whitelist rule to remove. An
642+
example could be: {'ip': '1.2.3.4', 'type': 'database'}. The type can
643+
be one of 'waf', 'database' or 'ftp'.
644+
:return obj response: The request response object
645+
"""
646+
return self.requests(
647+
"DELETE", HYPERNODE_API_WHITELIST_ENDPOINT.format(app_name), data=data
648+
)
649+
627650
def get_current_product_for_app(self, app_name):
628651
"""
629652
Retrieve information about the product the specified App is currently on.

hypernode_api_python/commands.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,44 @@ def add_whitelist_rule(args=None):
541541
print_response(client.add_whitelist_rule(app_name, data=data))
542542

543543

544+
def delete_whitelist_rule(args=None):
545+
parser = ArgumentParser(
546+
description="""
547+
Remove a WAF whitelist rule for the Hypernode.
548+
549+
Example:
550+
$ ./bin/delete_whitelist_rule 1.2.3.4 --type database
551+
Whitelist rule '1.2.3.4' (database) has been removed.
552+
""",
553+
formatter_class=RawTextHelpFormatter,
554+
)
555+
parser.add_argument(
556+
"ip",
557+
help="The whitelisted IP address to remove. See ./bin/get_whitelist_rules",
558+
)
559+
parser.add_argument(
560+
"--type",
561+
help="The type of the whitelist rule to remove",
562+
choices=["waf", "database", "ftp"],
563+
default="database",
564+
)
565+
args = parser.parse_args(args=args)
566+
client = get_client()
567+
app_name = get_app_name()
568+
data = {"ip": args.ip, "type": args.type}
569+
try:
570+
client.delete_whitelist_rule(app_name, data=data)
571+
print("Whitelist rule '{}' ({}) has been removed.".format(args.ip, args.type))
572+
exit(EX_OK)
573+
except Exception as e:
574+
print(
575+
"Whitelist rule '{}' ({}) failed to be removed: {}".format(
576+
args.ip, args.type, e
577+
)
578+
)
579+
exit(EX_UNAVAILABLE)
580+
581+
544582
def get_current_product_for_app(args=None):
545583
parser = ArgumentParser(
546584
description="""
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from unittest import TestCase
2+
from unittest.mock import Mock
3+
4+
from hypernode_api_python.client import (
5+
HYPERNODE_API_WHITELIST_ENDPOINT,
6+
HypernodeAPIPython,
7+
)
8+
9+
10+
class TestDeleteWhitelistRule(TestCase):
11+
def setUp(self):
12+
self.client = HypernodeAPIPython(token="my_token")
13+
self.mock_request = Mock()
14+
self.client.requests = self.mock_request
15+
self.app_name = "my_app"
16+
17+
def test_whitelist_endpoint_is_correct(self):
18+
self.assertEqual("/v2/whitelist/{}/", HYPERNODE_API_WHITELIST_ENDPOINT)
19+
20+
def test_calls_delete_whitelist_rule_endpoint_properly(self):
21+
data = {"ip": "1.2.3.4", "type": "database"}
22+
self.client.delete_whitelist_rule(self.app_name, data)
23+
24+
self.mock_request.assert_called_once_with(
25+
"DELETE", f"/v2/whitelist/{self.app_name}/", data=data
26+
)
27+
28+
def test_returns_delete_whitelist_rule_response(self):
29+
response = Mock()
30+
response.status_code = 204
31+
self.mock_request.return_value = response
32+
33+
self.assertEqual(
34+
self.client.delete_whitelist_rule(self.app_name, {"ip": "1.2.3.4"}),
35+
self.mock_request.return_value,
36+
)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from hypernode_api_python.commands import delete_whitelist_rule
2+
from tests.testcase import TestCase
3+
4+
5+
class TestDeleteWhitelistRule(TestCase):
6+
def setUp(self):
7+
self.print_response = self.set_up_patch(
8+
"hypernode_api_python.commands.print_response"
9+
)
10+
self.get_client = self.set_up_patch("hypernode_api_python.commands.get_client")
11+
self.client = self.get_client.return_value
12+
self.get_app_name = self.set_up_patch(
13+
"hypernode_api_python.commands.get_app_name"
14+
)
15+
self.get_app_name.return_value = "myappname"
16+
17+
def test_delete_whitelist_rule_gets_client(self):
18+
with self.assertRaises(SystemExit):
19+
delete_whitelist_rule(["1.2.3.4"])
20+
21+
self.get_client.assert_called_once_with()
22+
23+
def test_delete_whitelist_rule_gets_app_name(self):
24+
with self.assertRaises(SystemExit):
25+
delete_whitelist_rule(["1.2.3.4"])
26+
27+
self.get_app_name.assert_called_once_with()
28+
29+
def test_delete_whitelist_rule_deletes_whitelist_rule_with_default_type(self):
30+
with self.assertRaises(SystemExit):
31+
delete_whitelist_rule(["1.2.3.4"])
32+
33+
expected_data = {"ip": "1.2.3.4", "type": "database"}
34+
self.client.delete_whitelist_rule.assert_called_once_with(
35+
"myappname", data=expected_data
36+
)
37+
38+
def test_delete_whitelist_rule_deletes_whitelist_rule_with_specified_type(self):
39+
with self.assertRaises(SystemExit):
40+
delete_whitelist_rule(["1.2.3.4", "--type", "waf"])
41+
42+
expected_data = {"ip": "1.2.3.4", "type": "waf"}
43+
self.client.delete_whitelist_rule.assert_called_once_with(
44+
"myappname", data=expected_data
45+
)
46+
47+
def test_delete_whitelist_rule_exits_zero_on_success(self):
48+
with self.assertRaises(SystemExit) as cm:
49+
delete_whitelist_rule(["1.2.3.4"])
50+
51+
self.assertEqual(cm.exception.code, 0)
52+
53+
def test_delete_whitelist_rule_exits_nonzero_when_delete_fails(self):
54+
self.client.delete_whitelist_rule.side_effect = RuntimeError("some error")
55+
56+
with self.assertRaises(SystemExit) as cm:
57+
delete_whitelist_rule(["1.2.3.4"])
58+
59+
self.assertNotEqual(cm.exception.code, 0)

0 commit comments

Comments
 (0)