Skip to content

examples #137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 8, 2025
Merged

examples #137

merged 3 commits into from
Mar 8, 2025

Conversation

cdot65
Copy link
Owner

@cdot65 cdot65 commented Mar 8, 2025

User description

Checklist for This Pull Request

🚨Please adhere to the guidelines for contributing to this repository.

  • Ensure you are submitting your pull request to a branch dedicated to a specific topic/feature/bugfix. Avoid using the master branch for pull requests.
  • Target your pull request to the main development branch in this repository.
  • Ensure your commit messages follow the project's preferred format.
  • Check that your code additions do not fail any linting checks or unit tests.

Pull Request Description

Add service connection example.

What does this pull request accomplish?

  • Documentation update

Are there any breaking changes included?

  • Yes
  • No

PR Type

Enhancement, Documentation


Description

  • Add comprehensive service connection examples

  • Implement CRUD operations for connections

  • Include detailed error handling and logging

  • Generate CSV report for created connections


Changes walkthrough 📝

Relevant files
Enhancement
service_connections.py
Add comprehensive service connection examples                       

examples/scm/config/deployments/service_connections.py

  • Implement various service connection types
  • Add CRUD operations for connections
  • Include error handling and colorized logging
  • Generate CSV report for created connections
  • +1263/-0
    Documentation
    service_connections.md
    Update service connections documentation                                 

    docs/sdk/config/deployment/service_connections.md

  • Update core methods table
  • Refine service connection model attributes
  • +25/-25 
    service_connections_README.md
    Add README for service connections example                             

    examples/scm/config/deployments/service_connections_README.md

  • Add new README for service connections example
  • Include usage instructions and troubleshooting
  • +157/-0 

    Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • cdot65 added 2 commits March 8, 2025 08:24
    Introduced Service Connection management, including CRUD operations, filtering, validation, and pagination. Enhanced API parameter validation and added detailed usage examples in the documentation. Updated version to 0.3.18.
    Introduced Service Connection management, including CRUD operations, filtering, validation, and pagination. Enhanced API parameter validation and added detailed usage examples in the documentation. Updated version to 0.3.18.
    Copy link

    github-actions bot commented Mar 8, 2025

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
    🧪 No relevant tests
    🔒 Security concerns

    Sensitive information exposure:
    The script loads sensitive information like client_id, client_secret, and tsg_id from environment variables or a .env file. While this is a common practice, it's important to ensure that these environment variables are properly secured in production environments and that the .env file is not accidentally committed to version control.

    ⚡ Recommended focus areas for review

    Error Handling

    The script uses broad exception handling in several places. This could potentially mask specific errors and make debugging more difficult. Consider implementing more granular exception handling for different types of errors.

    def main():
        """
        Execute the comprehensive set of service connection examples for Strata Cloud Manager.
    
        This is the main entry point for the script that orchestrates the following workflow:
        1. Parse command-line arguments to customize execution
        2. Initialize the SCM client with credentials from environment variables or .env file
        3. Create various types of service connections (basic, BGP, QoS, advanced)
        4. Update an existing service connection to demonstrate modification capabilities
        5. List and filter service connections to show search functionality
        6. Fetch a specific service connection by name
        7. Generate a detailed CSV report of all created service connections
        8. Clean up created objects (unless skip_cleanup is enabled)
        9. Display execution statistics and summary information
    
        Command-line Arguments:
            --skip-cleanup: Preserve created objects (don't delete them)
            --basic: Create only basic service connection examples
            --bgp: Create only BGP service connection examples
            --qos: Create only QoS service connection examples
            --advanced: Create only advanced service connection examples
            --all: Create all service connection types (default behavior)
            --ipsec-tunnel: Name of existing IPsec tunnel to use (REQUIRED for all connections)
            --secondary-tunnel: Name of existing secondary IPsec tunnel (optional, for advanced connections)
            --no-report: Skip CSV report generation
            --max-limit: Maximum number of objects to return in a single API request (1-1000)
    
        Environment Variables:
            SCM_CLIENT_ID: Client ID for SCM authentication (required)
            SCM_CLIENT_SECRET: Client secret for SCM authentication (required)
            SCM_TSG_ID: Tenant Service Group ID for SCM authentication (required)
            SCM_LOG_LEVEL: Logging level, defaults to DEBUG (optional)
            SKIP_CLEANUP: Alternative way to preserve created objects (optional)
    
        Returns:
            None
        """
        # Parse command-line arguments
        args = parse_arguments()
    
        # Track execution time for reporting
        start_time = __import__("time").time()
        connection_count = 0
    
        # Determine whether to skip cleanup
        # Command-line argument takes precedence over environment variable
        skip_cleanup = args.skip_cleanup or os.environ.get("SKIP_CLEANUP", "").lower() == "true"
    
        # Determine which connection types to create
        # If no specific types are specified, create all (default behavior)
        create_all = args.all or not (args.basic or args.bgp or args.qos or args.advanced)
    
        # Keep track of created connections for cleanup
        created_connections = []
        created_connection_ids = []
    
        try:
            # Initialize client
            client = initialize_client()
    
            # Initialize ServiceConnection object
            log_section("SERVICE CONNECTION CONFIGURATION")
            log_operation_start("Initializing ServiceConnection manager")
            service_connections = ServiceConnection(client, max_limit=args.max_limit)
            log_operation_complete("ServiceConnection manager initialization", f"Max limit: {service_connections.max_limit}")
    
            # Check if we have required IPsec tunnel parameter
            if not args.ipsec_tunnel and (create_all or args.basic or args.bgp or args.qos or args.advanced):
                log_error("Missing required IPsec tunnel parameter")
                log_info("An existing IPsec tunnel name is required to create service connections")
                log_info("Example: python service_connections.py --ipsec-tunnel your-tunnel-name")
                log_info("Run with --help for more information")
                return
    
            # Create basic service connection
            if create_all or args.basic:
                log_section("BASIC SERVICE CONNECTION")
                log_info("Creating basic service connection with minimal configuration")
    
                basic_connection = create_basic_service_connection(
                    service_connections, 
                    ipsec_tunnel=args.ipsec_tunnel
                )
                if basic_connection:
                    created_connections.append(basic_connection)
                    created_connection_ids.append(basic_connection.id)
                    connection_count += 1
    
            # Create BGP service connection
            if create_all or args.bgp:
                log_section("BGP SERVICE CONNECTION")
                log_info("Creating service connection with BGP configuration")
    
                bgp_connection = create_bgp_service_connection(
                    service_connections,
                    ipsec_tunnel=args.ipsec_tunnel
                )
                if bgp_connection:
                    created_connections.append(bgp_connection)
                    created_connection_ids.append(bgp_connection.id)
                    connection_count += 1
    
            # Create QoS service connection
            if create_all or args.qos:
                log_section("QOS SERVICE CONNECTION")
                log_info("Creating service connection with QoS configuration")
    
                qos_connection = create_qos_service_connection(
                    service_connections,
                    ipsec_tunnel=args.ipsec_tunnel
                )
                if qos_connection:
                    created_connections.append(qos_connection)
                    created_connection_ids.append(qos_connection.id)
                    connection_count += 1
    
            # Create advanced service connection
            if create_all or args.advanced:
                log_section("ADVANCED SERVICE CONNECTION")
                log_info("Creating service connection with advanced configuration")
    
                advanced_connection = create_advanced_service_connection(
                    service_connections,
                    ipsec_tunnel=args.ipsec_tunnel,
                    secondary_tunnel=args.secondary_tunnel
                )
                if advanced_connection:
                    created_connections.append(advanced_connection)
                    created_connection_ids.append(advanced_connection.id)
                    connection_count += 1
    
            # Update one of the connections if we created any
            if created_connections:
                log_section("UPDATING SERVICE CONNECTION")
                log_info("Demonstrating how to update an existing service connection")
    
                updated_connection = fetch_and_update_service_connection(
                    service_connections, created_connections[0].id
                )
    
            # List and filter service connections
            all_connections = list_and_filter_service_connections(service_connections)
    
            # Fetch a specific connection by name
            if created_connections:
                log_section("FETCHING SERVICE CONNECTION BY NAME")
                log_info("Demonstrating how to fetch a service connection by name")
    
                # Use the first created connection's name
                fetched_connection = fetch_service_connection_by_name(
                    service_connections, created_connections[0].name
                )
    
            # Calculate intermediate execution statistics for the report
            current_time = __import__("time").time()
            execution_time_so_far = current_time - start_time
    
            # Generate CSV report before cleanup if there are connections to report and report generation is not disabled
            if created_connection_ids and not args.no_report:
                log_section("REPORT GENERATION")
                log_operation_start("Generating service connections CSV report")
    
                report_file = generate_service_connection_report(
                    service_connections, created_connection_ids, execution_time_so_far
                )
    
                if report_file:
                    log_success(f"Generated service connections report: {report_file}")
                    log_info(f"The report contains details of all {len(created_connection_ids)} service connections created")
                else:
                    log_error("Failed to generate service connections report")
            elif args.no_report:
                log_info("Report generation disabled by --no-report flag")
            else:
                log_info("No service connections were created, skipping report generation")
    
            # Clean up the created connections, unless skip_cleanup is true
            if skip_cleanup:
                log_info(f"SKIP_CLEANUP is set to true - preserving {len(created_connection_ids)} service connections")
                log_info("To clean up these connections, run the script again with SKIP_CLEANUP unset or set to false")
            else:
                cleanup_service_connections(service_connections, created_connection_ids)
    
            # Calculate and display final execution statistics
            end_time = __import__("time").time()
            execution_time = end_time - start_time
            minutes, seconds = divmod(execution_time, 60)
    
            log_section("EXECUTION SUMMARY")
            log_success(f"Example script completed successfully")
            log_info(f"Total service connections created: {connection_count}")
            log_info(f"Total execution time: {int(minutes)} minutes {int(seconds)} seconds")
            if connection_count > 0:
                log_info(f"Average time per connection: {execution_time/connection_count:.2f} seconds")
    
        except AuthenticationError as e:
            log_error(f"Authentication failed", e.message)
            log_info(f"Status code: {e.http_status_code}")
            log_info("Please verify your credentials in the .env file")
        except KeyboardInterrupt:
            log_warning("Script execution interrupted by user")
            log_info("Note: Some service connections may not have been cleaned up")
        except Exception as e:
            log_error(f"Unexpected error", str(e))
            # Print the full stack trace for debugging
            import traceback
            log_info(f"Stack trace: {traceback.format_exc()}")
    
    
    if __name__ == "__main__":
        main()
    Security Concern

    The script is using environment variables for sensitive information like client secrets. While this is a common practice, it's important to ensure these are properly secured in production environments.

    # Set up logging with color support and improved formatting
    # Define ANSI color codes for colorized output
    COLORS = {
        "RESET": "\033[0m",
        "BOLD": "\033[1m",
        "RED": "\033[31m",
        "GREEN": "\033[32m",
        "YELLOW": "\033[33m",
        "BLUE": "\033[34m",
        "MAGENTA": "\033[35m",
        "CYAN": "\033[36m",
        "WHITE": "\033[37m",
        "BRIGHT_GREEN": "\033[92m",
        "BRIGHT_YELLOW": "\033[93m",
        "BRIGHT_BLUE": "\033[94m",
        "BRIGHT_MAGENTA": "\033[95m",
        "BRIGHT_CYAN": "\033[96m",
    }
    
    # Configure logging format and level
    log_format = "%(asctime)s %(levelname)-8s %(message)s"
    date_format = "%Y-%m-%d %H:%M:%S"
    logging.basicConfig(level=logging.INFO, format=log_format, datefmt=date_format)
    logger = logging.getLogger("service_connection_example")
    Code Duplication

    There's some repetition in the create_*_service_connection functions. Consider refactoring to reduce duplication and improve maintainability.

    def create_basic_service_connection(sc_manager, ipsec_tunnel=None):
        """
        Create a basic service connection without complex configurations.
    
        This function demonstrates creating a simple service connection with
        minimal configuration options.
    
        Args:
            sc_manager: The ServiceConnection manager instance
            ipsec_tunnel: Name of existing IPsec tunnel to use (required)
    
        Returns:
            ServiceConnectionResponseModel: The created service connection, or None if creation failed
        """
        log_operation_start("Creating basic service connection")
    
        # Check if a valid IPsec tunnel name was provided
        if not ipsec_tunnel:
            log_error("No valid IPsec tunnel name provided")
            log_info("Please provide an existing IPsec tunnel name with --ipsec-tunnel parameter")
            log_info("Example: python service_connections.py --ipsec-tunnel your-tunnel-name")
            return None
    
        # Generate a unique connection name to avoid conflicts
        connection_name = f"basic-sc-{uuid.uuid4().hex[:6]}"
        log_info(f"Connection name: {connection_name}")
    
        # Create the connection configuration
        basic_connection_config = {
            "name": connection_name,
            "ipsec_tunnel": ipsec_tunnel,  # Use the provided tunnel name
            "region": "us-east-1",
            "onboarding_type": "classic",
            "subnets": ["10.1.0.0/24", "192.168.1.0/24"],
            "source_nat": True
        }
    
        log_info("Configuration details:")
        log_info(f"  - IPsec Tunnel: {basic_connection_config['ipsec_tunnel']}")
        log_info(f"  - Region: {basic_connection_config['region']}")
        log_info(f"  - Subnets: {', '.join(basic_connection_config['subnets'])}")
        log_info(f"  - Source NAT: {basic_connection_config['source_nat']}")
    
        try:
            log_info("Sending request to Strata Cloud Manager API...")
            new_connection = sc_manager.create(basic_connection_config)
            log_success(f"Created basic service connection: {new_connection.name}")
            log_info(f"  - Connection ID: {new_connection.id}")
            log_info(f"  - IPsec Tunnel: {new_connection.ipsec_tunnel}")
            log_operation_complete(
                "Basic service connection creation", f"Connection: {new_connection.name}"
            )
            return new_connection
        except NameNotUniqueError as e:
            log_error(f"Connection name conflict", e.message)
            log_info("Try using a different connection name or check existing objects")
        except InvalidObjectError as e:
            log_error(f"Invalid connection data", e.message)
            if e.details:
                log_info(f"Error details: {e.details}")
                log_info("Check your configuration values and try again")
        except Exception as e:
            error_str = str(e)
            if "is not a valid reference" in error_str and "ipsec-tunnel" in error_str:
                log_error(f"Invalid IPsec tunnel reference", "The specified IPsec tunnel does not exist")
                log_info("Please provide an existing IPsec tunnel name with --ipsec-tunnel parameter")
                log_info("Example: python service_connections.py --ipsec-tunnel your-tunnel-name")
            else:
                log_error(f"Unexpected error creating service connection", error_str)
    
        return None
    
    
    def create_bgp_service_connection(sc_manager, ipsec_tunnel=None):
        """
        Create a service connection with BGP configuration.
    
        This function demonstrates creating a service connection with
        BGP peering configuration.
    
        Args:
            sc_manager: The ServiceConnection manager instance
            ipsec_tunnel: Name of existing IPsec tunnel to use (required)
    
        Returns:
            ServiceConnectionResponseModel: The created service connection, or None if creation failed
        """
        log_operation_start("Creating service connection with BGP configuration")
    
        # Check if a valid IPsec tunnel name was provided
        if not ipsec_tunnel:
            log_error("No valid IPsec tunnel name provided")
            log_info("Please provide an existing IPsec tunnel name with --ipsec-tunnel parameter")
            log_info("Example: python service_connections.py --ipsec-tunnel your-tunnel-name")
            return None
    
        # Generate a unique connection name to avoid conflicts
        connection_name = f"bgp-sc-{uuid.uuid4().hex[:6]}"
        log_info(f"Connection name: {connection_name}")
    
        # Create the connection configuration with BGP details
        bgp_connection_config = {
            "name": connection_name,
            "ipsec_tunnel": ipsec_tunnel,  # Use the provided tunnel name
            "region": "us-east-1",
            "onboarding_type": "classic",
            "subnets": ["10.2.0.0/24", "192.168.2.0/24"],
            "source_nat": True,
            "bgp_peer": {
                "local_ip_address": "192.168.2.1",
                "peer_ip_address": "192.168.2.2",
            },
            "protocol": {
                "bgp": {
                    "enable": True,
                    "peer_as": "65000",
                    "originate_default_route": True,
                    "fast_failover": True
                }
            }
        }
    
        log_info("Configuration details:")
        log_info(f"  - IPsec Tunnel: {bgp_connection_config['ipsec_tunnel']}")
        log_info(f"  - Region: {bgp_connection_config['region']}")
        log_info(f"  - Subnets: {', '.join(bgp_connection_config['subnets'])}")
        log_info(f"  - Local BGP IP: {bgp_connection_config['bgp_peer']['local_ip_address']}")
        log_info(f"  - Peer BGP IP: {bgp_connection_config['bgp_peer']['peer_ip_address']}")
        log_info(f"  - Peer AS: {bgp_connection_config['protocol']['bgp']['peer_as']}")
    
        try:
            log_info("Sending request to Strata Cloud Manager API...")
            new_connection = sc_manager.create(bgp_connection_config)
            log_success(f"Created BGP service connection: {new_connection.name}")
            log_info(f"  - Connection ID: {new_connection.id}")
            log_info(f"  - IPsec Tunnel: {new_connection.ipsec_tunnel}")
            log_operation_complete(
                "BGP service connection creation", f"Connection: {new_connection.name}"
            )
            return new_connection
        except NameNotUniqueError as e:
            log_error(f"Connection name conflict", e.message)
            log_info("Try using a different connection name or check existing objects")
        except InvalidObjectError as e:
            log_error(f"Invalid connection data", e.message)
            if e.details:
                log_info(f"Error details: {e.details}")
                log_info("Check your configuration values and try again")
        except Exception as e:
            error_str = str(e)
            if "is not a valid reference" in error_str and "ipsec-tunnel" in error_str:
                log_error(f"Invalid IPsec tunnel reference", "The specified IPsec tunnel does not exist")
                log_info("Please provide an existing IPsec tunnel name with --ipsec-tunnel parameter")
                log_info("Example: python service_connections.py --ipsec-tunnel your-tunnel-name")
            else:
                log_error(f"Unexpected error creating service connection", error_str)
    
        return None
    
    
    def create_qos_service_connection(sc_manager, ipsec_tunnel=None):
        """
        Create a service connection with QoS configuration.
    
        This function demonstrates creating a service connection with
        Quality of Service settings.
    
        Args:
            sc_manager: The ServiceConnection manager instance
            ipsec_tunnel: Name of existing IPsec tunnel to use (required)
    
        Returns:
            ServiceConnectionResponseModel: The created service connection, or None if creation failed
        """
        log_operation_start("Creating service connection with QoS configuration")
    
        # Check if a valid IPsec tunnel name was provided
        if not ipsec_tunnel:
            log_error("No valid IPsec tunnel name provided")
            log_info("Please provide an existing IPsec tunnel name with --ipsec-tunnel parameter")
            log_info("Example: python service_connections.py --ipsec-tunnel your-tunnel-name")
            return None
    
        # Generate a unique connection name to avoid conflicts
        connection_name = f"qos-sc-{uuid.uuid4().hex[:6]}"
        log_info(f"Connection name: {connection_name}")
    
        # Create the connection configuration with QoS settings
        qos_connection_config = {
            "name": connection_name,
            "ipsec_tunnel": ipsec_tunnel,  # Use the provided tunnel name
            "region": "us-west-1",
            "onboarding_type": "classic",
            "subnets": ["10.3.0.0/24", "192.168.3.0/24"],
            "source_nat": True,
            "qos": {
                "enable": True,
                "qos_profile": "default-qos-profile"
            }
        }
    
        log_info("Configuration details:")
        log_info(f"  - IPsec Tunnel: {qos_connection_config['ipsec_tunnel']}")
        log_info(f"  - Region: {qos_connection_config['region']}")
        log_info(f"  - Subnets: {', '.join(qos_connection_config['subnets'])}")
        log_info(f"  - QoS Enabled: {qos_connection_config['qos']['enable']}")
        log_info(f"  - QoS Profile: {qos_connection_config['qos']['qos_profile']}")
    
        try:
            log_info("Sending request to Strata Cloud Manager API...")
            new_connection = sc_manager.create(qos_connection_config)
            log_success(f"Created QoS service connection: {new_connection.name}")
            log_info(f"  - Connection ID: {new_connection.id}")
            log_info(f"  - IPsec Tunnel: {new_connection.ipsec_tunnel}")
            log_operation_complete(
                "QoS service connection creation", f"Connection: {new_connection.name}"
            )
            return new_connection
        except NameNotUniqueError as e:
            log_error(f"Connection name conflict", e.message)
            log_info("Try using a different connection name or check existing objects")
        except InvalidObjectError as e:
            log_error(f"Invalid connection data", e.message)
            if e.details:
                log_info(f"Error details: {e.details}")
                log_info("Check your configuration values and try again")
        except Exception as e:
            error_str = str(e)
            if "is not a valid reference" in error_str and "ipsec-tunnel" in error_str:
                log_error(f"Invalid IPsec tunnel reference", "The specified IPsec tunnel does not exist")
                log_info("Please provide an existing IPsec tunnel name with --ipsec-tunnel parameter")
                log_info("Example: python service_connections.py --ipsec-tunnel your-tunnel-name")
            else:
                log_error(f"Unexpected error creating service connection", error_str)
    
        return None
    

    Copy link

    github-actions bot commented Mar 8, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Security
    Enhance security for credentials storage

    Consider adding a note about securely storing sensitive information like client
    secrets, and possibly suggest using environment variables instead of a .env file for
    production use.

    examples/scm/config/deployments/service_connections_README.md [31-35]

     SCM_CLIENT_ID=your_client_id
     SCM_CLIENT_SECRET=your_client_secret
     SCM_TSG_ID=your_tsg_id
     SCM_LOG_LEVEL=DEBUG  # Optional
     SKIP_CLEANUP=false   # Optional, set to true to preserve created objects
     
    +# Note: For production use, consider using environment variables
    +# instead of a .env file to securely store sensitive information.
    +
    Suggestion importance[1-10]: 8

    __

    Why: This suggestion significantly improves the security practices by recommending the use of environment variables for sensitive information in production environments, which is a crucial consideration for handling credentials securely.

    Medium
    General
    Improve boolean conversion from environment variable

    Consider using the strtobool function from the distutils.util module to handle
    various string representations of boolean values more robustly.

    examples/scm/config/deployments/service_connections.py [1099-1101]

    +from distutils.util import strtobool
     # Determine whether to skip cleanup
     # Command-line argument takes precedence over environment variable
    -skip_cleanup = args.skip_cleanup or os.environ.get("SKIP_CLEANUP", "").lower() == "true"
    +skip_cleanup = args.skip_cleanup or bool(strtobool(os.environ.get("SKIP_CLEANUP", "false")))
    Suggestion importance[1-10]: 7

    __

    Why: The suggestion improves the robustness of boolean conversion from environment variables by using the strtobool function, which can handle various string representations of boolean values more effectively than a simple string comparison.

    Medium
    Add network access prerequisite

    Consider adding a note about potential network requirements or firewall
    configurations that might be necessary for the script to communicate with the Strata
    Cloud Manager API.

    examples/scm/config/deployments/service_connections_README.md [16-24]

     ## Prerequisites
     
     - Python 3.8+
     - PAN-SCM-SDK installed
     - API credentials for Strata Cloud Manager
     - Appropriate permissions to manage service connections
     - **IMPORTANT**: Existing IPsec tunnels must be available in your SCM environment
       - You must provide the names of these tunnels when running the script
       - The tunnels must already be configured and available in SCM
    +- Ensure network access to Strata Cloud Manager API (check firewall rules if needed)
    Suggestion importance[1-10]: 7

    __

    Why: This suggestion adds valuable information about network access requirements, which is crucial for the script to function properly. It helps users preemptively address potential connectivity issues.

    Medium
    Improve error handling for missing parameter

    Consider raising a custom exception instead of using a return statement to exit the
    main function. This allows for better error handling and potential recovery in
    larger applications.

    examples/scm/config/deployments/service_connections.py [1120-1126]

    +class MissingIPsecTunnelError(Exception):
    +    pass
    +
     # Check if we have required IPsec tunnel parameter
     if not args.ipsec_tunnel and (create_all or args.basic or args.bgp or args.qos or args.advanced):
         log_error("Missing required IPsec tunnel parameter")
         log_info("An existing IPsec tunnel name is required to create service connections")
         log_info("Example: python service_connections.py --ipsec-tunnel your-tunnel-name")
         log_info("Run with --help for more information")
    -    return
    +    raise MissingIPsecTunnelError("IPsec tunnel parameter is required")
    Suggestion importance[1-10]: 6

    __

    Why: The suggestion enhances error handling by introducing a custom exception instead of using a return statement. This allows for more structured error handling and potential recovery in larger applications, improving the overall robustness of the code.

    Low

    Removed redundant items and streamlined the checklist by deleting the commit message format requirement and additional reviewer notes section. These changes aim to make the template more concise and focused on key contribution requirements.
    Copy link

    codecov bot commented Mar 8, 2025

    Codecov Report

    All modified and coverable lines are covered by tests ✅

    ✅ All tests successful. No failed tests found.

    @cdot65 cdot65 merged commit 3140900 into main Mar 8, 2025
    2 checks passed
    @cdot65 cdot65 deleted the examples branch March 8, 2025 14:29
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    1 participant