diff --git a/ec2driver.py b/ec2driver.py index f40eb89..d2d0a3e 100644 --- a/ec2driver.py +++ b/ec2driver.py @@ -514,69 +514,57 @@ class EC2Driver(driver.ComputeDriver): return [instance for instance in (self.nova.servers.list()) if openstack_security_group.name in [group['name'] for group in instance.security_groups]] - def _get_id_of_ec2_instance_to_add_security_group(self, ec2_security_group, openstack_security_group): - ec2_ids_of_instances_with_security_group_in_openstack_and_not_in_ec2 = [ - openstack_instance.metadata['ec2_id'] for openstack_instance - in self._get_openstack_instances_for_security_group(openstack_security_group) - if openstack_instance.metadata['ec2_id'] not in self._get_ec2_instance_ids_for_security_group(ec2_security_group) - ] + def _get_id_of_ec2_instance_to_update_security_group(self, ec2_instance_ids_for_security_group, ec2_ids_for_openstack_instances_for_security_group): + return (set(ec2_ids_for_openstack_instances_for_security_group).symmetric_difference(set(ec2_instance_ids_for_security_group))).pop() - if not ec2_ids_of_instances_with_security_group_in_openstack_and_not_in_ec2: - return None - else: - return ec2_ids_of_instances_with_security_group_in_openstack_and_not_in_ec2[0] - - def _get_id_of_ec2_instance_to_remove_security_group(self, ec2_security_group, openstack_security_group): - ec2_ids_of_instances_with_security_group_in_ec2_and_not_in_openstack = [ - id for id in self._get_ec2_instance_ids_for_security_group(ec2_security_group) - if id not in self._get_openstack_instances_for_security_group(openstack_security_group) - ] - - if not ec2_ids_of_instances_with_security_group_in_ec2_and_not_in_openstack: - return None - else: - return ec2_ids_of_instances_with_security_group_in_ec2_and_not_in_openstack[0] + def _should_add_security_group_to_instance(self, ec2_instance_ids_for_security_group, ec2_ids_for_openstack_instances_for_security_group): + return len(ec2_instance_ids_for_security_group) < len(ec2_ids_for_openstack_instances_for_security_group) def _add_security_group_to_instance(self, ec2_instance_id, ec2_security_group): - security_groups_for_instance = self.ec2_conn.get_instance_attribute(ec2_instance_id, "groupSet")['groupSet'] - security_group_ids_for_instance = [group.id for group in security_groups_for_instance] + security_group_ids_for_instance = self._get_ec2_security_group_ids_for_instance(ec2_instance_id) security_group_ids_for_instance.append(ec2_security_group.id) self.ec2_conn.modify_instance_attribute(ec2_instance_id, "groupSet", security_group_ids_for_instance) def _remove_security_group_from_instance(self, ec2_instance_id, ec2_security_group): - security_groups_for_instance = self.ec2_conn.get_instance_attribute(ec2_instance_id, "groupSet")['groupSet'] - security_group_ids_for_instance = [group.id for group in security_groups_for_instance] + security_group_ids_for_instance = self._get_ec2_security_group_ids_for_instance(ec2_instance_id) security_group_ids_for_instance.remove(ec2_security_group.id) self.ec2_conn.modify_instance_attribute(ec2_instance_id, "groupSet", security_group_ids_for_instance) + def _get_ec2_security_group_ids_for_instance(self, ec2_instance_id): + security_groups_for_instance = self.ec2_conn.get_instance_attribute(ec2_instance_id, "groupSet")['groupSet'] + security_group_ids_for_instance = [group.id for group in security_groups_for_instance] + return security_group_ids_for_instance + + def _get_or_create_ec2_security_group(self, openstack_security_group): + try: + return self.ec2_conn.get_all_security_groups(openstack_security_group.name)[0] + except EC2ResponseError as e: + LOG.warning(e.body) + return self.ec2_conn.create_security_group(openstack_security_group.name, openstack_security_group.description) + def refresh_security_group_rules(self, security_group_id): LOG.info("************** REFRESH SECURITY GROUP RULES ******************") openstack_security_group = self.nova.security_groups.get(security_group_id) + ec2_security_group = self._get_or_create_ec2_security_group(openstack_security_group) + + ec2_instance_ids_for_security_group = self._get_ec2_instance_ids_for_security_group(ec2_security_group) + ec2_ids_for_openstack_instances_for_security_group = [ + instance.metadata['ec2_id'] for instance + in self._get_openstack_instances_for_security_group(openstack_security_group) + ] + + self.security_group_lock.acquire() try: - ec2_security_group = self.ec2_conn.get_all_security_groups(openstack_security_group.name)[0] - except EC2ResponseError as e: - ec2_security_group = self.ec2_conn.create_security_group(openstack_security_group.name, openstack_security_group.description) - LOG.warning(e.body) - - ec2_instance_id_to_add_security_group = self._get_id_of_ec2_instance_to_add_security_group(ec2_security_group, openstack_security_group) - - if ec2_instance_id_to_add_security_group: - self.security_group_lock.acquire() - - try: + if self._should_add_security_group_to_instance(ec2_instance_ids_for_security_group, ec2_ids_for_openstack_instances_for_security_group): + ec2_instance_id_to_add_security_group = self._get_id_of_ec2_instance_to_update_security_group(ec2_instance_ids_for_security_group, ec2_ids_for_openstack_instances_for_security_group) self._add_security_group_to_instance(ec2_instance_id_to_add_security_group, ec2_security_group) - finally: - self.security_group_lock.release() - else: - ec2_instance_id_to_remove_security_group = self._get_id_of_ec2_instance_to_remove_security_group(ec2_security_group, openstack_security_group) - self.security_group_lock.acquire() - - try: + else: + ec2_instance_id_to_remove_security_group = self._get_id_of_ec2_instance_to_update_security_group(ec2_instance_ids_for_security_group, ec2_ids_for_openstack_instances_for_security_group) self._remove_security_group_from_instance(ec2_instance_id_to_remove_security_group, ec2_security_group) - finally: - self.security_group_lock.release() + finally: + self.security_group_lock.release() return True