diff --git a/networking-calico/networking_calico/plugins/ml2/drivers/calico/policy.py b/networking-calico/networking_calico/plugins/ml2/drivers/calico/policy.py index c8f47014828..1747ac22fb7 100644 --- a/networking-calico/networking_calico/plugins/ml2/drivers/calico/policy.py +++ b/networking-calico/networking_calico/plugins/ml2/drivers/calico/policy.py @@ -209,15 +209,17 @@ def _neutron_rule_to_etcd_rule(rule): entity_rule['nets'] = [rule['remote_ip_prefix']] LOG.debug("=> Entity rule %s" % entity_rule) + if port_spec is not None: + if rule['direction'] == 'ingress': + etcd_rule['destination'] = {'ports': port_spec} + else: + entity_rule['ports'] = port_spec + # Store in source or destination field of the overall rule. if entity_rule: if rule['direction'] == 'ingress': etcd_rule['source'] = entity_rule - if port_spec is not None: - etcd_rule['destination'] = {'ports': port_spec} else: - if port_spec is not None: - entity_rule['ports'] = port_spec etcd_rule['destination'] = entity_rule LOG.debug("=> %s Calico rule %s" % (rule['direction'], etcd_rule)) diff --git a/networking-calico/networking_calico/plugins/ml2/drivers/calico/test/test_plugin_etcd.py b/networking-calico/networking_calico/plugins/ml2/drivers/calico/test/test_plugin_etcd.py index 2b9459e8584..53261021b10 100644 --- a/networking-calico/networking_calico/plugins/ml2/drivers/calico/test/test_plugin_etcd.py +++ b/networking-calico/networking_calico/plugins/ml2/drivers/calico/test/test_plugin_etcd.py @@ -1203,6 +1203,63 @@ def test_neutron_rule_to_etcd_rule_protocol_any(self): 'ipVersion': 4, }) + def test_sg_rule_ingress_no_remote_ip_prefix(self): + # SG ingress rule with ports but no remote IP prefix + self.assertNeutronToEtcd(_neutron_rule_from_dict({ + "protocol": "tcp", + "port_range_min": 25, + "port_range_max": 34, + }), { + 'action': 'Allow', + 'destination': {'ports': ['25:34']}, + 'ipVersion': 4, + 'protocol': 'TCP', + }) + + def test_sg_rule_egress_no_remote_ip_prefix(self): + # SG egress rule with ports but no remote IP prefix + self.assertNeutronToEtcd(_neutron_rule_from_dict({ + "direction": "egress", + "protocol": "tcp", + "port_range_min": 25, + "port_range_max": 34, + }), { + 'action': 'Allow', + 'destination': {'ports': ['25:34']}, + 'ipVersion': 4, + 'protocol': 'TCP', + }) + + def test_sg_rule_ingress_with_remote_ip_prefix(self): + # SG ingress rule with ports and remote IP prefix + self.assertNeutronToEtcd(_neutron_rule_from_dict({ + "protocol": "tcp", + "remote_ip_prefix": "1.2.3.0/24", + "port_range_min": 25, + "port_range_max": 34, + }), { + 'action': 'Allow', + 'destination': {'ports': ['25:34']}, + 'ipVersion': 4, + 'protocol': 'TCP', + 'source': {'nets': ['1.2.3.0/24']}, + }) + + def test_sg_rule_egress_with_remote_ip_prefix(self): + # SG egress rule with ports and remote IP prefix + self.assertNeutronToEtcd(_neutron_rule_from_dict({ + "direction": "egress", + "protocol": "tcp", + "remote_ip_prefix": "1.2.3.0/24", + "port_range_min": 25, + "port_range_max": 34, + }), { + 'action': 'Allow', + 'destination': {'nets': ['1.2.3.0/24'], 'ports': ['25:34']}, + 'ipVersion': 4, + 'protocol': 'TCP', + }) + def test_not_master_does_not_resync(self): """Test that a driver that is not master does not resync.""" # Initialize the state early to put the elector in place, then override