Add a scenario test for remote address group
Add a scenario test for SG rules with remote address group.
Implements: blueprint address-groups-in-sg-rules
Change-Id: I982552f47297a83a351ec67090c9101d80d88d4a
diff --git a/neutron_tempest_plugin/config.py b/neutron_tempest_plugin/config.py
index 2290d0f..3812383 100644
--- a/neutron_tempest_plugin/config.py
+++ b/neutron_tempest_plugin/config.py
@@ -68,6 +68,11 @@
default=None,
choices=['None', 'linuxbridge', 'ovs', 'sriov'],
help='Agent used for devstack@q-agt.service'),
+ cfg.StrOpt('firewall_driver',
+ default=None,
+ choices=['None', 'openvswitch', 'ovn',
+ 'iptables_hybrid', 'iptables'],
+ help='Driver for security groups firewall in the L2 agent'),
# Multicast tests settings
cfg.StrOpt('multicast_group_range',
diff --git a/neutron_tempest_plugin/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index 6910c11..334d543 100644
--- a/neutron_tempest_plugin/scenario/base.py
+++ b/neutron_tempest_plugin/scenario/base.py
@@ -158,13 +158,14 @@
if sg['name'] == constants.DEFAULT_SECURITY_GROUP:
secgroup_id = sg['id']
break
-
+ resp = []
for rule in rule_list:
direction = rule.pop('direction')
- client.create_security_group_rule(
- direction=direction,
- security_group_id=secgroup_id,
- **rule)
+ resp.append(client.create_security_group_rule(
+ direction=direction,
+ security_group_id=secgroup_id,
+ **rule)['security_group_rule'])
+ return resp
@classmethod
def create_loginable_secgroup_rule(cls, secgroup_id=None,
diff --git a/neutron_tempest_plugin/scenario/test_security_groups.py b/neutron_tempest_plugin/scenario/test_security_groups.py
index 9059a2f..8b7098e 100644
--- a/neutron_tempest_plugin/scenario/test_security_groups.py
+++ b/neutron_tempest_plugin/scenario/test_security_groups.py
@@ -12,8 +12,12 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
-from neutron_lib import constants
+import netaddr
+from neutron_lib import constants
+import testtools
+
+from tempest.common import utils as tempest_utils
from tempest.common import waiters
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
@@ -310,6 +314,95 @@
self.ping_ip_address(fips[0]['floating_ip_address'],
should_succeed=False)
+ @testtools.skipUnless(
+ CONF.neutron_plugin_options.firewall_driver == 'openvswitch',
+ "Openvswitch agent is required to run this test")
+ @decorators.idempotent_id('678dd4c0-2953-4626-b89c-8e7e4110ec4b')
+ @tempest_utils.requires_ext(extension="address-group", service="network")
+ @tempest_utils.requires_ext(
+ extension="security-groups-remote-address-group", service="network")
+ def test_remote_group_and_remote_address_group(self):
+ """Test SG rules with remote group and remote address group
+
+ This test checks the ICMP connection among two servers using a security
+ group rule with remote group and another rule with remote address
+ group. The connection should be granted when at least one of the rules
+ is applied. When both rules are applied (overlapped), removing one of
+ them should not disable the connection.
+ """
+ # create a new sec group
+ ssh_secgrp_name = data_utils.rand_name('ssh_secgrp')
+ ssh_secgrp = self.os_primary.network_client.create_security_group(
+ name=ssh_secgrp_name)
+ # add cleanup
+ self.security_groups.append(ssh_secgrp['security_group'])
+ # configure sec group to support SSH connectivity
+ self.create_loginable_secgroup_rule(
+ secgroup_id=ssh_secgrp['security_group']['id'])
+ # spawn two instances with the sec group created
+ server_ssh_clients, fips, servers = self.create_vm_testing_sec_grp(
+ security_groups=[{'name': ssh_secgrp_name}])
+ # verify SSH functionality
+ for i in range(2):
+ self.check_connectivity(fips[i]['floating_ip_address'],
+ CONF.validation.image_ssh_user,
+ self.keypair['private_key'])
+ # try to ping instances without ICMP permissions
+ self.check_remote_connectivity(
+ server_ssh_clients[0], fips[1]['fixed_ip_address'],
+ should_succeed=False)
+ # add ICMP support to the remote group
+ rule_list = [{'protocol': constants.PROTO_NUM_ICMP,
+ 'direction': constants.INGRESS_DIRECTION,
+ 'remote_group_id': ssh_secgrp['security_group']['id']}]
+ remote_sg_rid = self.create_secgroup_rules(
+ rule_list, secgroup_id=ssh_secgrp['security_group']['id'])[0]['id']
+ # verify ICMP connectivity between instances works
+ self.check_remote_connectivity(
+ server_ssh_clients[0], fips[1]['fixed_ip_address'],
+ servers=servers)
+ # make sure ICMP connectivity doesn't work from framework
+ self.ping_ip_address(fips[0]['floating_ip_address'],
+ should_succeed=False)
+
+ # add ICMP rule with remote address group
+ test_ag = self.create_address_group(
+ name=data_utils.rand_name('test_ag'),
+ addresses=[str(netaddr.IPNetwork(fips[0]['fixed_ip_address']))])
+ rule_list = [{'protocol': constants.PROTO_NUM_ICMP,
+ 'direction': constants.INGRESS_DIRECTION,
+ 'remote_address_group_id': test_ag['id']}]
+ remote_ag_rid = self.create_secgroup_rules(
+ rule_list, secgroup_id=ssh_secgrp['security_group']['id'])[0]['id']
+ # verify ICMP connectivity between instances still works
+ self.check_remote_connectivity(
+ server_ssh_clients[0], fips[1]['fixed_ip_address'],
+ servers=servers)
+ # make sure ICMP connectivity doesn't work from framework
+ self.ping_ip_address(fips[0]['floating_ip_address'],
+ should_succeed=False)
+
+ # Remove the ICMP rule with remote group
+ self.client.delete_security_group_rule(remote_sg_rid)
+ # verify ICMP connectivity between instances still works as granted
+ # by the rule with remote address group
+ self.check_remote_connectivity(
+ server_ssh_clients[0], fips[1]['fixed_ip_address'],
+ servers=servers)
+ # make sure ICMP connectivity doesn't work from framework
+ self.ping_ip_address(fips[0]['floating_ip_address'],
+ should_succeed=False)
+
+ # Remove the ICMP rule with remote address group
+ self.client.delete_security_group_rule(remote_ag_rid)
+ # verify ICMP connectivity between instances doesn't work now
+ self.check_remote_connectivity(
+ server_ssh_clients[0], fips[1]['fixed_ip_address'],
+ should_succeed=False)
+ # make sure ICMP connectivity doesn't work from framework
+ self.ping_ip_address(fips[0]['floating_ip_address'],
+ should_succeed=False)
+
@decorators.idempotent_id('f07d0159-8f9e-4faa-87f5-a869ab0ad488')
def test_multiple_ports_secgroup_inheritance(self):
"""Test multiple port security group inheritance
diff --git a/zuul.d/master_jobs.yaml b/zuul.d/master_jobs.yaml
index 0d197e0..207a4f1 100644
--- a/zuul.d/master_jobs.yaml
+++ b/zuul.d/master_jobs.yaml
@@ -64,6 +64,7 @@
- router-admin-state-down-before-update
- router_availability_zone
- security-group
+ - security-groups-remote-address-group
- segment
- service-type
- sorting
@@ -162,6 +163,7 @@
available_features: "{{ network_available_features | join(',') }}"
neutron_plugin_options:
available_type_drivers: flat,vlan,local,vxlan
+ firewall_driver: openvswitch
irrelevant-files: &openvswitch-scenario-irrelevant-files
- ^(test-|)requirements.txt$
- ^releasenotes/.*$
@@ -231,6 +233,7 @@
available_features: "{{ network_available_features | join(',') }}"
neutron_plugin_options:
available_type_drivers: flat,vlan,local,vxlan
+ firewall_driver: iptables_hybrid
irrelevant-files:
- ^(test-|)requirements.txt$
- ^releasenotes/.*$
@@ -306,6 +309,7 @@
neutron_plugin_options:
available_type_drivers: flat,vlan,local,vxlan
q_agent: linuxbridge
+ firewall_driver: iptables
irrelevant-files:
- ^(test-|)requirements.txt$
- ^releasenotes/.*$
@@ -403,6 +407,7 @@
neutron_plugin_options:
available_type_drivers: local,flat,vlan,geneve
is_igmp_snooping_enabled: True
+ firewall_driver: ovn
irrelevant-files:
- ^(test-|)requirements.txt$
- ^releasenotes/.*$
@@ -543,6 +548,7 @@
image_is_advanced: true
available_type_drivers: flat,geneve,vlan,gre,local,vxlan
l3_agent_mode: dvr_snat
+ firewall_driver: openvswitch
group-vars:
subnode:
devstack_services: