Skip to content

Commit 4564d83

Browse files
committed
Additional Python formatting fixes with Black
1 parent 1b8ec24 commit 4564d83

11 files changed

Lines changed: 825 additions & 848 deletions

File tree

dev-tools/scripts/quality_check.py

Lines changed: 165 additions & 181 deletions
Large diffs are not rendered by default.

dev-tools/security/security_scan.py

Lines changed: 142 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -17,144 +17,190 @@
1717

1818
class SecurityScanner:
1919
"""Comprehensive security scanner for the project."""
20-
20+
2121
def __init__(self, project_root: Path):
2222
"""Initialize security scanner."""
2323
self.project_root = project_root
2424
self.results = {}
2525
self.sarif_files = []
26-
26+
2727
def run_bandit(self) -> Tuple[bool, str]:
2828
"""Run Bandit security linter with SARIF output."""
2929
print("Running Bandit security analysis...")
30-
30+
3131
try:
3232
# Check if bandit-sarif-formatter is available
3333
try:
3434
import bandit_sarif_formatter
35+
3536
sarif_available = True
3637
except ImportError:
3738
sarif_available = False
3839
print("WARNING: bandit-sarif-formatter not available, falling back to JSON")
39-
40+
4041
# Generate JSON output (always)
41-
subprocess.run([
42-
"python", "-m", "bandit", "-r", "src/",
43-
"-f", "json", "-o", "bandit-report.json"
44-
], cwd=self.project_root, check=False)
45-
42+
subprocess.run(
43+
["python", "-m", "bandit", "-r", "src/", "-f", "json", "-o", "bandit-report.json"],
44+
cwd=self.project_root,
45+
check=False,
46+
)
47+
4648
# Generate SARIF output if formatter is available
4749
if sarif_available:
48-
subprocess.run([
49-
"python", "-m", "bandit", "-r", "src/",
50-
"-f", "sarif", "-o", "bandit-report.sarif"
51-
], cwd=self.project_root, check=False)
52-
50+
subprocess.run(
51+
[
52+
"python",
53+
"-m",
54+
"bandit",
55+
"-r",
56+
"src/",
57+
"-f",
58+
"sarif",
59+
"-o",
60+
"bandit-report.sarif",
61+
],
62+
cwd=self.project_root,
63+
check=False,
64+
)
65+
5366
self.sarif_files.append("bandit-report.sarif")
5467
print("SUCCESS: Bandit SARIF report generated for GitHub Security integration")
55-
68+
5669
return True, "Bandit scan completed"
57-
70+
5871
except Exception as e:
5972
return False, f"Bandit scan failed: {e}"
60-
73+
6174
def run_safety(self) -> Tuple[bool, str]:
6275
"""Run Safety dependency vulnerability check."""
6376
print("Running Safety dependency scan...")
64-
77+
6578
try:
66-
result = subprocess.run([
67-
"python", "-m", "safety", "check", "--json"
68-
], cwd=self.project_root, capture_output=True, text=True)
69-
79+
result = subprocess.run(
80+
["python", "-m", "safety", "check", "--json"],
81+
cwd=self.project_root,
82+
capture_output=True,
83+
text=True,
84+
)
85+
7086
with open(self.project_root / "safety-report.json", "w") as f:
7187
f.write(result.stdout)
72-
88+
7389
return True, "Safety scan completed"
74-
90+
7591
except Exception as e:
7692
return False, f"Safety scan failed: {e}"
77-
93+
7894
def run_trivy(self) -> Tuple[bool, str]:
7995
"""Run Trivy container vulnerability scan."""
8096
print("Running Trivy container security scan...")
81-
97+
8298
try:
8399
# Build image
84-
subprocess.run([
85-
"docker", "build", "-t", "security-scan:latest", "."
86-
], cwd=self.project_root, check=True)
87-
100+
subprocess.run(
101+
["docker", "build", "-t", "security-scan:latest", "."],
102+
cwd=self.project_root,
103+
check=True,
104+
)
105+
88106
# SARIF output
89-
subprocess.run([
90-
"trivy", "image", "--format", "sarif",
91-
"--output", "trivy-results.sarif",
92-
"security-scan:latest"
93-
], cwd=self.project_root, check=False)
94-
107+
subprocess.run(
108+
[
109+
"trivy",
110+
"image",
111+
"--format",
112+
"sarif",
113+
"--output",
114+
"trivy-results.sarif",
115+
"security-scan:latest",
116+
],
117+
cwd=self.project_root,
118+
check=False,
119+
)
120+
95121
# JSON output
96-
subprocess.run([
97-
"trivy", "image", "--format", "json",
98-
"--output", "trivy-results.json",
99-
"security-scan:latest"
100-
], cwd=self.project_root, check=False)
101-
122+
subprocess.run(
123+
[
124+
"trivy",
125+
"image",
126+
"--format",
127+
"json",
128+
"--output",
129+
"trivy-results.json",
130+
"security-scan:latest",
131+
],
132+
cwd=self.project_root,
133+
check=False,
134+
)
135+
102136
self.sarif_files.append("trivy-results.sarif")
103137
return True, "Trivy scan completed"
104-
138+
105139
except Exception as e:
106140
return False, f"Trivy scan failed: {e}"
107-
141+
108142
def run_hadolint(self) -> Tuple[bool, str]:
109143
"""Run Hadolint Dockerfile security scan."""
110144
print("Running Hadolint Dockerfile scan...")
111-
145+
112146
try:
113-
subprocess.run([
114-
"hadolint", "Dockerfile", "--format", "sarif"
115-
], cwd=self.project_root,
116-
stdout=open(self.project_root / "hadolint-results.sarif", "w"),
117-
check=False)
118-
147+
subprocess.run(
148+
["hadolint", "Dockerfile", "--format", "sarif"],
149+
cwd=self.project_root,
150+
stdout=open(self.project_root / "hadolint-results.sarif", "w"),
151+
check=False,
152+
)
153+
119154
self.sarif_files.append("hadolint-results.sarif")
120155
return True, "Hadolint scan completed"
121-
156+
122157
except Exception as e:
123158
return False, f"Hadolint scan failed: {e}"
124-
159+
125160
def generate_sbom(self) -> Tuple[bool, str]:
126161
"""Generate Software Bill of Materials."""
127162
print("Generating SBOM files...")
128-
163+
129164
try:
130165
# Python dependencies SBOM with pip-audit (only CycloneDX format is supported)
131-
subprocess.run([
132-
"python", "-m", "pip_audit", "--format=cyclonedx-json",
133-
"--output=python-sbom-cyclonedx.json"
134-
], cwd=self.project_root, check=False)
135-
166+
subprocess.run(
167+
[
168+
"python",
169+
"-m",
170+
"pip_audit",
171+
"--format=cyclonedx-json",
172+
"--output=python-sbom-cyclonedx.json",
173+
],
174+
cwd=self.project_root,
175+
check=False,
176+
)
177+
136178
# Check if Syft is available
137179
if subprocess.run(["which", "syft"], capture_output=True).returncode == 0:
138180
# Project SBOM with Syft
139-
subprocess.run([
140-
"syft", ".", "-o", "spdx-json=project-sbom-spdx.json"
141-
], cwd=self.project_root, check=False)
142-
143-
subprocess.run([
144-
"syft", ".", "-o", "cyclonedx-json=project-sbom-cyclonedx.json"
145-
], cwd=self.project_root, check=False)
181+
subprocess.run(
182+
["syft", ".", "-o", "spdx-json=project-sbom-spdx.json"],
183+
cwd=self.project_root,
184+
check=False,
185+
)
186+
187+
subprocess.run(
188+
["syft", ".", "-o", "cyclonedx-json=project-sbom-cyclonedx.json"],
189+
cwd=self.project_root,
190+
check=False,
191+
)
146192
else:
147193
print("Syft not available - skipping project SBOM generation")
148-
194+
149195
return True, "SBOM generation completed"
150-
196+
151197
except Exception as e:
152198
return False, f"SBOM generation failed: {e}"
153-
199+
154200
def generate_report(self) -> str:
155201
"""Generate comprehensive security report."""
156202
print("Generating security report...")
157-
203+
158204
report = {
159205
"scan_timestamp": subprocess.check_output(["date", "-u"]).decode().strip(),
160206
"project": "Open Host Factory Plugin",
@@ -166,14 +212,14 @@ def generate_report(self) -> str:
166212
"Address high and critical severity vulnerabilities first",
167213
"Update dependencies with known vulnerabilities",
168214
"Review container base image for security updates",
169-
"Implement security controls for identified issues"
170-
]
215+
"Implement security controls for identified issues",
216+
],
171217
}
172-
218+
173219
# Write JSON report
174220
with open(self.project_root / "security-report.json", "w") as f:
175221
json.dump(report, f, indent=2)
176-
222+
177223
# Write markdown summary
178224
md_report = f"""# Security Scan Report
179225
@@ -183,19 +229,19 @@ def generate_report(self) -> str:
183229
## Scans Performed
184230
185231
"""
186-
232+
187233
for scan, (success, message) in self.results.items():
188234
status = "PASS" if success else "FAIL"
189235
md_report += f"- **{status}**: {scan} - {message}\n"
190-
236+
191237
md_report += f"""
192238
## Generated Files
193239
194240
### SARIF Files (for GitHub Security tab)
195241
"""
196242
for sarif_file in self.sarif_files:
197243
md_report += f"- `{sarif_file}`\n"
198-
244+
199245
md_report += """
200246
### Report Files
201247
- `security-report.json` - Detailed JSON report
@@ -221,59 +267,59 @@ def generate_report(self) -> str:
221267
- **pip-audit**: Python package vulnerability scanner
222268
- **Syft**: SBOM generator
223269
"""
224-
270+
225271
with open(self.project_root / "security-report.md", "w") as f:
226272
f.write(md_report)
227-
273+
228274
return "security-report.md"
229-
275+
230276
def run_all_scans(self, include_container: bool = True) -> Dict[str, Tuple[bool, str]]:
231277
"""Run all security scans."""
232278
print("Starting comprehensive security scan...")
233-
279+
234280
# Core security scans
235281
self.results["Bandit"] = self.run_bandit()
236282
self.results["Safety"] = self.run_safety()
237283
self.results["SBOM Generation"] = self.generate_sbom()
238-
284+
239285
# Container scans (optional)
240286
if include_container:
241287
self.results["Trivy"] = self.run_trivy()
242288
self.results["Hadolint"] = self.run_hadolint()
243-
289+
244290
# Generate report
245291
report_file = self.generate_report()
246292
print(f"Security report generated: {report_file}")
247-
293+
248294
return self.results
249295

250296

251297
def main():
252298
"""Main entry point."""
253299
parser = argparse.ArgumentParser(description="Comprehensive security scanner")
254-
parser.add_argument("--no-container", action="store_true",
255-
help="Skip container security scans")
256-
parser.add_argument("--project-root", type=Path, default=Path.cwd(),
257-
help="Project root directory")
258-
300+
parser.add_argument("--no-container", action="store_true", help="Skip container security scans")
301+
parser.add_argument(
302+
"--project-root", type=Path, default=Path.cwd(), help="Project root directory"
303+
)
304+
259305
args = parser.parse_args()
260-
306+
261307
scanner = SecurityScanner(args.project_root)
262308
results = scanner.run_all_scans(include_container=not args.no_container)
263-
309+
264310
# Print summary
265-
print("\n" + "="*60)
311+
print("\n" + "=" * 60)
266312
print("SECURITY SCAN SUMMARY")
267-
print("="*60)
268-
313+
print("=" * 60)
314+
269315
all_passed = True
270316
for scan, (success, message) in results.items():
271317
status = "PASS" if success else "FAIL"
272318
print(f"{status}: {scan} - {message}")
273319
if not success:
274320
all_passed = False
275-
276-
print("="*60)
321+
322+
print("=" * 60)
277323
if all_passed:
278324
print("All security scans completed successfully")
279325
sys.exit(0)

0 commit comments

Comments
 (0)