oci-radar 1.0.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mor Michaeli
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.4
2
+ Name: oci-radar
3
+ Version: 1.0.0
4
+ Summary: CLI tool for OCI services inventory and diagramming
5
+ Author: Mor Michaeli
6
+ License-Expression: MIT
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: typer
14
+ Requires-Dist: pandas
15
+ Dynamic: license-file
16
+
17
+ # OCI Radar
18
+
19
+ CLI tool for Oracle Cloud Infrastructure (OCI) services inventory and diagramming.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ pip install -e .
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```bash
30
+ # Full run (inventory + diagram)
31
+ oci-radar run
32
+
33
+ # Inventory only
34
+ oci-radar inventory
35
+
36
+ # Diagram only (requires inventory CSV)
37
+ oci-radar diagram
38
+ ```
39
+
40
+ ## Prerequisites
41
+
42
+ - [OCI CLI](https://docs.oracle.com/iaas/Content/API/SDKDocs/cliinstall.htm) installed and configured (`oci setup config`)
43
+ - Set `OCI_COMPARTMENT_ID` env var, or the tool will resolve the root tenancy compartment automatically
44
+
45
+ ## Outputs
46
+
47
+ | File | Description |
48
+ |------|-------------|
49
+ | `oci_inventory.csv` | All resources across the tenancy |
50
+ | `oci_diagram.drawio` | draw.io diagram grouped by service type |
@@ -0,0 +1,34 @@
1
+ # OCI Radar
2
+
3
+ CLI tool for Oracle Cloud Infrastructure (OCI) services inventory and diagramming.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install -e .
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ # Full run (inventory + diagram)
15
+ oci-radar run
16
+
17
+ # Inventory only
18
+ oci-radar inventory
19
+
20
+ # Diagram only (requires inventory CSV)
21
+ oci-radar diagram
22
+ ```
23
+
24
+ ## Prerequisites
25
+
26
+ - [OCI CLI](https://docs.oracle.com/iaas/Content/API/SDKDocs/cliinstall.htm) installed and configured (`oci setup config`)
27
+ - Set `OCI_COMPARTMENT_ID` env var, or the tool will resolve the root tenancy compartment automatically
28
+
29
+ ## Outputs
30
+
31
+ | File | Description |
32
+ |------|-------------|
33
+ | `oci_inventory.csv` | All resources across the tenancy |
34
+ | `oci_diagram.drawio` | draw.io diagram grouped by service type |
File without changes
@@ -0,0 +1,23 @@
1
+ import typer
2
+
3
+ from . import inventory as inv_mod, diagram as dia_mod, operations as ops_mod
4
+
5
+ app = typer.Typer()
6
+
7
+ @app.command()
8
+ def inventory():
9
+ """Inventory OCI services"""
10
+ inv_mod.run_inventory()
11
+
12
+ @app.command()
13
+ def diagram():
14
+ """Generate diagram of OCI services"""
15
+ dia_mod.generate_diagram()
16
+
17
+ @app.command()
18
+ def run():
19
+ """Run operations on OCI services"""
20
+ ops_mod.run_operations()
21
+
22
+ def main():
23
+ app()
@@ -0,0 +1,74 @@
1
+ import pandas as pd
2
+
3
+ def generate_diagram():
4
+ """Generate draw.io diagram from OCI inventory"""
5
+ try:
6
+ try:
7
+ df = pd.read_csv('oci_inventory.csv')
8
+ except FileNotFoundError:
9
+ print("Inventory not found. Running inventory first...")
10
+ from . import inventory
11
+ inventory.run_inventory()
12
+ df = pd.read_csv('oci_inventory.csv')
13
+
14
+ service_counts = df['ServiceType'].value_counts().to_dict()
15
+
16
+ xml = generate_drawio_xml(service_counts)
17
+
18
+ with open('oci_diagram.drawio', 'w') as f:
19
+ f.write(xml)
20
+
21
+ print("Diagram saved to oci_diagram.drawio")
22
+ return True
23
+
24
+ except Exception as e:
25
+ print(f"Error generating diagram: {e}")
26
+ return False
27
+
28
+ def generate_drawio_xml(service_counts):
29
+ """Generate draw.io XML with OCI services"""
30
+ xml = '''<?xml version="1.0" encoding="UTF-8"?>
31
+ <mxfile host="app.diagrams.net" modified="2026-05-26T00:00:00.000Z" agent="oci-radar" version="15.8.7" type="device">
32
+ <diagram id="diagram1" name="OCI Services">
33
+ <mxGraphModel dx="1200" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" math="0" shadow="0">
34
+ <root>
35
+ <mxCell id="0"/>
36
+ <mxCell id="1" parent="0"/>
37
+ <mxCell id="title" value="OCI Services Inventory" style="text;html=1;fontSize=18;fontStyle=1;verticalAlign=middle;" vertex="1" parent="1">
38
+ <mxGeometry x="400" y="20" width="300" height="40" as="geometry"/>
39
+ </mxCell>
40
+ '''
41
+
42
+ y = 100
43
+ colors = {
44
+ 'Compute Instances': '#FF6B6B',
45
+ 'DB Systems': '#4ECDC4',
46
+ 'Autonomous DB': '#45B7D1',
47
+ 'Functions': '#96CEB4',
48
+ 'OKE': '#FFEAA7',
49
+ 'Object Storage': '#DDA0DD',
50
+ 'Container Instances': '#F8B88B',
51
+ 'Streaming': '#B4A7D6',
52
+ 'Data Science': '#A8E6CF',
53
+ 'Load Balancers': '#FFD3A5',
54
+ 'VCN': '#C3E6CB',
55
+ 'API Gateway': '#FFC0CB',
56
+ 'Vault Secrets': '#E2C9F5',
57
+ }
58
+
59
+ for service_type, count in sorted(service_counts.items()):
60
+ color = colors.get(service_type, '#CCCCCC')
61
+ safe_id = service_type.replace(' ', '_').replace('/', '_')
62
+
63
+ xml += f''' <mxCell id="service_{safe_id}" value="{service_type}&#xa;({count} resources)" style="rounded=1;whiteSpace=wrap;html=1;fillColor={color};fontSize=12;fontStyle=1;" vertex="1" parent="1">
64
+ <mxGeometry x="50" y="{y}" width="200" height="60" as="geometry"/>
65
+ </mxCell>
66
+ '''
67
+ y += 80
68
+
69
+ xml += ''' </root>
70
+ </mxGraphModel>
71
+ </diagram>
72
+ </mxfile>'''
73
+
74
+ return xml
@@ -0,0 +1,88 @@
1
+ import json
2
+ import subprocess
3
+ import os
4
+ import pandas as pd
5
+
6
+ def run_inventory():
7
+ """Run inventory using OCI CLI"""
8
+ try:
9
+ compartment_id = os.getenv('OCI_COMPARTMENT_ID')
10
+ if not compartment_id:
11
+ result = subprocess.run(
12
+ ['oci', 'iam', 'compartment', 'list', '--include-root', '--all',
13
+ '--query', 'data[?contains(id,`tenancy`)].id | [0]', '--raw-output'],
14
+ capture_output=True,
15
+ text=True,
16
+ check=True
17
+ )
18
+ compartment_id = result.stdout.strip()
19
+
20
+ if not compartment_id:
21
+ print("Error: Could not determine compartment ID. Set OCI_COMPARTMENT_ID or run 'oci setup config'")
22
+ return
23
+
24
+ print(f"Using compartment: {compartment_id}")
25
+
26
+ result = subprocess.run(
27
+ [
28
+ 'oci', 'search', 'resource', 'structured-search',
29
+ '--query-text', 'query all resources',
30
+ '--limit', '1000',
31
+ '--query', 'data.items[*].{name:displayName,type:resourceType,compartmentId:compartmentId,state:lifecycleState,region:identifier}',
32
+ '--output', 'json',
33
+ ],
34
+ capture_output=True,
35
+ text=True,
36
+ check=True
37
+ )
38
+
39
+ raw = json.loads(result.stdout)
40
+ items = raw if isinstance(raw, list) else raw.get('data', raw)
41
+
42
+ resources = []
43
+ for item in items:
44
+ res_type = item.get('type', '')
45
+ resources.append({
46
+ 'Name': item.get('name', ''),
47
+ 'Type': res_type,
48
+ 'ServiceType': normalize_service_type(res_type),
49
+ 'CompartmentId': item.get('compartmentId', ''),
50
+ 'State': item.get('state', ''),
51
+ 'Region': item.get('region', ''),
52
+ })
53
+
54
+ df = pd.DataFrame(resources)
55
+ df.to_csv('oci_inventory.csv', index=False)
56
+ print(f"Inventory saved to oci_inventory.csv ({len(resources)} resources)")
57
+
58
+ except subprocess.CalledProcessError as e:
59
+ print(f"Error running OCI CLI: {e.stderr}")
60
+ return
61
+ except FileNotFoundError:
62
+ print("Error: OCI CLI not found. Please install it: https://docs.oracle.com/iaas/Content/API/SDKDocs/cliinstall.htm")
63
+ return
64
+
65
+ def normalize_service_type(resource_type):
66
+ """Map OCI resource types to friendly service names"""
67
+ mappings = {
68
+ 'Instance': 'Compute Instances',
69
+ 'DbSystem': 'DB Systems',
70
+ 'AutonomousDatabase': 'Autonomous DB',
71
+ 'FunctionsApplication': 'Functions',
72
+ 'Cluster': 'OKE',
73
+ 'Bucket': 'Object Storage',
74
+ 'ContainerInstance': 'Container Instances',
75
+ 'Stream': 'Streaming',
76
+ 'DataScienceProject': 'Data Science',
77
+ 'LoadBalancer': 'Load Balancers',
78
+ 'Vcn': 'VCN',
79
+ 'Subnet': 'Subnets',
80
+ 'SecurityList': 'Security Lists',
81
+ 'InternetGateway': 'Internet Gateways',
82
+ 'NatGateway': 'NAT Gateways',
83
+ 'ServiceGateway': 'Service Gateways',
84
+ 'ApiGateway': 'API Gateway',
85
+ 'VaultSecret': 'Vault Secrets',
86
+ 'Key': 'Keys',
87
+ }
88
+ return mappings.get(resource_type, resource_type)
@@ -0,0 +1,40 @@
1
+ import subprocess
2
+ from . import inventory, diagram
3
+
4
+ def run_operations():
5
+ """Run full operations: inventory and diagram using OCI CLI"""
6
+ print("=== OCI Radar ===\n")
7
+
8
+ try:
9
+ result = subprocess.run(['oci', '--version'], capture_output=True, text=True)
10
+ if result.returncode != 0:
11
+ raise FileNotFoundError()
12
+ print("✓ OCI CLI found\n")
13
+ except FileNotFoundError:
14
+ print("✗ Error: OCI CLI not found")
15
+ print(" Install: https://docs.oracle.com/iaas/Content/API/SDKDocs/cliinstall.htm")
16
+ return False
17
+
18
+ try:
19
+ subprocess.run(
20
+ ['oci', 'iam', 'compartment', 'list', '--include-root', '--limit', '1'],
21
+ capture_output=True,
22
+ text=True,
23
+ check=True
24
+ )
25
+ print("✓ OCI authentication valid\n")
26
+ except subprocess.CalledProcessError:
27
+ print("✗ Error: Not authenticated to OCI")
28
+ print(" Run: oci setup config")
29
+ return False
30
+
31
+ print("--- Running Inventory ---")
32
+ inventory.run_inventory()
33
+ print()
34
+
35
+ print("--- Generating Diagram ---")
36
+ diagram.generate_diagram()
37
+ print()
38
+
39
+ print("✓ Operations completed successfully")
40
+ return True
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.4
2
+ Name: oci-radar
3
+ Version: 1.0.0
4
+ Summary: CLI tool for OCI services inventory and diagramming
5
+ Author: Mor Michaeli
6
+ License-Expression: MIT
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: typer
14
+ Requires-Dist: pandas
15
+ Dynamic: license-file
16
+
17
+ # OCI Radar
18
+
19
+ CLI tool for Oracle Cloud Infrastructure (OCI) services inventory and diagramming.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ pip install -e .
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```bash
30
+ # Full run (inventory + diagram)
31
+ oci-radar run
32
+
33
+ # Inventory only
34
+ oci-radar inventory
35
+
36
+ # Diagram only (requires inventory CSV)
37
+ oci-radar diagram
38
+ ```
39
+
40
+ ## Prerequisites
41
+
42
+ - [OCI CLI](https://docs.oracle.com/iaas/Content/API/SDKDocs/cliinstall.htm) installed and configured (`oci setup config`)
43
+ - Set `OCI_COMPARTMENT_ID` env var, or the tool will resolve the root tenancy compartment automatically
44
+
45
+ ## Outputs
46
+
47
+ | File | Description |
48
+ |------|-------------|
49
+ | `oci_inventory.csv` | All resources across the tenancy |
50
+ | `oci_diagram.drawio` | draw.io diagram grouped by service type |
@@ -0,0 +1,15 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ oci_radar/__init__.py
5
+ oci_radar/cli.py
6
+ oci_radar/diagram.py
7
+ oci_radar/inventory.py
8
+ oci_radar/operations.py
9
+ oci_radar.egg-info/PKG-INFO
10
+ oci_radar.egg-info/SOURCES.txt
11
+ oci_radar.egg-info/dependency_links.txt
12
+ oci_radar.egg-info/entry_points.txt
13
+ oci_radar.egg-info/requires.txt
14
+ oci_radar.egg-info/top_level.txt
15
+ tests/test_placeholder.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ oci-radar = oci_radar.cli:main
@@ -0,0 +1,2 @@
1
+ typer
2
+ pandas
@@ -0,0 +1,3 @@
1
+ dist
2
+ oci_radar
3
+ tests
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "oci-radar"
7
+ version = "1.0.0"
8
+ description = "CLI tool for OCI services inventory and diagramming"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ authors = [{name = "Mor Michaeli"}]
12
+ license = "MIT"
13
+ license-files = ["LICENSE"]
14
+ classifiers = [
15
+ "Development Status :: 5 - Production/Stable",
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = [
20
+ "typer",
21
+ "pandas",
22
+ ]
23
+
24
+ [project.scripts]
25
+ oci-radar = "oci_radar.cli:main"
26
+
27
+ [tool.setuptools.packages.find]
28
+ where = ["."]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ # Placeholder for tests