def _extract_changes(self, dep_update, raw_nodes, previous_nodes): """Extracts the changes between the current node_instances and the raw_nodes specified :param dep_update: deployment update object :param raw_nodes: node objects from deployment update :return: a dictionary of modification type and node instanced modified """ deployment = self.sm.get(models.Deployment, dep_update.deployment_id) deployment_id_filter = {'deployment_id': deployment.id} # By this point the node_instances aren't updated yet previous_node_instances = [ instance.to_dict() for instance in self.sm.list(models.NodeInstance, filters=deployment_id_filter, get_all_results=True) ] # extract all the None relationships from the deployment update nodes # in order to use in the extract changes no_none_relationships_nodes = copy.deepcopy(raw_nodes) for node in no_none_relationships_nodes: node['relationships'] = [r for r in node['relationships'] if r] # project changes in deployment changes = tasks.modify_deployment( nodes=no_none_relationships_nodes, previous_nodes=previous_nodes, previous_node_instances=previous_node_instances, scaling_groups=deployment.scaling_groups, modified_nodes=()) self._patch_changes_with_relationship_index( changes[NODE_MOD_TYPES.EXTENDED_AND_RELATED], raw_nodes) return changes
def _extract_changes(self, dep_update, raw_nodes, previous_nodes): """Extracts the changes between the current node_instances and the raw_nodes specified :param dep_update: :param raw_nodes: :return: a dictionary of modification type and node instanced modifed """ deployment = self.sm.get_deployment(dep_update.deployment_id) deployment_id_filter = {'deployment_id': deployment.id} # By this point the node_instances aren't updated yet previous_node_instances = \ [instance.to_dict() for instance in self.sm.get_node_instances(filters=deployment_id_filter).items] # extract all the None relationships from the depup nodes in order # to use in the extract changes no_none_relationships_nodes = copy.deepcopy(raw_nodes) for node in no_none_relationships_nodes: node['relationships'] = [r for r in node['relationships'] if r] # project changes in deployment changes = tasks.modify_deployment( nodes=no_none_relationships_nodes, previous_nodes=previous_nodes, previous_node_instances=previous_node_instances, scaling_groups=deployment.scaling_groups, modified_nodes=() ) self._patch_changes_with_relationship_index( changes[NODE_MOD_TYPES.EXTENDED_AND_RELATED], raw_nodes) return changes
def start_deployment_modification(self, deployment_id, modified_nodes): # verify deployment exists self.sm.get_deployment(deployment_id) nodes = [node.to_dict() for node in self.sm.get_nodes(deployment_id)] node_instances = [instance.to_dict() for instance in self.sm.get_node_instances(deployment_id)] node_instances_modification = tasks.modify_deployment( nodes=nodes, previous_node_instances=node_instances, modified_nodes=modified_nodes) added_and_related = node_instances_modification['added_and_related'] added_node_instances = [instance for instance in added_and_related if instance.get('modification') == 'added'] self._create_deployment_node_instances(deployment_id, added_node_instances) self._wait_for_count(expected_count=(len(node_instances) + len(added_node_instances)), query_method=self._get_node_instance_ids, deployment_id=deployment_id) return { 'node_instances': node_instances_modification, 'modified_nodes': modified_nodes }
def start_deployment_modification(self, deployment_id, modified_nodes, context): # verify deployment exists self.sm.get_deployment(deployment_id, include=['id']) deployment_id_filter = self.create_filters_dict( deployment_id=deployment_id) existing_modifications = self.sm.deployment_modifications_list( include=['id', 'status']).items active_modifications = [ m.id for m in existing_modifications if m.status == models.DeploymentModification.STARTED] if active_modifications: raise \ manager_exceptions.ExistingStartedDeploymentModificationError( 'Cannot start deployment modification while there are ' 'existing started deployment modifications. Currently ' 'started deployment modifications: {0}' .format(active_modifications)) nodes = [node.to_dict() for node in self.sm.get_nodes( filters=deployment_id_filter).items] node_instances = [instance.to_dict() for instance in self.sm.get_node_instances( filters=deployment_id_filter).items] node_instances_modification = tasks.modify_deployment( nodes=nodes, previous_node_instances=node_instances, modified_nodes=modified_nodes) node_instances_modification['before_modification'] = [ instance.to_dict() for instance in self.sm.get_node_instances(filters=deployment_id_filter).items] now = str(datetime.now()) modification_id = str(uuid.uuid4()) modification = models.DeploymentModification( id=modification_id, created_at=now, ended_at=None, status=models.DeploymentModification.STARTED, deployment_id=deployment_id, modified_nodes=modified_nodes, node_instances=node_instances_modification, context=context) self.sm.put_deployment_modification(modification_id, modification) for node_id, modified_node in modified_nodes.items(): self.sm.update_node( modification.deployment_id, node_id, planned_number_of_instances=modified_node['instances']) added_and_related = node_instances_modification['added_and_related'] added_node_instances = [] for node_instance in added_and_related: if node_instance.get('modification') == 'added': added_node_instances.append(node_instance) else: current = self.sm.get_node_instance(node_instance['id']) new_relationships = current.relationships new_relationships += node_instance['relationships'] self.sm.update_node_instance(models.DeploymentNodeInstance( id=node_instance['id'], relationships=new_relationships, version=current.version, node_id=None, host_id=None, deployment_id=None, state=None, runtime_properties=None)) self._create_deployment_node_instances(deployment_id, added_node_instances) return modification
def start_deployment_modification(self, deployment_id, modified_nodes, context): deployment = self.sm.get_deployment(deployment_id) deployment_id_filter = self.create_filters_dict( deployment_id=deployment_id) existing_modifications = self.sm.deployment_modifications_list( include=['id', 'status']).items active_modifications = [ m.id for m in existing_modifications if m.status == models.DeploymentModification.STARTED] if active_modifications: raise \ manager_exceptions.ExistingStartedDeploymentModificationError( 'Cannot start deployment modification while there are ' 'existing started deployment modifications. Currently ' 'started deployment modifications: {0}' .format(active_modifications)) nodes = [node.to_dict() for node in self.sm.get_nodes( filters=deployment_id_filter).items] node_instances = [instance.to_dict() for instance in self.sm.get_node_instances( filters=deployment_id_filter).items] node_instances_modification = tasks.modify_deployment( nodes=nodes, previous_nodes=nodes, previous_node_instances=node_instances, modified_nodes=modified_nodes, scaling_groups=deployment.scaling_groups) node_instances_modification['before_modification'] = [ instance.to_dict() for instance in self.sm.get_node_instances(filters=deployment_id_filter).items] now = str(datetime.now()) modification_id = str(uuid.uuid4()) modification = models.DeploymentModification( id=modification_id, created_at=now, ended_at=None, status=models.DeploymentModification.STARTED, deployment_id=deployment_id, modified_nodes=modified_nodes, node_instances=node_instances_modification, context=context) self.sm.put_deployment_modification(modification_id, modification) for node_id, modified_node in modified_nodes.items(): if node_id in deployment.scaling_groups: deployment.scaling_groups[node_id]['properties'].update({ 'planned_instances': modified_node['instances'] }) else: self.sm.update_node( modification.deployment_id, node_id, planned_number_of_instances=modified_node['instances']) self.sm.update_deployment(deployment) added_and_related = node_instances_modification['added_and_related'] added_node_instances = [] for node_instance in added_and_related: if node_instance.get('modification') == 'added': added_node_instances.append(node_instance) else: node = self.sm.get_node(deployment_id=deployment_id, node_id=node_instance['node_id'], include=['relationships']) target_names = [r['target_id'] for r in node.relationships] current = self.sm.get_node_instance(node_instance['id']) current_relationship_groups = { target_name: list(group) for target_name, group in itertools.groupby( current.relationships, key=lambda r: r['target_name']) } new_relationship_groups = { target_name: list(group) for target_name, group in itertools.groupby( node_instance['relationships'], key=lambda r: r['target_name']) } new_relationships = [] for target_name in target_names: new_relationships += current_relationship_groups.get( target_name, []) new_relationships += new_relationship_groups.get( target_name, []) self.sm.update_node_instance(models.DeploymentNodeInstance( id=node_instance['id'], relationships=new_relationships, version=current.version, node_id=None, host_id=None, deployment_id=None, state=None, runtime_properties=None, scaling_groups=None)) self._create_deployment_node_instances(deployment_id, added_node_instances) return modification