def read_data_from_dir(cls, dir_path=None, serializer=None): """Read graph data from directory. :param dir_path: path :type dir_path: str :param serializer: serializer object :type serializer: object :return: data :rtype: list|object """ cls.check_dir(dir_path) serializer = serializer or Serializer() metadata_filepath = os.path.join(dir_path, 'metadata.yaml') if os.path.exists(metadata_filepath): data = serializer.read_from_full_path(metadata_filepath) else: data = {} tasks = [] for file_name in iterfiles(dir_path, 'tasks.yaml'): task_data = serializer.read_from_full_path(file_name) if task_data: tasks.extend(task_data) if tasks: data['tasks'] = tasks if not data: msg = ("Nothing to upload. Check if at least one 'tasks.yaml' " "file is not empty and exists in '{path}' directory " "path".format(path=dir_path)) raise error.ActionException(msg) return data
def delete_from_db(self, params): """To delete nodes from fuel db: fuel node --node-id 1 --delete-from-db fuel node --node-id 1 2 --delete-from-db (this works only for offline nodes) fuel node --node-id 1 --delete-from-db --force (this forces deletion of nodes regardless of their state) """ if not params.force: node_collection = NodeCollection.init_with_ids(params.node) online_nodes = [ node for node in node_collection.data if node['online'] ] if online_nodes: raise error.ActionException( "Nodes with ids {0} cannot be deleted from cluster " "because they are online. You might want to use the " "--force option.".format( [node['id'] for node in online_nodes])) NodeCollection.delete_by_ids(params.node) self.serializer.print_to_output( {}, "Nodes with ids {0} have been deleted from Fuel db.".format( params.node))
def get_env_id(self, node_collection): env_ids = set(n.env_id for n in node_collection) if len(env_ids) != 1: raise error.ActionException( "Inputed nodes assigned to multiple environments!") else: return env_ids.pop()
def full_path_directory(self, directory, base_name): full_path = os.path.join(directory, base_name) if not os.path.exists(full_path): try: os.mkdir(full_path) except OSError as e: raise error.ActionException(six.text_type(e)) return full_path
def unassign_all(self): nodes = self.get_all_nodes() if not nodes: raise error.ActionException( "Environment with id={0} doesn't have nodes to remove.".format( self.id)) return self.connection.post_request( "clusters/{0}/unassignment/".format(self.id), [{ "id": n.id } for n in nodes])
def take_action(self, parsed_args): data = self.client.get_by_id(parsed_args.id) if data['name'] != 'dump': msg = "Task with id {0} is not a snapshot generation task" raise error.ActionException(msg.format(data['id'])) if data['status'] != 'ready': data['link'] = None else: data['link'] = self.client.connection.root + data['message'] data = data_utils.get_display_data_single(self.columns, data) return self.columns, data
def get_status_single(self, testset_id): testrun_obj = self._entity_wrapper(testset_id) data = testrun_obj.get_tests_status_single() if data: result = [] # Retrieve and re-format 'tests' from nested data for clarity for tests in data.get('tests'): result.append("\n* {} - {}, ('{}')".format( tests["status"], tests["name"], tests["message"])) else: msg = "Test sets with id {0} does not exist".format(testset_id) raise error.ActionException(msg) data['tests'] = ' '.join(result) return data
def undiscover_nodes(self, env_id=None, node_id=None, force=False): """Delete nodes from database. If node_id is None then all nodes from specified environment will be deleted. :param env_id: Id of env to delete nodes from database :type env_id: int :param node_id: Id of node to delete from database :type node_id: int :param force: Forces deletion of nodes regardless of their state :type force: bool :returns: list -- ids of nodes that were deleted from database """ nodes = [] if node_id is not None: nodes.append(self._entity_wrapper(obj_id=node_id).data) elif env_id is not None: nodes.extend(self.get_all(environment_id=env_id)) if not nodes: raise error.ActionException( "Cluster with id {0} does not exist or " "does not contain any nodes".format(env_id)) else: raise ValueError('Expected either env_id or node_id args') # If 'force' flag is not specified then check nodes status if not force: online_nodes = [node for node in nodes if node['online']] if online_nodes: raise error.ActionException( "Nodes with ids {0} cannot be deleted from database " "because they are online. You might want to use the " "--force option.".format( [node['id'] for node in online_nodes])) node_ids = [node['id'] for node in nodes] objects.NodeCollection.delete_by_ids(node_ids) return node_ids
def start(self, params): """Deploy/Provision some node: fuel node --node-id 2 --provision fuel node --node-id 2 --deploy """ node_collection = NodeCollection.init_with_ids(params.node) method_type = "deploy" if params.deploy else "provision" env_id_to_start = self.get_env_id(node_collection) if not env_id_to_start: raise error.ActionException( "Input nodes are not assigned to any environment!") task = Environment(env_id_to_start).install_selected_nodes( method_type, node_collection.collection) self.serializer.print_to_output( task.data, "Started {0}ing {1}.".format(method_type, node_collection))
def render(self, params): """Render graph in PNG format fuel graph --render graph.gv fuel graph --render graph.gv --dir ./output/dir/ To apply transitive reduction filter on rendered graph: fuel graph --render graph.gv --tred fuel graph --render graph.gv --dir ./output/dir/ --tred Read graph from stdin some_process | fuel graph --render - """ if params.render == '-': dot_data = sys.stdin.read() out_filename = 'graph.gv' elif not os.path.exists(params.render): raise error.ArgumentException("Input file does not exist") else: out_filename = os.path.basename(params.render) with open(params.render, 'r') as f: dot_data = f.read() target_dir = self.full_path_directory( self.default_directory(params.dir), '') target_file = os.path.join( target_dir, '{0}.png'.format(out_filename), ) if not os.access(os.path.dirname(target_file), os.W_OK): raise error.ActionException( 'Path {0} is not writable'.format(target_file)) render_graph(dot_data, target_file, params.tred) print('Graph saved in "{0}"'.format(target_file))
def check_advanced_feature(cls): if 'advanced' not in cls._entity_wrapper.get_feature_groups(): msg = "Advanced feature should be enabled in feature groups" raise error.ActionException(msg)