nuvu-scan 1.3.8__py3-none-any.whl → 2.0.0__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.
- nuvu_scan/__init__.py +1 -1
- nuvu_scan/cli/commands/scan.py +32 -0
- nuvu_scan/cli/formatters/html.py +262 -10
- nuvu_scan/cli/main.py +2 -1
- nuvu_scan/core/base.py +6 -0
- nuvu_scan/core/providers/aws/aws_scanner.py +41 -15
- nuvu_scan/core/providers/aws/collectors/athena.py +3 -0
- nuvu_scan/core/providers/aws/collectors/glue.py +420 -15
- nuvu_scan/core/providers/aws/collectors/iam.py +9 -0
- nuvu_scan/core/providers/aws/collectors/redshift.py +718 -40
- nuvu_scan/core/providers/gcp/gcp_scanner.py +42 -10
- {nuvu_scan-1.3.8.dist-info → nuvu_scan-2.0.0.dist-info}/METADATA +58 -14
- {nuvu_scan-1.3.8.dist-info → nuvu_scan-2.0.0.dist-info}/RECORD +15 -15
- {nuvu_scan-1.3.8.dist-info → nuvu_scan-2.0.0.dist-info}/entry_points.txt +1 -0
- {nuvu_scan-1.3.8.dist-info → nuvu_scan-2.0.0.dist-info}/WHEEL +0 -0
|
@@ -50,11 +50,11 @@ class GCPScanner(CloudProviderScan):
|
|
|
50
50
|
try:
|
|
51
51
|
creds, _ = default()
|
|
52
52
|
return creds
|
|
53
|
-
except DefaultCredentialsError:
|
|
53
|
+
except DefaultCredentialsError as e:
|
|
54
54
|
raise ValueError(
|
|
55
55
|
"GCP credentials not found. Provide service_account_key_file, "
|
|
56
56
|
"service_account_key_json, or set GOOGLE_APPLICATION_CREDENTIALS"
|
|
57
|
-
)
|
|
57
|
+
) from e
|
|
58
58
|
|
|
59
59
|
def _get_project_id(self) -> str:
|
|
60
60
|
"""Get GCP project ID from credentials or config."""
|
|
@@ -72,17 +72,49 @@ class GCPScanner(CloudProviderScan):
|
|
|
72
72
|
|
|
73
73
|
raise ValueError("GCP project_id is required. Set it in credentials or use --gcp-project")
|
|
74
74
|
|
|
75
|
+
# Map of collector names to their classes for filtering
|
|
76
|
+
COLLECTOR_MAP = {
|
|
77
|
+
"gcs": GCSCollector,
|
|
78
|
+
"bigquery": BigQueryCollector,
|
|
79
|
+
"dataproc": DataprocCollector,
|
|
80
|
+
"pubsub": PubSubCollector,
|
|
81
|
+
"iam": IAMCollector,
|
|
82
|
+
"gemini": GeminiCollector,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
def get_available_collectors(cls) -> list[str]:
|
|
87
|
+
"""Return list of available collector names."""
|
|
88
|
+
return list(cls.COLLECTOR_MAP.keys())
|
|
89
|
+
|
|
75
90
|
def _initialize_collectors(self) -> list:
|
|
76
|
-
"""Initialize
|
|
91
|
+
"""Initialize GCP service collectors based on config."""
|
|
77
92
|
collectors = []
|
|
78
93
|
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
collectors
|
|
94
|
+
# Get requested collectors from config
|
|
95
|
+
requested = self.config.collectors if self.config.collectors else []
|
|
96
|
+
|
|
97
|
+
# Normalize to lowercase
|
|
98
|
+
requested_lower = [c.lower() for c in requested]
|
|
99
|
+
|
|
100
|
+
# If no specific collectors requested, use all
|
|
101
|
+
if not requested_lower:
|
|
102
|
+
for collector_cls in self.COLLECTOR_MAP.values():
|
|
103
|
+
collectors.append(collector_cls(self.credentials, self.project_id))
|
|
104
|
+
else:
|
|
105
|
+
# Filter to only requested collectors
|
|
106
|
+
for name, collector_cls in self.COLLECTOR_MAP.items():
|
|
107
|
+
if name in requested_lower:
|
|
108
|
+
collectors.append(collector_cls(self.credentials, self.project_id))
|
|
109
|
+
|
|
110
|
+
# Warn about unknown collectors
|
|
111
|
+
known = set(self.COLLECTOR_MAP.keys())
|
|
112
|
+
unknown = set(requested_lower) - known
|
|
113
|
+
if unknown:
|
|
114
|
+
import sys
|
|
115
|
+
|
|
116
|
+
print(f"Warning: Unknown collectors ignored: {', '.join(unknown)}", file=sys.stderr)
|
|
117
|
+
print(f"Available collectors: {', '.join(sorted(known))}", file=sys.stderr)
|
|
86
118
|
|
|
87
119
|
return collectors
|
|
88
120
|
|
|
@@ -1,44 +1,53 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nuvu-scan
|
|
3
|
-
Version:
|
|
4
|
-
Summary: Multi-Cloud Data Asset Control -
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Multi-Cloud Data Asset Control - Discover, govern, and optimize your cloud data assets across AWS and GCP
|
|
5
5
|
Project-URL: Homepage, https://nuvu.dev
|
|
6
6
|
Project-URL: Documentation, https://github.com/nuvudev/nuvu-scan#readme
|
|
7
7
|
Project-URL: Repository, https://github.com/nuvudev/nuvu-scan
|
|
8
8
|
Project-URL: Issues, https://github.com/nuvudev/nuvu-scan/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/nuvudev/nuvu-scan/blob/main/CHANGELOG.md
|
|
9
10
|
Author-email: Nuvu <info@nuvu.dev>
|
|
10
11
|
License: Apache-2.0
|
|
11
|
-
Keywords: aws,cloud,data,governance,infrastructure,scanning
|
|
12
|
-
Classifier: Development Status ::
|
|
12
|
+
Keywords: aws,bigquery,cloud,cost-optimization,data,data-catalog,gcp,glue,governance,infrastructure,redshift,s3,scanning
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
13
15
|
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: System Administrators
|
|
14
17
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
15
19
|
Classifier: Programming Language :: Python :: 3
|
|
16
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
23
|
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Database :: Database Engines/Servers
|
|
20
25
|
Classifier: Topic :: System :: Systems Administration
|
|
21
26
|
Requires-Python: >=3.10
|
|
22
27
|
Requires-Dist: boto3>=1.28.0
|
|
28
|
+
Requires-Dist: botocore>=1.31.0
|
|
23
29
|
Requires-Dist: click>=8.0.0
|
|
24
30
|
Requires-Dist: google-api-python-client>=2.100.0
|
|
25
31
|
Requires-Dist: google-auth>=2.23.0
|
|
26
32
|
Requires-Dist: google-cloud-bigquery>=3.11.0
|
|
27
33
|
Requires-Dist: google-cloud-billing>=1.11.0
|
|
28
34
|
Requires-Dist: google-cloud-dataproc>=5.4.0
|
|
35
|
+
Requires-Dist: google-cloud-monitoring>=2.16.0
|
|
29
36
|
Requires-Dist: google-cloud-pubsub>=2.18.0
|
|
30
37
|
Requires-Dist: google-cloud-storage>=2.10.0
|
|
31
38
|
Provides-Extra: dev
|
|
32
|
-
Requires-Dist:
|
|
39
|
+
Requires-Dist: bandit>=1.7.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: boto3-stubs[essential]>=1.28.0; extra == 'dev'
|
|
33
41
|
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: pre-commit>=3.5.0; extra == 'dev'
|
|
34
43
|
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
35
44
|
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
36
|
-
Requires-Dist: ruff>=0.
|
|
45
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
37
46
|
Description-Content-Type: text/markdown
|
|
38
47
|
|
|
39
48
|
# Nuvu Scan
|
|
40
49
|
|
|
41
|
-
**Take Control of Your Cloud Data Estate**
|
|
50
|
+
**Take Control of Your Cloud Data Estate**
|
|
42
51
|
Discover, govern, and optimize your cloud data assets across **AWS and GCP** — reduce wasted spend, enforce compliance, and gain full visibility into unused, idle, or risky resources.
|
|
43
52
|
|
|
44
53
|
---
|
|
@@ -71,7 +80,7 @@ pip install nuvu-scan
|
|
|
71
80
|
|
|
72
81
|
### Optional: Push results to Nuvu Cloud
|
|
73
82
|
|
|
74
|
-
Nuvu Scan is fully open-source and runs standalone — no account required.
|
|
83
|
+
Nuvu Scan is fully open-source and runs standalone — no account required.
|
|
75
84
|
If you want dashboards, team workflows, and long‑term history, you can optionally push results to Nuvu Cloud.
|
|
76
85
|
|
|
77
86
|
```bash
|
|
@@ -186,6 +195,41 @@ nuvu scan --provider gcp --gcp-credentials /path/to/service-account-key.json --g
|
|
|
186
195
|
nuvu scan --provider gcp --gcp-project your-project-id --output-format json --output-file gcp-report.json
|
|
187
196
|
```
|
|
188
197
|
|
|
198
|
+
### Selective Scanning (Collectors)
|
|
199
|
+
|
|
200
|
+
Run focused scans on specific services instead of a full scan:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# List available collectors for a provider
|
|
204
|
+
nuvu scan --provider aws --list-collectors
|
|
205
|
+
# Output: athena, glue, iam, mwaa, redshift, s3
|
|
206
|
+
|
|
207
|
+
nuvu scan --provider gcp --list-collectors
|
|
208
|
+
# Output: bigquery, dataproc, gcs, gemini, iam, pubsub
|
|
209
|
+
|
|
210
|
+
# Scan only Redshift
|
|
211
|
+
nuvu scan --provider aws -c redshift --region us-west-2
|
|
212
|
+
|
|
213
|
+
# Scan multiple specific collectors
|
|
214
|
+
nuvu scan --provider aws -c redshift -c glue --region us-west-2
|
|
215
|
+
|
|
216
|
+
# Scan only S3 buckets
|
|
217
|
+
nuvu scan --provider aws -c s3 --output-format html
|
|
218
|
+
|
|
219
|
+
# Full scan (default - all collectors)
|
|
220
|
+
nuvu scan --provider aws # Runs all collectors
|
|
221
|
+
|
|
222
|
+
# GCP: Scan only BigQuery
|
|
223
|
+
nuvu scan --provider gcp -c bigquery --gcp-project your-project
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Benefits of selective scanning:**
|
|
227
|
+
- **Faster scans** - Focus on services you care about
|
|
228
|
+
- **Reduced API calls** - Only query the services you need
|
|
229
|
+
- **Targeted reports** - Generate reports for specific areas
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
189
233
|
## Features
|
|
190
234
|
|
|
191
235
|
- **Asset Discovery**: Automatically discovers cloud data assets:
|
|
@@ -225,7 +269,7 @@ Nuvu requires read-only access to your AWS account. The tool uses the following
|
|
|
225
269
|
```bash
|
|
226
270
|
# Option 1: Create IAM user
|
|
227
271
|
aws iam create-user --user-name nuvu-scan-readonly
|
|
228
|
-
|
|
272
|
+
|
|
229
273
|
# Option 2: Create IAM role (for EC2/ECS/Lambda)
|
|
230
274
|
aws iam create-role --role-name nuvu-scan-readonly --assume-role-policy-document file://trust-policy.json
|
|
231
275
|
```
|
|
@@ -234,7 +278,7 @@ Nuvu requires read-only access to your AWS account. The tool uses the following
|
|
|
234
278
|
```bash
|
|
235
279
|
# For IAM user
|
|
236
280
|
aws iam put-user-policy --user-name nuvu-scan-readonly --policy-name NuvuScanReadOnly --policy-document file://aws-iam-policy.json
|
|
237
|
-
|
|
281
|
+
|
|
238
282
|
# For IAM role
|
|
239
283
|
aws iam put-role-policy --role-name nuvu-scan-readonly --policy-name NuvuScanReadOnly --policy-document file://aws-iam-policy.json
|
|
240
284
|
```
|
|
@@ -254,7 +298,7 @@ Nuvu requires read-only access to your AWS account. The tool uses the following
|
|
|
254
298
|
```
|
|
255
299
|
|
|
256
300
|
**Method 2: Temporary Credentials (Access Key + Secret Key + Session Token)**
|
|
257
|
-
|
|
301
|
+
|
|
258
302
|
If you're using AWS SSO, assumed roles, or other temporary credentials:
|
|
259
303
|
```bash
|
|
260
304
|
export AWS_ACCESS_KEY_ID=your-access-key-id
|
|
@@ -264,7 +308,7 @@ Nuvu requires read-only access to your AWS account. The tool uses the following
|
|
|
264
308
|
```
|
|
265
309
|
|
|
266
310
|
**Method 3: IAM Role Assumption**
|
|
267
|
-
|
|
311
|
+
|
|
268
312
|
To assume a role (useful for cross-account access or when using a role with more permissions):
|
|
269
313
|
```bash
|
|
270
314
|
# With explicit credentials
|
|
@@ -272,11 +316,11 @@ Nuvu requires read-only access to your AWS account. The tool uses the following
|
|
|
272
316
|
--access-key-id your-access-key-id \
|
|
273
317
|
--secret-access-key your-secret-access-key \
|
|
274
318
|
--role-arn arn:aws:iam::123456789012:role/MyRole
|
|
275
|
-
|
|
319
|
+
|
|
276
320
|
# From default credentials (e.g., EC2 instance role)
|
|
277
321
|
nuvu scan --provider aws \
|
|
278
322
|
--role-arn arn:aws:iam::123456789012:role/MyRole
|
|
279
|
-
|
|
323
|
+
|
|
280
324
|
# With external ID (if required by the role)
|
|
281
325
|
nuvu scan --provider aws \
|
|
282
326
|
--role-arn arn:aws:iam::123456789012:role/MyRole \
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
nuvu_scan/__init__.py,sha256=
|
|
1
|
+
nuvu_scan/__init__.py,sha256=tsQim3nEvAmZ_2-lY6FPQSC5a4bAcUwltNYAn6bpaY0,68
|
|
2
2
|
nuvu_scan/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
nuvu_scan/cli/main.py,sha256=
|
|
3
|
+
nuvu_scan/cli/main.py,sha256=CI8ahTFALjd-HcGPAphXX8ZgJUtz7hG9l45MELOMwn0,396
|
|
4
4
|
nuvu_scan/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
nuvu_scan/cli/commands/scan.py,sha256=
|
|
5
|
+
nuvu_scan/cli/commands/scan.py,sha256=1FTILZXhQ2apz0HuMw9MyT0gZS75EsS0fXJBxyKePws,11622
|
|
6
6
|
nuvu_scan/cli/formatters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
nuvu_scan/cli/formatters/csv.py,sha256=xGC8Kl1SKOcflLsZqBNJEucZUxgacSmlU8vogWQpskg,1719
|
|
8
|
-
nuvu_scan/cli/formatters/html.py,sha256=
|
|
8
|
+
nuvu_scan/cli/formatters/html.py,sha256=1uhZL6utjnv5-iyLPo_4QqQFUi0fvhbrb4DHZbnl1nc,17894
|
|
9
9
|
nuvu_scan/cli/formatters/json.py,sha256=T2DoEOcQrqLRyEF8VnPPari-nD83U0kNwQwBBxySlFo,1668
|
|
10
10
|
nuvu_scan/core/__init__.py,sha256=G6Iqb0-Td7mEi1PteLoImeqAnzbPzBTv-q1qJ1q4j1A,217
|
|
11
|
-
nuvu_scan/core/base.py,sha256=
|
|
11
|
+
nuvu_scan/core/base.py,sha256=4xEv-qujS-6TnDGv3Vqgw9omnzdVPnMaGY5r1g_oN2A,6811
|
|
12
12
|
nuvu_scan/core/analyzers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
nuvu_scan/core/models/__init__.py,sha256=osGjl3G0LOYqaJoG_60_i9ZhAeGJ_0stZuMoxRO77aw,188
|
|
14
14
|
nuvu_scan/core/providers/__init__.py,sha256=aipXSMSaFB7TbLdjma4naxzChDOHFCo_VZbG-lbrpKs,105
|
|
15
15
|
nuvu_scan/core/providers/aws/__init__.py,sha256=R5ZPCc-qybHZh4v5w_D0tZc8cYJNuhlfCPnLg3Zr28A,98
|
|
16
|
-
nuvu_scan/core/providers/aws/aws_scanner.py,sha256=
|
|
16
|
+
nuvu_scan/core/providers/aws/aws_scanner.py,sha256=gBqzuKWVh6ZZ8uK5A7pt5QEiO1hPgqukrUoOicFv_i0,15296
|
|
17
17
|
nuvu_scan/core/providers/aws/collectors/__init__.py,sha256=uFPTKjtMFHCQwsZy9WmMSvKZpfuXU8SxCfQRhi6yUt0,373
|
|
18
|
-
nuvu_scan/core/providers/aws/collectors/athena.py,sha256=
|
|
18
|
+
nuvu_scan/core/providers/aws/collectors/athena.py,sha256=sHuFmZMZ1TM91DxmxrcCSZ6OiN9l7udlMQPnCg7nI70,5737
|
|
19
19
|
nuvu_scan/core/providers/aws/collectors/cost_explorer.py,sha256=qas79Cm_rCyYDzeL4F0cER90Ohyg9rN33fBHh4VA9og,6730
|
|
20
|
-
nuvu_scan/core/providers/aws/collectors/glue.py,sha256=
|
|
21
|
-
nuvu_scan/core/providers/aws/collectors/iam.py,sha256=
|
|
20
|
+
nuvu_scan/core/providers/aws/collectors/glue.py,sha256=_FsdpQrBN3gpkrteRL1Usslq-zUmDWJdzYQp7eBSyZ4,25137
|
|
21
|
+
nuvu_scan/core/providers/aws/collectors/iam.py,sha256=E3mifkmcDWym07OeUGX8s-UaWwa49W-pOMr5XvxdZmA,10771
|
|
22
22
|
nuvu_scan/core/providers/aws/collectors/mwaa.py,sha256=WSXB2kPIxpy82-6JX6Jkqkzjgh9rPZZuMf4AetfnTKs,12397
|
|
23
|
-
nuvu_scan/core/providers/aws/collectors/redshift.py,sha256=
|
|
23
|
+
nuvu_scan/core/providers/aws/collectors/redshift.py,sha256=b9dYIZ389xOtzmT-ml1-A_nkhCeHrJmjX0cmTLDLhYI,41612
|
|
24
24
|
nuvu_scan/core/providers/aws/collectors/s3.py,sha256=Ma8LMgEpUucN64uohQ2zlGIkUbxmRNkUbeSfZpPe3Pw,13093
|
|
25
25
|
nuvu_scan/core/providers/gcp/__init__.py,sha256=NZ8bStAq0Qt4IRcxaCBAkbJVUPQLQHRRTl0fUxVuTxg,98
|
|
26
|
-
nuvu_scan/core/providers/gcp/gcp_scanner.py,sha256=
|
|
26
|
+
nuvu_scan/core/providers/gcp/gcp_scanner.py,sha256=Vt2kRCMyLRTJsQjIyGHnNnJEGlgAh6bEpctR0L-_y5A,7264
|
|
27
27
|
nuvu_scan/core/providers/gcp/collectors/__init__.py,sha256=HbtMXas5Vh6kYz6RS1d_q7WQgIvZ_N5-fIR-UKHSi9M,394
|
|
28
28
|
nuvu_scan/core/providers/gcp/collectors/bigquery.py,sha256=K1uNN-I_PvR-jdyonY8hZT9LWyEftMKMxksizmkFfd8,14849
|
|
29
29
|
nuvu_scan/core/providers/gcp/collectors/billing.py,sha256=pA2vbHdzQSQR4_yR6wPF8gWN1CoPjRCQ5LVQG8BKoYs,4735
|
|
@@ -32,7 +32,7 @@ nuvu_scan/core/providers/gcp/collectors/gcs.py,sha256=qf-QMW56dR8C0Qg5snF1w7JNDV
|
|
|
32
32
|
nuvu_scan/core/providers/gcp/collectors/gemini.py,sha256=NsYTELcvdSGwSOFEmE3Zmp1bzto99iUCCr0yY4j54zg,17968
|
|
33
33
|
nuvu_scan/core/providers/gcp/collectors/iam.py,sha256=lusayhIwPLjzzpBEE7UD61-oVmceR1cYHstHWZq4VPA,8332
|
|
34
34
|
nuvu_scan/core/providers/gcp/collectors/pubsub.py,sha256=OMBSeWi2Hjp1jgpEQ-a8ecLxV1MRtVVgy0QlVlWnS2k,4953
|
|
35
|
-
nuvu_scan-
|
|
36
|
-
nuvu_scan-
|
|
37
|
-
nuvu_scan-
|
|
38
|
-
nuvu_scan-
|
|
35
|
+
nuvu_scan-2.0.0.dist-info/METADATA,sha256=FO_K95EjcPKGYOnJ-canTLMoIDejXhQSRneRaEiC4bw,21526
|
|
36
|
+
nuvu_scan-2.0.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
37
|
+
nuvu_scan-2.0.0.dist-info/entry_points.txt,sha256=dge4RP32Lsft0GA_oBPCwFAKZ_GgzD3eq-vD4LY-jPE,83
|
|
38
|
+
nuvu_scan-2.0.0.dist-info/RECORD,,
|
|
File without changes
|