Refactor: Simplify connectivity analysis logic by breaking down into smaller helper functions for improved readability and maintainability
All checks were successful
CI / lint-and-test (pull_request) Successful in 1m0s
CI / ansible-validation (pull_request) Successful in 2m12s
CI / secret-scanning (pull_request) Successful in 54s
CI / dependency-scan (pull_request) Successful in 58s
CI / sast-scan (pull_request) Successful in 2m58s
CI / license-check (pull_request) Successful in 59s
CI / vault-check (pull_request) Successful in 2m50s
CI / playbook-test (pull_request) Successful in 2m42s
CI / container-scan (pull_request) Successful in 1m44s
CI / sonar-analysis (pull_request) Successful in 2m12s
CI / workflow-summary (pull_request) Successful in 51s

This commit is contained in:
ilia 2025-12-15 14:55:10 -05:00
parent dc94395bbc
commit d6655babd9
2 changed files with 88 additions and 36 deletions

View File

@ -395,7 +395,7 @@ jobs:
-Dsonar.projectKey=ansible \ -Dsonar.projectKey=ansible \
-Dsonar.sources=. \ -Dsonar.sources=. \
-Dsonar.host.url=${SONAR_HOST_URL} \ -Dsonar.host.url=${SONAR_HOST_URL} \
-Dsonar.login=${SONAR_TOKEN} \ -Dsonar.token=${SONAR_TOKEN} \
-X; then -X; then
echo "" echo ""
echo "❌ SonarScanner analysis failed!" echo "❌ SonarScanner analysis failed!"

View File

@ -141,39 +141,91 @@ class ConnectivityTester:
return result return result
def _analyze_connectivity(self, result: Dict) -> Tuple[str, str]: def _analyze_connectivity(self, result: Dict) -> Tuple[str, str]:
"""Analyze connectivity results and provide recommendations.""" """Analyze connectivity results and provide recommendations.
hostname = result['hostname']
primary_ip = result['primary_ip'] Split into smaller helpers to keep this function's complexity low
fallback_ip = result['fallback_ip'] while preserving the original decision logic.
"""
# Primary IP works perfectly for handler in (
if result['primary_ping'] and result['primary_ssh']: self._handle_primary_success,
return 'success', f"{hostname} is fully accessible via primary IP {primary_ip}" self._handle_primary_ping_only,
self._handle_fallback_path,
# Primary ping works but SSH fails self._handle_no_fallback,
if result['primary_ping'] and not result['primary_ssh']: ):
error = result['primary_ssh_error'] outcome = handler(result)
if 'Permission denied' in error: if outcome is not None:
return 'ssh_key', f"{hostname}: SSH key issue on {primary_ip} - run: make copy-ssh-key HOST={hostname}" return outcome
elif 'Connection refused' in error:
return 'ssh_service', f"{hostname}: SSH service not running on {primary_ip}" hostname = result["hostname"]
else: return "unknown", f"? {hostname}: Unknown connectivity state"
return 'ssh_error', f"{hostname}: SSH error on {primary_ip} - {error}"
def _handle_primary_success(self, result: Dict) -> Optional[Tuple[str, str]]:
# Primary IP fails, test fallback """Handle case where primary IP works perfectly."""
if not result['primary_ping'] and fallback_ip: if result.get("primary_ping") and result.get("primary_ssh"):
if result['fallback_ping'] and result['fallback_ssh']: hostname = result["hostname"]
return 'use_fallback', f"{hostname}: Switch to fallback IP {fallback_ip} (primary {primary_ip} failed)" primary_ip = result["primary_ip"]
elif result['fallback_ping'] and not result['fallback_ssh']: return "success", f"{hostname} is fully accessible via primary IP {primary_ip}"
return 'fallback_ssh', f"{hostname}: Fallback IP {fallback_ip} reachable but SSH failed" return None
else:
return 'both_failed', f"{hostname}: Both primary {primary_ip} and fallback {fallback_ip} failed" def _handle_primary_ping_only(self, result: Dict) -> Optional[Tuple[str, str]]:
"""Handle cases where primary ping works but SSH fails."""
# No fallback IP and primary failed if result.get("primary_ping") and not result.get("primary_ssh"):
if not result['primary_ping'] and not fallback_ip: hostname = result["hostname"]
return 'no_fallback', f"{hostname}: Primary IP {primary_ip} failed, no fallback available" primary_ip = result["primary_ip"]
error = result.get("primary_ssh_error", "")
return 'unknown', f"? {hostname}: Unknown connectivity state"
if "Permission denied" in error:
return (
"ssh_key",
f"{hostname}: SSH key issue on {primary_ip} - run: make copy-ssh-key HOST={hostname}",
)
if "Connection refused" in error:
return "ssh_service", f"{hostname}: SSH service not running on {primary_ip}"
return "ssh_error", f"{hostname}: SSH error on {primary_ip} - {error}"
return None
def _handle_fallback_path(self, result: Dict) -> Optional[Tuple[str, str]]:
"""Handle cases where primary fails and a fallback IP is defined."""
if result.get("primary_ping"):
return None
fallback_ip = result.get("fallback_ip")
if not fallback_ip:
return None
hostname = result["hostname"]
primary_ip = result["primary_ip"]
if result.get("fallback_ping") and result.get("fallback_ssh"):
return (
"use_fallback",
f"{hostname}: Switch to fallback IP {fallback_ip} (primary {primary_ip} failed)",
)
if result.get("fallback_ping") and not result.get("fallback_ssh"):
return (
"fallback_ssh",
f"{hostname}: Fallback IP {fallback_ip} reachable but SSH failed",
)
return (
"both_failed",
f"{hostname}: Both primary {primary_ip} and fallback {fallback_ip} failed",
)
def _handle_no_fallback(self, result: Dict) -> Optional[Tuple[str, str]]:
"""Handle cases where primary failed and no fallback IP is available."""
if result.get("primary_ping"):
return None
fallback_ip = result.get("fallback_ip")
if fallback_ip:
return None
hostname = result["hostname"]
primary_ip = result["primary_ip"]
return "no_fallback", f"{hostname}: Primary IP {primary_ip} failed, no fallback available"
def run_tests(self) -> List[Dict]: def run_tests(self) -> List[Dict]:
"""Run connectivity tests for all hosts.""" """Run connectivity tests for all hosts."""
@ -264,8 +316,8 @@ class ConnectivityTester:
# Auto-fallback suggestion # Auto-fallback suggestion
if fallback_needed: if fallback_needed:
print(f"\n🤖 Or run auto-fallback to fix automatically:") print("\n🤖 Or run auto-fallback to fix automatically:")
print(f" make auto-fallback") print(" make auto-fallback")
def export_json(self, results: List[Dict], output_file: str): def export_json(self, results: List[Dict], output_file: str):
"""Export results to JSON file.""" """Export results to JSON file."""