Skip to content

Add missing integration instance lifecycle management methods #54

@egallis31

Description

@egallis31

Add missing integration instance lifecycle management methods

Description

The JupiterOne Python API client lacks several integration instance lifecycle management methods that exist in the underlying GraphQL API. While some integration methods exist (create_integration_instance, fetch_integration_instances), key lifecycle operations like delete, filtered listing, and name-based lookup are missing, forcing users to implement custom solutions or use direct GraphQL mutations.

Current Behavior

The Python API client currently provides limited integration instance management:

Available methods:

  • create_integration_instance()
  • fetch_integration_instances() ✅ (basic)
  • get_integration_instance_details()
  • update_integration_instance_config_value() ✅ (limited)

Missing methods (require custom implementation):

  • Delete integration instances
  • List integrations with filtering (by resource group, name, etc.)
  • Get integration by name (common use case)
  • Comprehensive update method

Current workaround (from helpers.py):

def get_integration_instance_id(integration_name: str, j1_client: JupiterOneClient) -> Optional[str]:
    """
    Retrieve the integration instance ID by name.
    Custom implementation required because no built-in method exists.
    """
    logger.info(f"Searching for integration instance: {integration_name}")
    
    try:
        response = j1_client.fetch_integration_instances()
        instances = response.get('data', {}).get('integrationInstancesV2', {}).get('instances')
        
        if instances:
            for instance in instances:
                if instance.get('name') == integration_name:
                    instance_id = instance.get('id')
                    logger.info(f"Found integration '{integration_name}' with ID: {instance_id}")
                    return instance_id
        
    except Exception as e:
        logger.debug(f"API method failed: {e}")
    
    logger.warning(f"Integration instance '{integration_name}' not found")
    return None


def delete_integration(integration_id: str) -> None:
    """
    Helper function to delete an integration instance.
    Custom GraphQL implementation required.
    """
    delete_mutation = """
    mutation DeleteIntegrationInstance($id: String!) {
        deleteIntegrationInstance(id: $id) {
            success
            __typename
        }
    }
    """
    
    variables = {"id": integration_id}
    result = make_graphql_request(delete_mutation, variables, "DeleteIntegrationInstance")
    
    assert result['data']['deleteIntegrationInstance']['success'], "Integration deletion failed."

Expected Behavior

The Python API client should provide comprehensive integration instance lifecycle management methods that match the capabilities of the underlying GraphQL API.

Missing Methods

The following methods should be added to the JupiterOneClient class:

1. delete_integration_instance(instance_id)

success = j1_client.delete_integration_instance(instance_id="integration-123")

2. list_integration_instances(definition_id=None, resource_group_id=None, name=None)

# List all integration instances
all_instances = j1_client.list_integration_instances()

# List instances by integration definition
aws_instances = j1_client.list_integration_instances(definition_id="aws-definition-id")

# List instances in specific resource group
rg_instances = j1_client.list_integration_instances(resource_group_id="rg-id")

# Search by name pattern
named_instances = j1_client.list_integration_instances(name="prod-*")

3. get_integration_instance_by_name(instance_name)

instance = j1_client.get_integration_instance_by_name("my-aws-integration")

4. update_integration_instance(instance_id, **kwargs)

# Comprehensive update method (beyond just config values)
updated_instance = j1_client.update_integration_instance(
    instance_id="integration-123",
    name="Updated Integration Name",
    description="Updated description",
    resource_group_id="new-resource-group-id",
    polling_interval="ONE_HOUR"
)

5. enable_integration_instance(instance_id) / disable_integration_instance(instance_id)

j1_client.enable_integration_instance(instance_id="integration-123")
j1_client.disable_integration_instance(instance_id="integration-123")

Code Example

Current state (custom implementation required):

# Users must implement custom logic for common operations

# 1. Delete integration - requires custom GraphQL
delete_mutation = """
mutation DeleteIntegrationInstance($id: String!) {
    deleteIntegrationInstance(id: $id) {
        success
        __typename
    }
}
"""
# Manual GraphQL handling...

# 2. Find integration by name - requires custom parsing
def find_integration_by_name(name):
    response = j1_client.fetch_integration_instances()
    instances = response.get('data', {}).get('integrationInstancesV2', {}).get('instances')
    for instance in instances:
        if instance.get('name') == name:
            return instance
    return None

# 3. Filter integrations - requires custom logic
# No built-in filtering capabilities

Desired API experience:

# What we want to be able to do

# Create integration (already supported in v1.5.0)
integration = j1_client.create_integration_instance(
    instance_name="my-aws-integration",
    instance_description="AWS production account",
    resource_group_id="prod-rg"
)

# List and filter integrations easily
all_integrations = j1_client.list_integration_instances()
aws_integrations = j1_client.list_integration_instances(definition_id="aws-def-id")
prod_integrations = j1_client.list_integration_instances(resource_group_id="prod-rg")

# Find by name (common use case)
my_integration = j1_client.get_integration_instance_by_name("my-aws-integration")

# Update integration properties
j1_client.update_integration_instance(
    instance_id=my_integration['id'],
    description="Updated AWS production account",
    resource_group_id="new-prod-rg"
)

# Lifecycle management
j1_client.disable_integration_instance(my_integration['id'])
j1_client.enable_integration_instance(my_integration['id'])

# Delete when no longer needed
j1_client.delete_integration_instance(my_integration['id'])

Consistency with Other Methods

Other resource management operations in the client follow comprehensive patterns:

# Alert rules have full lifecycle management
alerts = j1_client.list_alert_rules()
alert = j1_client.create_alert_rule(...)
j1_client.update_alert_rule(rule_id="123", ...)
j1_client.delete_alert_rule(rule_id="123")

# Entities have full lifecycle management
entity = j1_client.create_entity(...)
j1_client.update_entity(entity_id="123", ...)
j1_client.delete_entity(entity_id="123")

# Integration instances have PARTIAL management (this issue)
integration = j1_client.create_integration_instance(...)
# Missing: comprehensive update, delete, filtered listing

Impact

This limitation affects:

  • Integration Lifecycle Management: No easy way to delete or comprehensively update integrations
  • Automation Scripts: CI/CD pipelines must implement custom GraphQL for integration cleanup
  • Resource Discovery: Finding integrations by name requires custom parsing logic
  • Resource Group Management: No filtering by resource group for integration listing
  • Code Maintainability: Custom implementations are harder to maintain than client methods
  • Error Handling: Users must implement their own GraphQL error handling

Proposed Solution

Add comprehensive integration instance lifecycle management methods to the JupiterOneClient class following the established patterns from other resource methods.

Environment

  • JupiterOne Python API Client: v1.5.0
  • Python: 3.8+

Additional Context

This issue was identified during automated testing where integration lifecycle management is required. The current gaps force developers to maintain custom implementations for common operations like finding integrations by name and deleting unused integrations.

Integration management is commonly needed in:

  • Automated deployment scripts
  • CI/CD pipeline integration provisioning
  • Resource cleanup and lifecycle management
  • Integration migration between resource groups
  • Development/testing environment automation

Related Issues

  • Issue #49 - Added resource_group_id to create_integration_instance (resolved in v1.5.0)
  • Dashboard management methods (similar pattern needed)
  • Question management methods (similar pattern needed)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions