Skip to content

Commit

Permalink
Correct policy for OpenStack sec group with no remote_ip_prefix
Browse files Browse the repository at this point in the history
Fixes #7968

When an OpenStack security group does not specify a remote_ip_prefix - in other words, it applies to
traffic from all possible sources - but it does specify ports - in other words, it only applies to
those ports, the resulting Calico policy is _missing_ the restriction to the intended ports, and so
is accidentally an allow policy for _all_ ports.
  • Loading branch information
nelljerram committed Sep 19, 2023
1 parent 6f0117b commit ff96fc8
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ff96fc8

Please sign in to comment.