def save_issues_as_new_graph(self, issues): all_keys = [] for issue in issues: all_keys.append(issue['Key']) graph = GS_Graph() # save results in graph graph.add_nodes(all_keys) return Lambda_Graph().save_gs_graph(graph, graph_type='graph-search')
def test_save(self): (self.graph.add_node("RISK-424").add_node("ID-42").add_edge( "RISK-424", '', "ID-42").add_edge("RISK-424", '', "ID-7")) file = self.graph.save() loaded_graph = GS_Graph() loaded_graph.load(file) assert loaded_graph.nodes == self.graph.nodes assert len(loaded_graph.edges) == len(self.graph.edges) assert self.graph.render_puml().puml == loaded_graph.render_puml().puml
def get_gs_graph_from_most_recent_version(self, lucene_query): data = self.save_to_elk().get_most_recent_version_of_document(lucene_query) if data is None: return None graph = GS_Graph() if data.get('nodes'): graph.nodes = data.get('nodes') graph.edges = data.get('edges') graph.puml.puml = data.get('extra_data').get('puml') return graph
def graph_links(self, target, depth=1): if target is None: return None graph = self.get_gs_graph___by_name(target) # check if the value provided is a saved graph if graph is not None: # if it exists keys = graph.nodes # set keys to graph nodes else: # if not keys = target.upper().split(",") # use value as keys graph = GS_Graph() graph.add_all_linked_issues(keys, depth) return graph
def save_gs_graph(self, graph: GS_Graph, graph_name = None, graph_type = None, channel= None, user = None): nodes = graph.nodes edges = graph.edges puml = graph.puml.puml if '@enduml' not in puml: # means that graph is not rendered puml = graph.render_puml().puml extra_data = { "user" : user , "channel" : channel , "puml" : puml , "params" : graph.create_params , "stats" : graph.stats() } return self.save_graph(nodes, edges, extra_data, None, graph_name, graph_type)
def test_to_json__from_json(self): graph = self.graph graph.add_nodes(['abc', 'xyz', '123']).add_edges([('abc', '', 'xyz'), ('abc', '', '123')]) graph.create_params = ['in', 'unit test'] assert json.loads(graph.to_json()) == { 'create_params': ['in', 'unit test'], 'edges': [['abc', '', 'xyz'], ['abc', '', '123']], 'node_type': {}, 'nodes': ['abc', 'xyz', '123'], 'notes': [], 'puml_config': True, 'puml_options': { 'height': None, 'left-to-right': True, 'link-types-to-add': [], 'link-types-to-ignore': [], 'node-text-value': 'Summary', 'only-from-projects': [], 'show-edge-labels': True, 'show-key-in-text': True, 'width': None }, 'skin_params': [] } assert json.loads(graph.to_json(puml_config=False)) == { 'edges': [['abc', '', 'xyz'], ['abc', '', '123']], 'nodes': ['abc', 'xyz', '123'] } graph_json = graph.to_json() new_graph = GS_Graph().from_json(graph_json) new_graph_json = new_graph.to_json() assert graph_json == new_graph_json assert graph_json != GS_Graph().to_json() assert GS_Graph().from_json( graph.to_json(puml_config=False)).nodes == ['abc', 'xyz', '123']
def test_to_json__from_json__store_issues(self): graph = self.graph graph.add_nodes(['RISK-12', 'RISK-24', 'RISK-1084' ]).add_edges([('RISK-12', '', 'RISK-24'), ('RISK-12', '', 'RISK-1084')]) graph_json = graph.to_json(store_issues=True) assert set(json.loads(graph_json).get('issues')) == { 'RISK-12', 'RISK-24', 'RISK-1084' } assert set(GS_Graph().from_json(graph_json).issues) == { 'RISK-12', 'RISK-24', 'RISK-1084' }
def test____create_stakeholder_graph_from_security_story(self): #from gs_elk.API_Jira_Diagrams import API_Jira_Diagrams #graph = API_Jira_Diagrams().risks_story_mixed_orders_v2__puml() file = '/tmp/graph-sec-9195.json' graph = GS_Graph().load(file) issue_types_path = [ 'is Stakeholder', 'is created by R2', 'is created by R3', 'is created by R4', 'is created by VULN', 'is Vulnerability of', 'RISK supported by', 'risk reduced by', 'is child of', 'is fixed by' ] start_node = 'SEC-8651' self.graph.create_sub_graph_from_start_node(graph.nodes, start_node, issue_types_path) self.graph.add_link_types_as_nodes() self.graph.puml.save_tmp()
def view_schema(self): issues = self.graph.get_nodes_issues() schema = {} puml = self.graph.puml for edge in self.graph.edges: if issues[edge[0]]: from_issue_type = puml.fix_id( issues[edge[0]].get('Issue Type')) else: from_issue_type = 'NA' link_name = edge[1] if issues[edge[2]]: to_issue_type = puml.fix_id(issues[edge[2]].get('Issue Type')) else: to_issue_type = 'NA' schema_edge = (from_issue_type, link_name, to_issue_type) if schema.get(schema_edge) is None: schema[schema_edge] = { 'count': 0, 'from_issue_type': from_issue_type, 'link_name': link_name, 'to_issue_type': to_issue_type } schema.get(schema_edge)['count'] += 1 new_graph = GS_Graph() for item in schema.values(): new_graph.add_node(item.get('from_issue_type')) new_graph.add_node(item.get('to_issue_type')) new_graph.add_edge(item.get('from_issue_type'), item.get('link_name'), item.get('to_issue_type')) self.graph = new_graph self.graph.render_puml() return self.puml()
def setUp(self): self.graph = GS_Graph() self.result = None
def get_graph(self, graph_name): graph_json: str = self.get_graph_json(graph_name) graph: GS_Graph = GS_Graph().from_json(graph_json) return graph
def test_render_and_save_gs_graph_____org_chart(self): graph = GS_Graph() is_a_manager_nodes = graph.api_issues.all_link_types('it_assets')['is manager of'].keys() graph.add_nodes(is_a_manager_nodes) graph.add_linked_issues_of_type('is manager of') graph.render_and_save_to_elk ("test_save_gs_graph_____org_chart", "from unit test")
def test_save_gs_graph(self): graph = GS_Graph() graph.add_node("aaa") graph.add_edge("aaa","->","bbb") result = self.lambda_graph.save_gs_graph(graph, "test_save_gs_graph", "from unit test") Dev.pprint(result)
def test_get_gs_graph___from_user(self): user = '******' graph = GS_Graph().add_node("aaa").add_edge("aaa", "->", "bbb") self.lambda_graph.save_gs_graph(graph, user = user) graph = self.lambda_graph.get_gs_graph___from_user(user) assert graph.stats() == {'count_edges': 1, 'count_nodes': 1, 'size_puml': 90}
def test____load_and_render_left_to_right(self): file = '/tmp/graph-sec-9195.json' graph = GS_Graph().load(file) graph.puml_options['left-to-right'] = True graph.render_puml() graph.puml.save_tmp()
def epic_graph(key): return GS_Graph().add_nodes_from_epics()
class Test_GS_Graph(TestCase): def setUp(self): self.graph = GS_Graph() self.result = None def tearDown(self): if self.result is not None: Dev.pprint(self.result) def test_add_node(self): self.graph.add_node('a') assert self.graph.nodes == ['a'] def test_add_linked_issues_of_type(self): self.graph.add_node('SEC-9195') self.graph.add_linked_issues_of_types([ 'is parent of', 'supports RISK', 'creates RISK', 'is Vulnerability of', 'creates R2', 'creates R1', 'has Stakeholder' ]) self.graph.render_puml() self.graph.puml.save_tmp() #self.graph.save('/tmp/graph-sec-9195.json') #print(self.graph.puml.puml) # self.graph.puml.add_line("scale 2.25") # self.graph.puml.add_line("\tscale 2024 height \n") #self.graph.puml.add_line('skinparam handwritten true') # def test_add_all_linked_issues(self): # keys = ['RISK-1494'] # (self.graph.set_links_path_mode_to_down() # .set_puml_show_key_in_text (True) # #.set_puml_only_from_projects(['RISK', 'VULN']) # .set_puml_width (4000) # #.set_puml_height (6000) # .add_all_linked_issues (keys, 5) # #.add_link_types_as_nodes(self.graph.risk_links_paths_down) # .render_puml_and_save_tmp () # ) # # Dev.pprint(len(self.graph.nodes)) # Dev.pprint(len(self.graph.edges)) def test_add_all_linked_issues____with_color_coding_on_rating(self): issues = None def on_add_node(element, title, id, original_id): key = id.replace('_', '-') issue = issues.get(key) color = '#FFFFFF' if issue: rating = issue['Rating'] if rating == 'High': color = '#F37071' elif rating == 'Medium': color = '#F0BF99' elif rating == 'Low': color = '#78999D' elif rating == 'TBD': color = '#F7A4A4' node_puml = '{0} "<color:#000000>{1}</color>" as {2} {3}'.format( element, title, id, color) return node_puml self.graph.puml.on_add_node = on_add_node self.graph.puml.add_line("\tscale 3024 width \n") keys = ['RISK-1610'] # ['GSP-95'] # 'FACT-47', # (self.graph.set_puml_left_to_right(True).set_puml_only_from_projects([ 'RISK', 'VULN' ]).set_puml_show_key_in_text(False).set_puml_show_edge_labels( False).add_all_linked_issues(keys, 2)) issues = self.graph.get_nodes_issues() self.graph.render_puml() self.graph.puml.save_tmp() Dev.pprint(len(self.graph.nodes)) Dev.pprint(len(self.graph.edges)) #self.graph.render_puml_and_save_tmp() def test_add_all_linked_issues____with___risk_links_paths_down(self): issues = None def on_add_node(element, title, id, original_id): key = id.replace('_', '-') issue = issues.get(key) color = '#FFFFFF' if issue: status = issue['Status'] if status in ['Blocked', 'Backlog']: color = '#F37071' elif status in ['To VULN Assess', 'To Validate']: color = '#F0BF99' elif status == 'Allocated for Fix': color = '#78999D' elif status == 'Fixed': color = '#6DD1A3' node_puml = '{0} "<color:#000000>{1}</color>" as {2} {3}'.format( element, title, id, color) return node_puml self.graph.puml.on_add_node = on_add_node keys = ['IA-333' ] #['RISK-1526'] #['RISK-1610'] # ['GSP-95'] # 'FACT-47', # graph = self.graph #self.risk_links_paths_down (graph #.set_puml_node_edge_value("Status") .set_puml_link_types_to_add( graph.risk_links_paths_down ).set_puml_show_key_in_text(False).add_all_linked_issues(keys, 4)) issues = self.graph.get_nodes_issues() graph.render_puml_and_save_tmp() Dev.pprint(len(graph.nodes)) Dev.pprint(len(graph.edges)) def test_add_all_linked_issues____with___risk_links_paths_up(self): keys = ['SEC-8708'] #['RISK-1610'] # ['GSP-95'] # 'FACT-47', # graph = self.graph #self.risk_links_paths_down (graph #.set_puml_node_edge_value(None) .set_puml_link_types_to_add(graph.risk_links_paths_up ).add_all_linked_issues(keys, 5)) graph.render_puml_and_save_tmp() #self.graph.add_link_types_as_nodes() Dev.pprint(len(graph.nodes)) Dev.pprint(len(graph.edges)) @unittest.skip("needs fixing the ES index") def test_add_all_linked_issues____IT_Assets(self): it_systems = self.graph.api_issues.elastic( ).search_using_lucene_index_by_id('Issue\ Type: "IT Assets"') keys = list(it_systems.keys())[0:20] self.graph.set_puml_width(5000) self.graph.set_link_types_from_issues(it_systems) self.graph.set_puml_link_types_to_add(['has to be done after']) self.graph.add_all_linked_issues(keys, 1) self.graph.render_puml_and_save_tmp() return def test_add_link_types_as_nodes____GitHub(self): self.graph.add_node('IA-333') self.graph.add_linked_issues_of_types( ['is Vulnerable to', 'has Stakeholder']) self.graph.add_link_types_as_nodes() self.graph.render_puml_and_save_tmp() return # def test_edges__link_types(self): # self.graph.add_all_linked_issues( ['RISK-1610'], 2) # result = self.graph.get_unique_link_types() # #Dev.pprint(result) # assert len(result) == 22 def test_graph(self): self.result = self.graph.add_node('aaa').graph().nodes() def test_remove_with_links(self): (self.graph.add_node("RISK-424").add_node("ID-42").add_node( "ID-41").add_edge("RISK-424", '', "ID-42").add_edge("RISK-424", '', "ID-7")) Dev.pprint(self.graph.nodes) Dev.pprint(self.graph.edges) self.graph.remove_with_links() Dev.pprint(self.graph.nodes) Dev.pprint(self.graph.edges) def test_save(self): (self.graph.add_node("RISK-424").add_node("ID-42").add_edge( "RISK-424", '', "ID-42").add_edge("RISK-424", '', "ID-7")) file = self.graph.save() loaded_graph = GS_Graph() loaded_graph.load(file) assert loaded_graph.nodes == self.graph.nodes assert len(loaded_graph.edges) == len(self.graph.edges) assert self.graph.render_puml().puml == loaded_graph.render_puml().puml #loaded_graph.puml.save_tmp() #### use cases def test____create_org_chart_everybody(self): is_a_manager_nodes = self.graph.all_link_types( 'it_assets')['is manager of'].keys() self.graph.add_nodes(is_a_manager_nodes) self.graph.add_linked_issues_of_type('is manager of') self.graph.render_puml() self.graph.puml.save_tmp() def test____load_and_render_left_to_right(self): file = '/tmp/graph-sec-9195.json' graph = GS_Graph().load(file) graph.puml_options['left-to-right'] = True graph.render_puml() graph.puml.save_tmp() def test____create_stakeholder_graph_from_security_story(self): #from gs_elk.API_Jira_Diagrams import API_Jira_Diagrams #graph = API_Jira_Diagrams().risks_story_mixed_orders_v2__puml() file = '/tmp/graph-sec-9195.json' graph = GS_Graph().load(file) issue_types_path = [ 'is Stakeholder', 'is created by R2', 'is created by R3', 'is created by R4', 'is created by VULN', 'is Vulnerability of', 'RISK supported by', 'risk reduced by', 'is child of', 'is fixed by' ] start_node = 'SEC-8651' self.graph.create_sub_graph_from_start_node(graph.nodes, start_node, issue_types_path) self.graph.add_link_types_as_nodes() self.graph.puml.save_tmp() def test__create_graph_with_epic_data__top_level_okrs_up(self): graph = self.graph (graph.add_all_linked_issues( ['GSOKR-924']).add_nodes_from_epics().set_link_paths_to_ignore([ 'is child of', 'has Stakeholder' ]).set_links_path_mode_to_up().add_all_linked_issues(depth=3)) graph.render_puml_and_save_tmp() def test__create_graph_with_epic_data__top_level_okrs_down(self): graph = self.graph (graph.add_all_linked_issues(['GSOKR-924']).add_nodes_from_epics(). set_links_path_mode_to_up().set_link_paths_to_ignore([ 'is child of', 'has Stakeholder' ]).set_links_path_mode_to_up().add_all_linked_issues(depth=4)) graph.render_puml_and_save_tmp() def test__create_graph_for_epic_SEC_8694(self): graph = self.graph (graph.add_all_linked_issues(['SEC-8694']).add_nodes_from_epics(). set_links_path_mode_to_up().add_all_linked_issues(depth=2)) graph.render_puml_and_save_tmp() def test__create_graph_with_epic_data__sec_9195(self): graph = self.graph #Dev.pprint(self.graph.api_issues.epic_issues('SEC-9195')) #return (graph.add_all_linked_issues( ['GSOKR-924']).add_nodes_from_epics().set_link_paths_to_ignore([ 'is child of', 'has Stakeholder' ]).set_links_path_mode_to_up().add_all_linked_issues(depth=3)) Dev.pprint(len(graph.nodes)) graph.render_puml_and_save_tmp() # def test__create_graph_with_epic_data__assignee(self): # keys = ['SEC-9696'] # graph = self.graph # (graph .set_links_path_mode_to_down() # .add_all_linked_issues(keys, 1) # .add_nodes_from_epics() # .add_all_linked_issues() # .set_puml_node_text_value('Assignee') # ) # self.graph.render_puml() # self.graph.puml.save_tmp() # # #graph.render_puml_and_save_tmp() # # API_Slack('DDKUZTK6X').puml_to_slack(graph.puml.puml) def test__create_graph_with_up_down_data(self): keys = ['SEC-9696'] graph = self.graph (graph # .set_puml_node_edge_value(None) .set_puml_link_types_to_add(graph.risk_links_paths_down ).add_all_linked_issues(keys, 1)) graph.render_puml_and_save_tmp() def test__create_graph_with_up_down_data(self): keys = ['IA-386'] graph = self.graph (graph.set_puml_link_types_to_add(["is parent of" ]).add_all_linked_issues(keys, 2) # was 6 .set_puml_direction_top_down()) graph.render_puml_and_save_tmp() def tests_expand_link_types_to_add(self): self.graph.set_puml_link_types_to_add(['risks_up','stakeholders_up']) \ .expand_link_types_to_add() def test__create_graph_with_special_link_types(self): keys = ['RISK-1494'] graph = self.graph (graph # .set_puml_node_edge_value(None) .set_puml_link_types_to_add(['risks_down'] ).add_all_linked_issues(keys, 5)) graph.render_puml_and_save_tmp() #Dev.pprint(result) def test_to_json__from_json(self): graph = self.graph graph.add_nodes(['abc', 'xyz', '123']).add_edges([('abc', '', 'xyz'), ('abc', '', '123')]) graph.create_params = ['in', 'unit test'] assert json.loads(graph.to_json()) == { 'create_params': ['in', 'unit test'], 'edges': [['abc', '', 'xyz'], ['abc', '', '123']], 'node_type': {}, 'nodes': ['abc', 'xyz', '123'], 'notes': [], 'puml_config': True, 'puml_options': { 'height': None, 'left-to-right': True, 'link-types-to-add': [], 'link-types-to-ignore': [], 'node-text-value': 'Summary', 'only-from-projects': [], 'show-edge-labels': True, 'show-key-in-text': True, 'width': None }, 'skin_params': [] } assert json.loads(graph.to_json(puml_config=False)) == { 'edges': [['abc', '', 'xyz'], ['abc', '', '123']], 'nodes': ['abc', 'xyz', '123'] } graph_json = graph.to_json() new_graph = GS_Graph().from_json(graph_json) new_graph_json = new_graph.to_json() assert graph_json == new_graph_json assert graph_json != GS_Graph().to_json() assert GS_Graph().from_json( graph.to_json(puml_config=False)).nodes == ['abc', 'xyz', '123'] def test_to_json__from_json__store_issues(self): graph = self.graph graph.add_nodes(['RISK-12', 'RISK-24', 'RISK-1084' ]).add_edges([('RISK-12', '', 'RISK-24'), ('RISK-12', '', 'RISK-1084')]) graph_json = graph.to_json(store_issues=True) assert set(json.loads(graph_json).get('issues')) == { 'RISK-12', 'RISK-24', 'RISK-1084' } assert set(GS_Graph().from_json(graph_json).issues) == { 'RISK-12', 'RISK-24', 'RISK-1084' }
def expand(team_id=None, channel=None, params=None, data=None, only_create=False, save_graph=True): if len(params) < 3: text = ':red_circle: Hi, for the `expand` command, you need to provide the following parameters: ' attachment_text = '- *graph_name*: the graph to expand\n' \ '- *depth* : how many cycles to expand\n' \ '- *links to expand*: as a comma-delimited list ' slack_message(text, [{'text': attachment_text}], channel, team_id) return create_params = ["expand"] + list( params ) # create copy of array so that we don't lose data with the pops below graph_or_key = params.pop(0) depth = int(params.pop(0)) link_types_to_add = ' '.join(params).split(',') graph = Lambda_Graph().get_gs_graph___by_name(graph_or_key) if graph is None: graph = GS_Graph() # if it wasn't a graph graph.add_node(graph_or_key) # use it as key (graph.set_puml_link_types_to_add( link_types_to_add).add_all_linked_issues( [], depth).set_create_params(create_params)) if save_graph: new_graph_name = graph.reset_puml().render_and_save_to_elk() else: return graph if only_create: return graph, new_graph_name, graph_or_key, depth, link_types_to_add if channel: # if the channel value is provided render the new graph and send it to slack, if not, just return the new graph data text = "Rendering new graph called `{0}`,\n Which was created by expanding the graph/key `{1}` with depth `{2}`, for link types `{3}` (`{4}` nodes, `{5}` edges)"\ .format(new_graph_name, graph_or_key, depth, link_types_to_add, len(graph.nodes), len(graph.edges)) slack_message(text, [], channel, team_id) Lambda('gw_bot.lambdas.puml_to_slack').invoke({ "puml": graph.get_puml(), "channel": channel, "team_id": team_id }) else: data = { "graph_or_key": graph_or_key, "depth": depth, "nodes": graph.nodes, "edges": graph.edges, "puml": graph.puml.puml, "graph_name": new_graph_name } return json.dumps(data, indent=4)
def test_get_graph_data(self): graph_name = 'graph_I3H' #graph_name = 'graph_782' # graph_name = 'graph_N59' source_graph_data = Lambda_Graph().get_graph_data(graph_name) root_key = 'Issues Created' gs_graph = GS_Graph() gs_graph.add_node(root_key) for key, node in source_graph_data['nodes'].items(): if node is None: continue creator = node.get('Creator') issue_type = node.get('Issue Type') issue_type_key = f'{issue_type}-{creator}' gs_graph.add_node(key) gs_graph.add_node(creator) gs_graph.add_node(issue_type_key) gs_graph.add_edge(root_key, '..', creator) gs_graph.add_edge(creator, '..', issue_type_key) gs_graph.add_edge(issue_type_key, '..', key) self.result = Lambda_Graph().save_gs_graph(gs_graph)