Skip to content

Commit e098496

Browse files
authored
fix: Export all visible default edges (#12)
1 parent 1b91b8b commit e098496

File tree

5 files changed

+51
-39
lines changed

5 files changed

+51
-39
lines changed

cloud2sql/collect_plugins.py

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
from queue import Queue
88
from threading import Event
99
from time import sleep
10-
from typing import Dict, Optional, List, Any
10+
from typing import Dict, Optional, List, Any, Tuple
1111

1212
import pkg_resources
1313
import yaml
1414
from resotoclient import Kind, Model
1515
from resotolib.args import Namespace
1616
from resotolib.baseplugin import BaseCollectorPlugin
17-
from resotolib.baseresources import BaseResource
17+
from resotolib.baseresources import BaseResource, EdgeType
1818
from resotolib.config import Config
1919
from resotolib.core.actions import CoreFeedback
2020
from resotolib.core.model_export import node_to_dict
@@ -50,7 +50,6 @@ def collectors(raw_config: Json, feedback: CoreFeedback) -> Dict[str, BaseCollec
5050

5151

5252
def configure(path_to_config: Optional[str]) -> Json:
53-
# Config.init_default_config()
5453
if path_to_config:
5554
with open(path_to_config) as f:
5655
return yaml.safe_load(f) # type: ignore
@@ -61,6 +60,30 @@ def collect(collector: BaseCollectorPlugin, engine: Engine, feedback: CoreFeedba
6160
# collect cloud data
6261
feedback.progress_done(collector.cloud, 0, 1)
6362
collector.collect()
63+
64+
# group all nodes by kind
65+
nodes_by_kind: Dict[str, List[Json]] = defaultdict(list)
66+
node: BaseResource
67+
for node in collector.graph.nodes:
68+
node._graph = collector.graph
69+
# create an exported node with the same scheme as resotocore
70+
exported = node_to_dict(node)
71+
exported["type"] = "node"
72+
exported["ancestors"] = {
73+
"cloud": {"reported": {"id": node.cloud().name}},
74+
"account": {"reported": {"id": node.account().name}},
75+
"region": {"reported": {"id": node.region().name}},
76+
"zone": {"reported": {"id": node.zone().name}},
77+
}
78+
nodes_by_kind[node.kind].append(exported)
79+
80+
# group all edges by kind of from/to
81+
edges_by_kind: Dict[Tuple[str, str], List[Json]] = defaultdict(list)
82+
for from_node, to_node, key in collector.graph.edges:
83+
if key.edge_type == EdgeType.default:
84+
edge_node = {"from": from_node.chksum, "to": to_node.chksum, "type": "edge"}
85+
edges_by_kind[(from_node.kind, to_node.kind)].append(edge_node)
86+
6487
# read the kinds created from this collector
6588
kinds = [from_json(m, Kind) for m in collector.graph.export_model(walk_subclasses=False)]
6689
updater = sql_updater(Model({k.fqn: k for k in kinds}), engine)
@@ -73,25 +96,9 @@ def collect(collector: BaseCollectorPlugin, engine: Engine, feedback: CoreFeedba
7396
with engine.connect() as conn:
7497
with conn.begin():
7598
# create the ddl metadata from the kinds
76-
updater.create_schema(conn, args)
99+
updater.create_schema(conn, args, list(edges_by_kind.keys()))
77100
feedback.progress_done(schema, 1, 1, context=[collector.cloud])
78101

79-
# group all nodes by kind
80-
nodes_by_kind = defaultdict(list)
81-
node: BaseResource
82-
for node in collector.graph.nodes:
83-
node._graph = collector.graph
84-
# create an exported node with the same scheme as resotocore
85-
exported = node_to_dict(node)
86-
exported["type"] = "node"
87-
exported["ancestors"] = {
88-
"cloud": {"reported": {"id": node.cloud().name}},
89-
"account": {"reported": {"id": node.account().name}},
90-
"region": {"reported": {"id": node.region().name}},
91-
"zone": {"reported": {"id": node.zone().name}},
92-
}
93-
nodes_by_kind[node.kind].append(exported)
94-
95102
# insert batches of nodes by kind
96103
for kind, nodes in nodes_by_kind.items():
97104
log.info(f"Inserting {len(nodes)} nodes of kind {kind}")
@@ -100,12 +107,6 @@ def collect(collector: BaseCollectorPlugin, engine: Engine, feedback: CoreFeedba
100107
ne_count += len(nodes)
101108
feedback.progress_done(syncdb, ne_count, node_edge_count, context=[collector.cloud])
102109

103-
# group all nodes by kind of from/to
104-
edges_by_kind = defaultdict(list)
105-
for from_node, to_node, _ in collector.graph.edges:
106-
edge_node = {"from": from_node.chksum, "to": to_node.chksum, "type": "edge"}
107-
edges_by_kind[(from_node.kind, to_node.kind)].append(edge_node)
108-
109110
# insert batches of edges by from/to kind
110111
for from_to, nodes in edges_by_kind.items():
111112
log.info(f"Inserting {len(nodes)} edges from {from_to[0]} to {from_to[1]}")

cloud2sql/sql.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def insert_edges(self, from_to: Tuple[str, str], nodes: List[Json]) -> Iterator[
7070
pass
7171

7272
@abstractmethod
73-
def create_schema(self, connection: Connection, args: Namespace) -> MetaData:
73+
def create_schema(self, connection: Connection, args: Namespace, edges: List[Tuple[str, str]]) -> MetaData:
7474
pass
7575

7676
@staticmethod
@@ -141,7 +141,7 @@ def base_props_not_visited(kd: Kind) -> Tuple[List[Property], List[str]]:
141141
prs, scs = base_props_not_visited(kind)
142142
return prs + carz, scs
143143

144-
def create_schema(self, connection: Connection, args: Namespace) -> MetaData:
144+
def create_schema(self, connection: Connection, args: Namespace, edges: List[Tuple[str, str]]) -> MetaData:
145145
log.info(f"Create schema for {len(self.table_kinds)} kinds and their relationships")
146146

147147
def table_schema(kind: Kind) -> None:
@@ -182,6 +182,9 @@ def link_table_schema_from_successors(kind: Kind) -> None:
182182
# step 2: create link tables for all kinds
183183
for kind in self.table_kinds:
184184
link_table_schema_from_successors(kind)
185+
# step 3: create link tables for all seen edges
186+
for from_kind, to_kind in edges:
187+
link_table_schema(from_kind, to_kind)
185188

186189
# drop tables if requested
187190
self.metadata.drop_all(connection)

tests/collect_plugins_test.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,23 @@ def test_collect() -> None:
1717
# get all tables
1818
metadata = MetaData()
1919
metadata.reflect(bind=engine)
20-
assert set(metadata.tables.keys()) == {
21-
"example_account",
22-
"example_custom_resource",
23-
"example_instance",
24-
"example_network",
25-
"example_region",
26-
"example_volume",
20+
expected_counts = {
21+
"example_account": 1,
22+
"example_custom_resource": 1,
23+
"example_instance": 2,
24+
"example_network": 2,
25+
"example_region": 2,
26+
"example_volume": 2,
27+
"link_example_account_example_region": 2,
28+
"link_example_instance_example_volume": 2,
29+
"link_example_network_example_instance": 2,
30+
"link_example_region_example_custom_resource": 1,
31+
"link_example_region_example_instance": 2,
32+
"link_example_region_example_network": 2,
33+
"link_example_region_example_volume": 2,
2734
}
28-
# check that there are entries in the tables
35+
36+
assert set(metadata.tables.keys()) == expected_counts.keys() # check that there are entries in the tables
2937
with Session(engine) as session:
3038
for table in metadata.tables.values():
31-
assert session.query(table).count() > 0
39+
assert session.query(table).count() == expected_counts[table.name]

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def engine() -> Engine:
7373
def engine_with_schema(updater: SqlDefaultUpdater, args: Namespace) -> Engine:
7474
engine = create_engine("sqlite:///:memory:")
7575
with engine.connect() as connection:
76-
updater.create_schema(connection, args)
76+
updater.create_schema(connection, args, [])
7777
return engine
7878

7979

tests/sql_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
def test_create_schema(model: Model, engine: Engine) -> None:
1313
updater: SqlDefaultUpdater = SqlDefaultUpdater(model)
1414
with engine.connect() as connection:
15-
updater.create_schema(connection, Namespace())
15+
updater.create_schema(connection, Namespace(), [])
1616

1717
info = MetaData()
1818
info.reflect(bind=engine)

0 commit comments

Comments
 (0)