Skip to content

Commit

Permalink
Implements #1611 in OST
Browse files Browse the repository at this point in the history
  • Loading branch information
micafer committed Sep 26, 2024
1 parent 774c4f7 commit 330562a
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 21 deletions.
101 changes: 80 additions & 21 deletions IM/connectors/OpenStack.py
Original file line number Diff line number Diff line change
Expand Up @@ -1653,6 +1653,24 @@ def _get_security_group(self, driver, sg_name):
self.log_exception("Error getting security groups.")
return None

def add_security_group_rules(self, driver, outports, sg):
"""Add the security group rules to the security group"""
for outport in outports:
if outport.is_range():
to_port = outport.get_port_end()
from_port = outport.get_port_init()
else:
to_port = from_port = outport.get_remote_port()

try:
driver.ex_create_security_group_rule(sg, outport.get_protocol(),
from_port, to_port,
outport.get_remote_cidr())
except Exception as ex:
self.log_warn("Exception adding SG rules: %s" % get_ex_error(ex))
self.error_messages += ("Exception adding port range: %s-%s to SG rules.\n" %
(from_port, to_port))

def create_security_groups(self, driver, inf, radl):
res = []
system = radl.systems[0]
Expand Down Expand Up @@ -1709,27 +1727,7 @@ def create_security_groups(self, driver, inf, radl):
if network.isPublic() or network.getValue("proxy_host"):
outports = self.add_ssh_port(outports)

for outport in outports:
if outport.is_range():
try:
driver.ex_create_security_group_rule(sg, outport.get_protocol(),
outport.get_port_init(),
outport.get_port_end(),
outport.get_remote_cidr())
except Exception as ex:
self.log_warn("Exception adding SG rules: %s" % get_ex_error(ex))
self.error_messages += ("Exception adding port range: %s-%s to SG rules.\n" %
(outport.get_port_init(), outport.get_port_end()))
else:
try:
driver.ex_create_security_group_rule(sg, outport.get_protocol(),
outport.get_remote_port(),
outport.get_remote_port(),
outport.get_remote_cidr())
except Exception as ex:
self.log_warn("Exception adding SG rules: %s" % get_ex_error(ex))
self.error_messages += ("Exception adding port %s to SG rules.\n" %
outport.get_remote_port())
self.add_security_group_rules(driver, outports, sg)

return res

Expand Down Expand Up @@ -1958,6 +1956,67 @@ def alterVM(self, vm, radl, auth_data):
if not success:
return (success, msg)

success, msg = self.alter_security_groups(vm, radl, auth_data)
if not success:
return (success, msg)

return (True, "")

def alter_security_groups(self, vm, radl, auth_data):
driver = self.get_driver(auth_data)

# First check if the node is "routed"
for network in radl.networks:
if network.getValue('router'):
self.log_info("Network has a router set. Skip SG rules modification.")
return (True, "")

for network in radl.networks:
outports = network.getOutPorts() or []

old_network = vm.info.get_network_by_id(network.id)
old_outports = []
if old_network:
old_outports = old_network.getOutPorts() or []

if old_outports == outports:
self.log_debug("No changes in the SG rules for network %s." % network.id)
break

# open always SSH port on public nets or private with proxy host
if old_network and old_network.isPublic() or old_network.getValue("proxy_host"):
old_outports = self.add_ssh_port(old_outports)
if network.isPublic() or network.getValue("proxy_host"):
outports = self.add_ssh_port(outports)

sg_name = network.getValue("sg_name")
if not sg_name:
sg_name = "im-%s-%s" % (str(vm.inf.id), network.id)

sg = self._get_security_group(driver, sg_name)
if not sg:
self.log_error("Error updating security group: %s. It does not exist." % sg_name)
break

# Delete old SG rules
for rule in sg.rules:
# For each rule in the SG, check if it is in the old_outports and remove it
for outport in old_outports:
protocol = outport.get_protocol()
if outport.is_range():
to_port = outport.get_port_end()
from_port = outport.get_port_init()
else:
to_port = from_port = outport.get_remote_port()
if rule.from_port == from_port and rule.to_port == to_port and rule.ip_protocol == protocol:
try:
driver.ex_delete_security_group_rule(rule)
except Exception as ex:
self.log_warn("Exception removing old SG rules: %s" % get_ex_error(ex))

# Add new SG rules
self.add_security_group_rules(driver, outports, sg)

return (True, "")

def resizeVM(self, vm, radl, auth_data):
Expand Down
46 changes: 46 additions & 0 deletions test/unit/connectors/OpenStack.py
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,7 @@ def test_55_alter(self, add_elastic_ip_from_pool, get_driver):
ost_cloud = self.get_ost_cloud()

inf = MagicMock()
inf.id = "infid"
vm = VirtualMachine(inf, "1", ost_cloud.cloud, radl, radl, ost_cloud, 1)
vm.volumes = []

Expand Down Expand Up @@ -737,6 +738,51 @@ def test_55_alter(self, add_elastic_ip_from_pool, get_driver):
self.assertEqual(driver.ex_detach_floating_ip_from_node.call_args_list[0][0], (node, fip))
self.assertIsNone(vm.requested_radl.systems[0].getValue('net_interface.0.ip'))

radl_data = """
network net (outbound = 'yes' and outports = '8080')
system test (
cpu.arch='x86_64' and
cpu.count=1 and
memory.size=512m and
net_interface.0.connection = 'net' and
net_interface.0.ip = '8.8.8.8' and
net_interface.0.dns_name = 'test' and
disk.0.os.name = 'linux' and
disk.0.image.url = 'one://server.com/1' and
disk.0.os.credentials.username = 'user' and
disk.0.os.credentials.password = 'pass'
)"""
radl = radl_parse.parse_radl(radl_data)
vm = VirtualMachine(inf, "1", ost_cloud.cloud, radl, radl, ost_cloud, 1)

new_radl_data = """
network net (outbound = 'yes' and outports = '8081')
system test (
net_interface.0.connection = 'net'
)"""
new_radl = radl_parse.parse_radl(new_radl_data)

sg = MagicMock()
sg.name = "im-infid-net"
rule = MagicMock()
rule.id = "rid"
rule.from_port = 8080
rule.to_port = 8080
rule.ip_protocol = 'tcp'
sg.rules = [rule]
driver.ex_list_security_groups.return_value = [sg]
driver.ex_delete_security_group_rule.return_value = True
driver.ex_create_security_group_rule.return_value = True

success, _ = ost_cloud.alterVM(vm, new_radl, auth)
self.assertTrue(success, msg="ERROR: modifying VM info.")
self.assertEqual(driver.ex_delete_security_group_rule.call_count, 1)
self.assertEqual(driver.ex_delete_security_group_rule.call_args_list[0][0], (rule,))
self.assertEqual(driver.ex_create_security_group_rule.call_count, 2)
self.assertEqual(driver.ex_create_security_group_rule.call_args_list[0][0],
(sg, 'tcp', 8081, 8081, '0.0.0.0/0'))
self.assertEqual(driver.ex_create_security_group_rule.call_args_list[1][0],
(sg, 'tcp', 22, 22, '0.0.0.0/0'))
self.assertNotIn("ERROR", self.log.getvalue(), msg="ERROR found in log: %s" % self.log.getvalue())

@patch('libcloud.compute.drivers.openstack.OpenStackNodeDriver')
Expand Down

0 comments on commit 330562a

Please sign in to comment.