summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorTodd Willey <todd@ansolabs.com>2011-06-25 02:30:47 +0000
committerTarmac <>2011-06-25 02:30:47 +0000
commit4db84dc78ae6660dbced7e9382ae5c441a135908 (patch)
tree64c242a2d4ca45772e3a010d2e99f939564eb06e /nova
parente6f3ce3541d3ce380c00dda3b878a652fc31f2fc (diff)
parent51d93c5b1722bef9783cd7572c1464a084ece0aa (diff)
Add api methods to delete provider firewall rules.
Diffstat (limited to 'nova')
-rw-r--r--nova/api/ec2/admin.py20
-rw-r--r--nova/db/api.py10
-rw-r--r--nova/db/sqlalchemy/api.py21
-rw-r--r--nova/tests/test_adminapi.py22
-rw-r--r--nova/tests/test_libvirt.py7
5 files changed, 80 insertions, 0 deletions
diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py
index 343bc61c4..df7876b9d 100644
--- a/nova/api/ec2/admin.py
+++ b/nova/api/ec2/admin.py
@@ -369,3 +369,23 @@ class AdminController(object):
raise exception.ApiError(_('Duplicate rule'))
self.compute_api.trigger_provider_fw_rules_refresh(context)
return {'status': 'OK', 'message': 'Added %s rules' % rules_added}
+
+ def describe_external_address_blocks(self, context):
+ blocks = db.provider_fw_rule_get_all(context)
+ # NOTE(todd): use a set since we have icmp/udp/tcp rules with same cidr
+ blocks = set([b.cidr for b in blocks])
+ blocks = [{'cidr': b} for b in blocks]
+ return {'externalIpBlockInfo':
+ list(sorted(blocks, key=lambda k: k['cidr']))}
+
+ def remove_external_address_block(self, context, cidr):
+ LOG.audit(_('Removing ip block from %s'), cidr, context=context)
+ cidr = urllib.unquote(cidr).decode()
+ # raise if invalid
+ netaddr.IPNetwork(cidr)
+ rules = db.provider_fw_rule_get_all_by_cidr(context, cidr)
+ for rule in rules:
+ db.provider_fw_rule_destroy(context, rule['id'])
+ if rules:
+ self.compute_api.trigger_provider_fw_rules_refresh(context)
+ return {'status': 'OK', 'message': 'Deleted %s rules' % len(rules)}
diff --git a/nova/db/api.py b/nova/db/api.py
index 97ae9aba3..e6a46aec9 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -1044,6 +1044,16 @@ def provider_fw_rule_get_all(context):
return IMPL.provider_fw_rule_get_all(context)
+def provider_fw_rule_get_all_by_cidr(context, cidr):
+ """Get all provider-level firewall rules."""
+ return IMPL.provider_fw_rule_get_all_by_cidr(context, cidr)
+
+
+def provider_fw_rule_destroy(context, rule_id):
+ """Delete a provider firewall rule from the database."""
+ return IMPL.provider_fw_rule_destroy(context, rule_id)
+
+
###################
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index e10d02a4e..b6f5cc717 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -2189,6 +2189,7 @@ def provider_fw_rule_create(context, rule):
return fw_rule_ref
+@require_admin_context
def provider_fw_rule_get_all(context):
session = get_session()
return session.query(models.ProviderFirewallRule).\
@@ -2196,6 +2197,26 @@ def provider_fw_rule_get_all(context):
all()
+@require_admin_context
+def provider_fw_rule_get_all_by_cidr(context, cidr):
+ session = get_session()
+ return session.query(models.ProviderFirewallRule).\
+ filter_by(deleted=can_read_deleted(context)).\
+ filter_by(cidr=cidr).\
+ all()
+
+
+@require_admin_context
+def provider_fw_rule_destroy(context, rule_id):
+ session = get_session()
+ with session.begin():
+ session.query(models.ProviderFirewallRule).\
+ filter_by(id=rule_id).\
+ update({'deleted': True,
+ 'deleted_at': utils.utcnow(),
+ 'updated_at': literal_column('updated_at')})
+
+
###################
diff --git a/nova/tests/test_adminapi.py b/nova/tests/test_adminapi.py
index 7ecaf1c09..ce826fd5b 100644
--- a/nova/tests/test_adminapi.py
+++ b/nova/tests/test_adminapi.py
@@ -85,5 +85,27 @@ class AdminApiTestCase(test.TestCase):
def test_block_external_ips(self):
"""Make sure provider firewall rules are created."""
result = self.api.block_external_addresses(self.context, '1.1.1.1/32')
+ self.api.remove_external_address_block(self.context, '1.1.1.1/32')
self.assertEqual('OK', result['status'])
self.assertEqual('Added 3 rules', result['message'])
+
+ def test_list_blocked_ips(self):
+ """Make sure we can see the external blocks that exist."""
+ self.api.block_external_addresses(self.context, '1.1.1.2/32')
+ result = self.api.describe_external_address_blocks(self.context)
+ num = len(db.provider_fw_rule_get_all(self.context))
+ self.api.remove_external_address_block(self.context, '1.1.1.2/32')
+ # we only list IP, not tcp/udp/icmp rules
+ self.assertEqual(num / 3, len(result['externalIpBlockInfo']))
+
+ def test_remove_ip_block(self):
+ """Remove ip blocks."""
+ result = self.api.block_external_addresses(self.context, '1.1.1.3/32')
+ self.assertEqual('OK', result['status'])
+ num0 = len(db.provider_fw_rule_get_all(self.context))
+ result = self.api.remove_external_address_block(self.context,
+ '1.1.1.3/32')
+ self.assertEqual('OK', result['status'])
+ self.assertEqual('Deleted 3 rules', result['message'])
+ num1 = len(db.provider_fw_rule_get_all(self.context))
+ self.assert_(num1 < num0)
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index ee94d3c17..d12e21063 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -1115,6 +1115,13 @@ class IptablesFirewallTestCase(test.TestCase):
provjump_rules.append(rule)
self.assertEqual(1, len(provjump_rules))
+ # remove a rule from the db, cast to compute to refresh rule
+ db.provider_fw_rule_destroy(admin_ctxt, provider_fw1['id'])
+ self.fw.refresh_provider_fw_rules()
+ rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
+ if rule.chain == 'provider']
+ self.assertEqual(1, len(rules))
+
class NWFilterTestCase(test.TestCase):
def setUp(self):