ocean icon indicating copy to clipboard operation
ocean copied to clipboard

feat: adding support for ingesting opsgenie notification and alert po…

Open em0ney opened this issue 9 months ago • 3 comments

User description

…licies

Description

What -

Why -

How -

Type of change

Please leave one option from the following and delete the rest:

  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [ ] New feature (non-breaking change which adds functionality)
  • [ ] New Integration (non-breaking change which adds a new integration)
  • [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • [ ] Non-breaking change (fix of existing functionality that will not change current behavior)
  • [ ] Documentation (added/updated documentation)

All tests should be run against the port production environment(using a testing org).

Core testing checklist

  • [ ] Integration able to create all default resources from scratch
  • [ ] Resync finishes successfully
  • [ ] Resync able to create entities
  • [ ] Resync able to update entities
  • [ ] Resync able to detect and delete entities
  • [ ] Scheduled resync able to abort existing resync and start a new one
  • [ ] Tested with at least 2 integrations from scratch
  • [ ] Tested with Kafka and Polling event listeners
  • [ ] Tested deletion of entities that don't pass the selector

Integration testing checklist

  • [ ] Integration able to create all default resources from scratch
  • [ ] Resync able to create entities
  • [ ] Resync able to update entities
  • [ ] Resync able to detect and delete entities
  • [ ] Resync finishes successfully
  • [ ] If new resource kind is added or updated in the integration, add example raw data, mapping and expected result to the examples folder in the integration directory.
  • [ ] If resource kind is updated, run the integration with the example data and check if the expected result is achieved
  • [ ] If new resource kind is added or updated, validate that live-events for that resource are working as expected
  • [ ] Docs PR link here

Preflight checklist

  • [ ] Handled rate limiting
  • [ ] Handled pagination
  • [ ] Implemented the code in async
  • [ ] Support Multi account

Screenshots

Include screenshots from your environment showing how the resources of the integration will look.

API Documentation

Provide links to the API documentation used for this integration.


PR Type

Enhancement


Description

  • Added support for ingesting OpsGenie alert and notification policies.

  • Introduced new resource kinds ALERT_POLICY and NOTIFICATION_POLICY.

  • Updated API handling for OpsGenie resources with suffix adjustments.

  • Enhanced blueprint and configuration files for new policy types.


Changes walkthrough 📝

Relevant files
Enhancement
client.py
Adjusted API client for resource suffix handling                 

integrations/opsgenie/client.py

  • Added _should_add_suffix method to handle resource suffix logic.
  • Updated get_paginated_resources to use suffix logic for URLs.
  • +11/-1   
    main.py
    Added resync handlers for alert and notification policies

    integrations/opsgenie/main.py

  • Added on_alert_policy_resync for alert policy resync handling.
  • Added on_notification_policy_resync for notification policy resync
    handling.
  • +45/-0   
    utils.py
    Defined new resource kinds for policies                                   

    integrations/opsgenie/utils.py

  • Added ALERT_POLICY and NOTIFICATION_POLICY to ObjectKind.
  • Updated API version mapping for new resource kinds.
  • +6/-0     
    blueprints.json
    Added blueprint for OpsGenie policies                                       

    integrations/opsgenie/.port/resources/blueprints.json

  • Added a new blueprint for OpsGenie policies.
  • Defined schema and relations for policy blueprint.
  • +37/-0   
    port-app-config.yaml
    Updated app configuration for new policy types                     

    integrations/opsgenie/.port/resources/port-app-config.yaml

  • Added mappings for policies/alert and policies/notification.
  • Configured relations and properties for new policy types.
  • +28/-0   
    spec.yaml
    Updated spec file with new policy kinds                                   

    integrations/opsgenie/.port/spec.yaml

  • Added policies/alert and policies/notification to resource features.
  • +2/-0     

    Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • em0ney avatar Mar 10 '25 02:03 em0ney

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Duplicate Code

    The implementations of on_alert_policy_resync and on_notification_policy_resync are nearly identical. Consider refactoring to a common helper function that accepts the policy type as a parameter to reduce code duplication.

    @ocean.on_resync(ObjectKind.ALERT_POLICY)
    async def on_alert_policy_resync(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE:
        opsgenie_client = init_client()
        all_policies = []
        async for teams_batch in opsgenie_client.get_paginated_resources(
            resource_type=ObjectKind.TEAM
        ):
            logger.info(f"Received batch with {len(teams_batch)} teams")
            for team in teams_batch:
                team_id = team["id"]
                async for policy_batch in opsgenie_client.get_paginated_resources(
                    resource_type=ObjectKind.ALERT_POLICY,
                    query_params={"teamId": team_id}
                ):
                    all_policies.extend(policy_batch)
    
    
        logger.info(
            f"Received {len(all_policies)} alert policies"
        )
        yield all_policies
    
    @ocean.on_resync(ObjectKind.NOTIFICATION_POLICY)
    async def on_notification_policy_resync(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE:
        opsgenie_client = init_client()
    
        all_policies = []
        async for teams_batch in opsgenie_client.get_paginated_resources(
            resource_type=ObjectKind.TEAM
        ):
            logger.info(f"Received batch with {len(teams_batch)} teams")
            for team in teams_batch:
                team_id = team["id"]
                async for policy_batch in opsgenie_client.get_paginated_resources(
                    resource_type=ObjectKind.NOTIFICATION_POLICY,
                    query_params={"teamId": team_id}
                ):
                    all_policies.extend(policy_batch)
    
        logger.info(
            f"Received {len(all_policies)} notification policies"
        )
        yield all_policies
    
    Missing Documentation

    The newly added _should_add_suffix method lacks docstring documentation explaining its purpose and parameters, which would be helpful for future maintenance.

    async def _should_add_suffix(self, resource_type: ObjectKind) -> bool:
        # Some OpsGenie endpoints don't use plural form
        # Default to True for backward compatibility
        if resource_type == ObjectKind.ALERT_POLICY:
            return False
        if resource_type == ObjectKind.NOTIFICATION_POLICY:
            return False
        return True
    

    qodo-code-review[bot] avatar Mar 10 '25 02:03 qodo-code-review[bot]

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Add error handling

    The function doesn't handle potential errors when fetching policies. Consider
    adding error handling to prevent the entire resync process from failing if a
    single team's policies can't be retrieved.

    integrations/opsgenie/main.py [167-181]

     @ocean.on_resync(ObjectKind.ALERT_POLICY)
     async def on_alert_policy_resync(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE:
         opsgenie_client = init_client()
         all_policies = []
         async for teams_batch in opsgenie_client.get_paginated_resources(
             resource_type=ObjectKind.TEAM
         ):
             logger.info(f"Received batch with {len(teams_batch)} teams")
             for team in teams_batch:
                 team_id = team["id"]
    -            async for policy_batch in opsgenie_client.get_paginated_resources(
    -                resource_type=ObjectKind.ALERT_POLICY,
    -                query_params={"teamId": team_id}
    -            ):
    -                all_policies.extend(policy_batch)
    +            try:
    +                async for policy_batch in opsgenie_client.get_paginated_resources(
    +                    resource_type=ObjectKind.ALERT_POLICY,
    +                    query_params={"teamId": team_id}
    +                ):
    +                    all_policies.extend(policy_batch)
    +            except Exception as e:
    +                logger.error(f"Failed to fetch alert policies for team {team_id}: {e}")
    
    • [ ] Apply this suggestion
    Suggestion importance[1-10]: 7

    __

    Why: The suggestion adds important error handling to prevent the entire resync process from failing if fetching policies for a single team fails. This is a significant improvement for robustness and reliability, as it allows the process to continue with other teams even if one fails.

    Medium
    General
    Fix inconsistent whitespace

    The function has unnecessary whitespace between the code and the logging
    statement, which breaks the indentation flow and could cause confusion. Remove
    the extra blank lines to maintain consistent code structure.

    integrations/opsgenie/main.py [167-187]

     @ocean.on_resync(ObjectKind.ALERT_POLICY)
     async def on_alert_policy_resync(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE:
         opsgenie_client = init_client()
         all_policies = []
         async for teams_batch in opsgenie_client.get_paginated_resources(
             resource_type=ObjectKind.TEAM
         ):
             logger.info(f"Received batch with {len(teams_batch)} teams")
             for team in teams_batch:
                 team_id = team["id"]
                 async for policy_batch in opsgenie_client.get_paginated_resources(
                     resource_type=ObjectKind.ALERT_POLICY,
                     query_params={"teamId": team_id}
                 ):
                     all_policies.extend(policy_batch)
     
    -
         logger.info(
             f"Received {len(all_policies)} alert policies"
         )
         yield all_policies
    
    • [ ] Apply this suggestion
    Suggestion importance[1-10]: 3

    __

    Why: The suggestion correctly identifies and removes unnecessary blank lines between the policy collection and logging statement, improving code readability and maintaining consistent style. While valid, this is a minor style improvement with minimal functional impact.

    Low
    Maintain consistent spacing

    The function has inconsistent whitespace compared to the alert policy function.
    For code consistency, remove the extra blank line after initializing the client
    to match the style of the alert policy function.

    integrations/opsgenie/main.py [189-204]

     @ocean.on_resync(ObjectKind.NOTIFICATION_POLICY)
     async def on_notification_policy_resync(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE:
         opsgenie_client = init_client()
    -
         all_policies = []
         async for teams_batch in opsgenie_client.get_paginated_resources(
             resource_type=ObjectKind.TEAM
         ):
             logger.info(f"Received batch with {len(teams_batch)} teams")
             for team in teams_batch:
                 team_id = team["id"]
                 async for policy_batch in opsgenie_client.get_paginated_resources(
                     resource_type=ObjectKind.NOTIFICATION_POLICY,
                     query_params={"teamId": team_id}
                 ):
                     all_policies.extend(policy_batch)
    
    • [ ] Apply this suggestion
    Suggestion importance[1-10]: 3

    __

    Why: The suggestion correctly identifies and removes an extra blank line after client initialization to maintain consistent style with the alert policy function. This is a valid but minor style improvement that enhances code consistency.

    Low
    • [ ] More

    qodo-code-review[bot] avatar Mar 10 '25 02:03 qodo-code-review[bot]

    This pull request is automatically being deployed by Amplify Hosting (learn more).

    Access this pull request here: https://pr-1473.d1ftd8v2gowp8w.amplifyapp.com