Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 80 additions & 21 deletions IM/connectors/OpenStack.py
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,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 @@ -1722,27 +1740,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 @@ -1971,6 +1969,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 @@ -637,6 +637,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 @@ -738,6 +739,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