Fix StrongSwan CRL reread handler race condition

The ipsec rereadcrls command was failing with exit code 7 when the IPsec
daemon wasn't fully started yet. This is a timing issue that can occur
during initial setup.

Added retry logic to:
1. Wait up to 10 seconds for the IPsec daemon to be ready
2. Check daemon status before attempting CRL operations
3. Gracefully handle the case where daemon isn't ready

Also fixed Python linting issues (whitespace) in test files caught by ruff.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Dan Guido 2025-08-06 21:22:11 -07:00
parent 808fd85956
commit 4be204f1d5
3 changed files with 108 additions and 101 deletions

View file

@ -9,4 +9,14 @@
service: name=apparmor state=restarted
- name: rereadcrls
shell: ipsec rereadcrls; ipsec purgecrls
shell: |
# Wait for ipsec daemon to be ready (up to 10 seconds)
for i in $(seq 1 10); do
if ipsec statusall >/dev/null 2>&1; then
ipsec rereadcrls && ipsec purgecrls
exit 0
fi
sleep 1
done
# If daemon still not ready, try anyway but don't fail the playbook
ipsec rereadcrls; ipsec purgecrls || true

View file

@ -6,7 +6,6 @@ Tests all strongswan role templates with various configurations.
import os
import sys
import uuid
from pathlib import Path
from jinja2 import Environment, FileSystemLoader, StrictUndefined
@ -189,7 +188,7 @@ def test_openssl_template_constraints():
return True
try:
with open(openssl_path, 'r') as f:
with open(openssl_path) as f:
content = yaml.safe_load(f)
# Find the CA CSR task

View file

@ -7,16 +7,14 @@ This script checks for:
3. Common anti-patterns
"""
import os
import re
import sys
from pathlib import Path
from typing import List, Tuple
from jinja2 import Environment, FileSystemLoader, StrictUndefined, TemplateSyntaxError, meta
def find_jinja2_templates(root_dir: str = '.') -> List[Path]:
def find_jinja2_templates(root_dir: str = '.') -> list[Path]:
"""Find all Jinja2 template files in the project."""
templates = []
patterns = ['**/*.j2', '**/*.jinja2', '**/*.yml.j2', '**/*.conf.j2']
@ -33,7 +31,7 @@ def find_jinja2_templates(root_dir: str = '.') -> List[Path]:
return sorted(templates)
def check_inline_comments_in_expressions(template_content: str, template_path: Path) -> List[str]:
def check_inline_comments_in_expressions(template_content: str, template_path: Path) -> list[str]:
"""
Check for inline comments (#) within Jinja2 expressions.
This is the error we just fixed in openssl.yml.
@ -68,7 +66,7 @@ def check_inline_comments_in_expressions(template_content: str, template_path: P
return errors
def check_undefined_variables(template_path: Path) -> List[str]:
def check_undefined_variables(template_path: Path) -> list[str]:
"""
Parse template and extract all undefined variables.
This helps identify what variables need to be provided.
@ -76,7 +74,7 @@ def check_undefined_variables(template_path: Path) -> List[str]:
errors = []
try:
with open(template_path, 'r') as f:
with open(template_path) as f:
template_content = f.read()
env = Environment(undefined=StrictUndefined)
@ -101,14 +99,14 @@ def check_undefined_variables(template_path: Path) -> List[str]:
f"{template_path}: Uses undefined variables: {', '.join(sorted(unknown_vars))}"
)
except Exception as e:
except Exception:
# Don't report parse errors here, they're handled elsewhere
pass
return errors
def validate_template_syntax(template_path: Path) -> Tuple[bool, List[str]]:
def validate_template_syntax(template_path: Path) -> tuple[bool, list[str]]:
"""
Validate a single template for syntax errors.
Returns (is_valid, list_of_errors)
@ -126,7 +124,7 @@ def validate_template_syntax(template_path: Path) -> Tuple[bool, List[str]]:
if template_path.name in ansible_specific_templates:
# Still check for inline comments but skip full parsing
try:
with open(template_path, 'r') as f:
with open(template_path) as f:
template_content = f.read()
errors.extend(check_inline_comments_in_expressions(template_content, template_path))
except Exception:
@ -134,7 +132,7 @@ def validate_template_syntax(template_path: Path) -> Tuple[bool, List[str]]:
return len(errors) == 0, errors
try:
with open(template_path, 'r') as f:
with open(template_path) as f:
template_content = f.read()
# Check for inline comments first (our custom check)
@ -171,12 +169,12 @@ def validate_template_syntax(template_path: Path) -> Tuple[bool, List[str]]:
return len(errors) == 0, errors
def check_common_antipatterns(template_path: Path) -> List[str]:
def check_common_antipatterns(template_path: Path) -> list[str]:
"""Check for common Jinja2 anti-patterns."""
warnings = []
try:
with open(template_path, 'r') as f:
with open(template_path) as f:
content = f.read()
# Check for missing spaces around filters