tgwrap 0.10.0__py3-none-any.whl → 0.10.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tgwrap/cli.py +7 -1
- tgwrap/inspector-resources-template.yml +5 -0
- tgwrap/main.py +100 -3
- {tgwrap-0.10.0.dist-info → tgwrap-0.10.2.dist-info}/METADATA +2 -4
- tgwrap-0.10.2.dist-info/RECORD +13 -0
- tgwrap-0.10.0.dist-info/RECORD +0 -13
- {tgwrap-0.10.0.dist-info → tgwrap-0.10.2.dist-info}/LICENSE +0 -0
- {tgwrap-0.10.0.dist-info → tgwrap-0.10.2.dist-info}/WHEEL +0 -0
- {tgwrap-0.10.0.dist-info → tgwrap-0.10.2.dist-info}/entry_points.txt +0 -0
tgwrap/cli.py
CHANGED
@@ -750,6 +750,11 @@ def check_deployments(manifest_file, verbose, working_dir, out):
|
|
750
750
|
help='Whether or not external dependencies must be ignored',
|
751
751
|
show_default=True
|
752
752
|
)
|
753
|
+
@click.option('--analyze', '-a',
|
754
|
+
is_flag=True, default=False,
|
755
|
+
help='Show analysis of the graph',
|
756
|
+
show_default=True
|
757
|
+
)
|
753
758
|
@click.option('--include-dir', '-I',
|
754
759
|
multiple=True, default=[],
|
755
760
|
help=r'A glob of a directory that needs to be included, this option can be used multiple times. For example: -I "integrations/\*/\*"',
|
@@ -765,7 +770,7 @@ def check_deployments(manifest_file, verbose, working_dir, out):
|
|
765
770
|
)
|
766
771
|
@click.argument('terragrunt-args', nargs=-1, type=click.UNPROCESSED)
|
767
772
|
@click.version_option(version=__version__)
|
768
|
-
def show_graph(verbose, backwards, exclude_external_dependencies, working_dir, include_dir, exclude_dir, terragrunt_args):
|
773
|
+
def show_graph(verbose, backwards, exclude_external_dependencies, analyze, working_dir, include_dir, exclude_dir, terragrunt_args):
|
769
774
|
""" Shows the dependencies of a project """
|
770
775
|
|
771
776
|
check_latest_version(verbose)
|
@@ -774,6 +779,7 @@ def show_graph(verbose, backwards, exclude_external_dependencies, working_dir, i
|
|
774
779
|
tgwrap.show_graph(
|
775
780
|
backwards=backwards,
|
776
781
|
exclude_external_dependencies=exclude_external_dependencies,
|
782
|
+
analyze=analyze,
|
777
783
|
working_dir=working_dir,
|
778
784
|
include_dirs=include_dir,
|
779
785
|
exclude_dirs=exclude_dir,
|
@@ -43,6 +43,11 @@ databricks_workspace:
|
|
43
43
|
properties:
|
44
44
|
properties.provisioningState: Succeeded
|
45
45
|
location: "{{location_code}}"
|
46
|
+
machine_learning_workspace:
|
47
|
+
url: https://management.azure.com/subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.MachineLearningServices/workspaces/{name}?api-version=2023-04-01
|
48
|
+
properties:
|
49
|
+
properties.provisioningState: Succeeded
|
50
|
+
location: "{{location_code}}"
|
46
51
|
data_factory:
|
47
52
|
url: https://management.azure.com/subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.DataFactory/factories/{name}?api-version=2018-06-01
|
48
53
|
properties:
|
tgwrap/main.py
CHANGED
@@ -1764,15 +1764,88 @@ Note:
|
|
1764
1764
|
except Exception:
|
1765
1765
|
pass
|
1766
1766
|
|
1767
|
-
def show_graph(self, backwards, exclude_external_dependencies, working_dir, include_dirs, exclude_dirs, terragrunt_args):
|
1767
|
+
def show_graph(self, backwards, exclude_external_dependencies, analyze, working_dir, include_dirs, exclude_dirs, terragrunt_args):
|
1768
1768
|
""" Shows the dependencies of a project """
|
1769
1769
|
|
1770
|
+
def set_json_dumps_default(obj):
|
1771
|
+
if isinstance(obj, set):
|
1772
|
+
return list(obj)
|
1773
|
+
raise TypeError
|
1774
|
+
|
1775
|
+
def calculate_dependencies(graph):
|
1776
|
+
dependencies = {}
|
1777
|
+
for node in graph.nodes:
|
1778
|
+
out_degree = graph.out_degree(node)
|
1779
|
+
in_degree = graph.in_degree(node)
|
1780
|
+
total_degree = out_degree + in_degree
|
1781
|
+
dependencies[node] = {
|
1782
|
+
'dependencies': out_degree,
|
1783
|
+
'dependent_on_it': in_degree,
|
1784
|
+
'total': total_degree,
|
1785
|
+
}
|
1786
|
+
|
1787
|
+
return dependencies
|
1788
|
+
|
1789
|
+
def calculate_graph_metrics(graph):
|
1790
|
+
|
1791
|
+
metrics = {}
|
1792
|
+
|
1793
|
+
# Degree centrality
|
1794
|
+
metric = {
|
1795
|
+
'values': dict(sorted(nx.degree_centrality(graph).items(), key=lambda item: item[1], reverse=True)),
|
1796
|
+
'description': 'Shows the degree of each node relative to the number of nodes in the graph',
|
1797
|
+
}
|
1798
|
+
sorted_dependencies = sorted(dependencies.items(), key=lambda x: x[1]['total'], reverse=True)
|
1799
|
+
metrics['degree_centrality'] = metric
|
1800
|
+
|
1801
|
+
# Betweenness centrality
|
1802
|
+
metric = {
|
1803
|
+
'values': dict(sorted(nx.betweenness_centrality(graph).items(), key=lambda item: item[1], reverse=True)),
|
1804
|
+
'description': 'Indicates nodes that frequently lie on shortest paths between other nodes',
|
1805
|
+
}
|
1806
|
+
metrics['betweenness_centrality'] = metric
|
1807
|
+
|
1808
|
+
# Closeness centrality
|
1809
|
+
metric = {
|
1810
|
+
'values': dict(sorted(nx.closeness_centrality(graph).items(), key=lambda item: item[1], reverse=True)),
|
1811
|
+
'description': 'Reflects how quickly a node can reach other nodes in the graph',
|
1812
|
+
}
|
1813
|
+
metrics['closeness_centrality'] = metric
|
1814
|
+
|
1815
|
+
# Strongly Connected Components (SCC)
|
1816
|
+
metric = {
|
1817
|
+
'values': list(nx.strongly_connected_components(graph)),
|
1818
|
+
'description': 'Lists sets of nodes that are mutually reachable',
|
1819
|
+
}
|
1820
|
+
metrics['strongly_connected_components'] = metric
|
1821
|
+
|
1822
|
+
# Weakly Connected Components (WCC)
|
1823
|
+
metric = {
|
1824
|
+
'values': list(nx.weakly_connected_components(graph)),
|
1825
|
+
'description': 'Lists sets of nodes that are connected disregarding edge directions',
|
1826
|
+
}
|
1827
|
+
metrics['weakly_connected_components'] = metric
|
1828
|
+
|
1829
|
+
# Average Path Length (only if the graph is connected)
|
1830
|
+
if nx.is_strongly_connected(graph):
|
1831
|
+
metric = {
|
1832
|
+
'values': nx.average_shortest_path_length(graph),
|
1833
|
+
'description': 'Shows the average shortest path length, indicating the graph\'s efficiency',
|
1834
|
+
}
|
1835
|
+
metrics['average_path_length'] = metric
|
1836
|
+
|
1837
|
+
return metrics
|
1838
|
+
|
1770
1839
|
self.printer.verbose(f"Attempting to show dependencies")
|
1771
1840
|
if terragrunt_args:
|
1772
1841
|
self.printer.verbose(f"- with additional parameters: {' '.join(terragrunt_args)}")
|
1773
1842
|
|
1774
1843
|
"Runs the desired command in the directories as defined in the directed graph"
|
1775
1844
|
graph = self._get_di_graph(backwards=backwards, working_dir=working_dir)
|
1845
|
+
try:
|
1846
|
+
graph.remove_node(r'\n')
|
1847
|
+
except nx.exception.NetworkXError:
|
1848
|
+
pass
|
1776
1849
|
|
1777
1850
|
# first go through the groups and clean up where needed
|
1778
1851
|
groups = self._prepare_groups(
|
@@ -1792,6 +1865,27 @@ Note:
|
|
1792
1865
|
for directory in group:
|
1793
1866
|
self.printer.normal(f"- {directory}")
|
1794
1867
|
|
1868
|
+
if analyze:
|
1869
|
+
self.printer.header("Graph analysis", print_line_before=True)
|
1870
|
+
|
1871
|
+
self.printer.bold("Dependencies counts:", print_line_before=True)
|
1872
|
+
dependencies = calculate_dependencies(graph)
|
1873
|
+
sorted_dependencies = sorted(dependencies.items(), key=lambda x: x[1]['total'], reverse=True)
|
1874
|
+
for node, counts in sorted_dependencies:
|
1875
|
+
msg = f"""
|
1876
|
+
{node} ->
|
1877
|
+
\ttotal: {counts['total']}
|
1878
|
+
\tdependent on: {counts['dependent_on_it']}
|
1879
|
+
\tdependencies: {counts['dependencies']}
|
1880
|
+
"""
|
1881
|
+
self.printer.normal(msg)
|
1882
|
+
|
1883
|
+
metrics = calculate_graph_metrics(graph)
|
1884
|
+
for metric, item in metrics.items():
|
1885
|
+
self.printer.bold(f'Metric: {metric}')
|
1886
|
+
self.printer.normal(f'Description: {item["description"]}')
|
1887
|
+
self.printer.normal(json.dumps(item['values'], indent=2, default=set_json_dumps_default))
|
1888
|
+
|
1795
1889
|
def clean(self, working_dir):
|
1796
1890
|
""" Clean the temporary files of a terragrunt/terraform project """
|
1797
1891
|
|
@@ -1922,9 +2016,12 @@ Note:
|
|
1922
2016
|
exit_code = 0
|
1923
2017
|
self.printer.header('Inspection status:', print_line_before=True)
|
1924
2018
|
for k,v in results.items():
|
1925
|
-
msg = f"{v['type']}: {k}
|
2019
|
+
msg = f"""{v['type']}: {k}
|
2020
|
+
-> Resource: {v.get('inspect_status_code', 'NC')} ({v.get('inspect_message', 'not found')})""" # only since python 3.12 you can use things like \t and \n in an f-string
|
1926
2021
|
if 'rbac_assignment_status_code' in v:
|
1927
|
-
msg = msg + f
|
2022
|
+
msg = msg + f"""
|
2023
|
+
-> RBAC: {v['rbac_assignment_status_code']} ({v.get('rbac_assignment_message')})"
|
2024
|
+
""" # only since python 3.12 you can use things like \t and \n in an f-string
|
1928
2025
|
if v['inspect_status_code'] != 'OK' or v.get('rbac_assignment_status_code', 'OK') == 'NOK':
|
1929
2026
|
self.printer.error(msg=msg)
|
1930
2027
|
exit_code += 1
|
@@ -1,17 +1,15 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: tgwrap
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.2
|
4
4
|
Summary: A (terragrunt) wrapper around a (terraform) wrapper around ....
|
5
5
|
Home-page: https://gitlab.com/lunadata/tgwrap
|
6
6
|
License: MIT
|
7
7
|
Keywords: terraform,terragrunt,terrasafe,python
|
8
8
|
Author: Gerco Grandia
|
9
9
|
Author-email: gerco.grandia@4synergy.nl
|
10
|
-
Requires-Python: >=3.
|
10
|
+
Requires-Python: >=3.12,<4.0
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
13
|
-
Classifier: Programming Language :: Python :: 3.10
|
14
|
-
Classifier: Programming Language :: Python :: 3.11
|
15
13
|
Classifier: Programming Language :: Python :: 3.12
|
16
14
|
Requires-Dist: azure-core (>=1.30.2,<2.0.0)
|
17
15
|
Requires-Dist: azure-identity (>=1.17.1,<2.0.0)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
tgwrap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
tgwrap/analyze.py,sha256=TJvAKVIbWl8-8oxpTwXVBWU72q_XQKzUTlyMZ25cV2M,8728
|
3
|
+
tgwrap/cli.py,sha256=0SFzLJA-deut81Mpt6Giq77WK26vTDcajyFnPIHXR5c,31649
|
4
|
+
tgwrap/deploy.py,sha256=-fSk-Ix_HqrXY7KQX_L27TnFzIuhBHYv4xYJW6zRDN4,10243
|
5
|
+
tgwrap/inspector-resources-template.yml,sha256=Mos8NDzzZ3VxdXgeiVL9cmQfRcIXIHMLf79_KLwdXu8,3297
|
6
|
+
tgwrap/inspector.py,sha256=5pW7Ex1lkKRoXY6hZGbCNmSD2iRzgMSfqi9w7gb-AcY,16990
|
7
|
+
tgwrap/main.py,sha256=WKxlREE4QmdZKTHivhWa3K5yI40amGlmjBs4y7oCTqw,88748
|
8
|
+
tgwrap/printer.py,sha256=frn1PARd8A28mkRCYR6ybN2x0NBULhNOutn4l2U7REY,2754
|
9
|
+
tgwrap-0.10.2.dist-info/LICENSE,sha256=VT-AVxIXt3EQTC-7Hy1uPGnrDNJLqfcgLgJD78fiyx4,1065
|
10
|
+
tgwrap-0.10.2.dist-info/METADATA,sha256=TMYitOkytrAQdGcEIeCOeiyKLg5yAFtgnmiupyLiJjo,17476
|
11
|
+
tgwrap-0.10.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
12
|
+
tgwrap-0.10.2.dist-info/entry_points.txt,sha256=H8X0PMPmd4aW7Y9iyChZ0Ug6RWGXqhRUvHH-6f6Mxz0,42
|
13
|
+
tgwrap-0.10.2.dist-info/RECORD,,
|
tgwrap-0.10.0.dist-info/RECORD
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
tgwrap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
tgwrap/analyze.py,sha256=TJvAKVIbWl8-8oxpTwXVBWU72q_XQKzUTlyMZ25cV2M,8728
|
3
|
-
tgwrap/cli.py,sha256=UokTSBp84HZ9IAwn0MlGMUjpjL76SILWm1GNlVHAqr0,31482
|
4
|
-
tgwrap/deploy.py,sha256=-fSk-Ix_HqrXY7KQX_L27TnFzIuhBHYv4xYJW6zRDN4,10243
|
5
|
-
tgwrap/inspector-resources-template.yml,sha256=goQaqyaTb_o1fAuCBHl-6xc1Rul63Byqau5RQ4qJvTo,2992
|
6
|
-
tgwrap/inspector.py,sha256=5pW7Ex1lkKRoXY6hZGbCNmSD2iRzgMSfqi9w7gb-AcY,16990
|
7
|
-
tgwrap/main.py,sha256=zKddIfI7-KHd1lX9xXh_tqgnIUa8uOxqDSxsVNW-klg,84544
|
8
|
-
tgwrap/printer.py,sha256=frn1PARd8A28mkRCYR6ybN2x0NBULhNOutn4l2U7REY,2754
|
9
|
-
tgwrap-0.10.0.dist-info/LICENSE,sha256=VT-AVxIXt3EQTC-7Hy1uPGnrDNJLqfcgLgJD78fiyx4,1065
|
10
|
-
tgwrap-0.10.0.dist-info/METADATA,sha256=kH2A2ZYjEQPKQ0iGbJKiachqmV1yELC3j1k5g7ZWVyM,17578
|
11
|
-
tgwrap-0.10.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
12
|
-
tgwrap-0.10.0.dist-info/entry_points.txt,sha256=H8X0PMPmd4aW7Y9iyChZ0Ug6RWGXqhRUvHH-6f6Mxz0,42
|
13
|
-
tgwrap-0.10.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|