Files
cleveragents-core/features/cloud_aws_sdk.feature
freemo 3556481681 feat(resource): implement AWS SDK integration for CloudResourceHandler
Implements real AWS SDK integration for CloudResourceHandler using boto3
as an optional dependency. Key changes:

- Add boto3/botocore as optional [aws] dependency in pyproject.toml
- Implement CloudResourceHandler.resolve() for AWS: builds boto3 session,
  verifies credentials via STS get_caller_identity for account-level types,
  and returns a BoundResource with the resource ARN as sandbox_path
- Implement discover_aws_resources() to enumerate VPCs, subnets, instances,
  S3 buckets, IAM roles, RDS instances, ECS clusters, Lambda functions,
  and EKS clusters via the AWS API
- Implement CloudResourceHandler.discover_children() for AWS resource types
  using the new discovery function
- Implement CloudSandboxStrategy.create/commit/rollback for AWS using a
  tag-based isolation strategy (CleverAgents:PlanId tag)
- GCP and Azure providers still raise NotImplementedError (pending)
- boto3 is optional: handler raises ImportError with helpful install message
  when boto3 is not installed
- Credentials are never logged (existing redaction infrastructure preserved)
- Update cloud_resources.feature to reflect new AWS behavior
- Add comprehensive cloud_aws_sdk.feature with 47 BDD scenarios covering
  all new code paths with mocked boto3

Closes #1021
2026-04-02 08:42:46 +00:00

232 lines
12 KiB
Gherkin

Feature: AWS SDK integration for CloudResourceHandler
As a CleverAgents user
I want the CloudResourceHandler to use real AWS SDK operations
So that I can resolve and discover AWS cloud resources
# boto3 availability
Scenario: boto3 availability flag is exposed
Given awssdk the cloud handler module is imported
Then awssdk the boto3 availability flag should be a boolean
# ── _build_aws_session ────────────────────────────────────────────────────
Scenario: _build_aws_session raises ImportError when boto3 is unavailable
Given awssdk boto3 is not available
When awssdk I try to build an AWS session with valid credentials
Then awssdk an ImportError should be raised mentioning "cleveragents[aws]"
Scenario: _build_aws_session builds a session from explicit credentials
Given awssdk boto3 is available via mock
When awssdk I build an AWS session with explicit credentials
Then awssdk the session should be created successfully
Scenario: _build_aws_session builds a session from profile name
Given awssdk boto3 is available via mock
When awssdk I build an AWS session with a profile name "test-profile"
Then awssdk the session should be created with profile "test-profile"
# ── CloudResourceHandler.resolve for AWS ─────────────────────────────────
Scenario: resolve returns BoundResource for AWS account type with mocked STS
Given awssdk boto3 is available via mock
And awssdk AWS STS returns account id "123456789012"
And awssdk a valid AWS cloud resource of type "aws"
When awssdk I call resolve on the cloud handler with mocked boto3
Then awssdk a BoundResource should be returned
And awssdk the BoundResource slot_name should be "cloud-slot"
And awssdk the BoundResource resource_type should be "aws"
And awssdk the BoundResource sandbox_path should contain "123456789012"
Scenario: resolve returns BoundResource for aws-vpc type (no STS check)
Given awssdk boto3 is available via mock
And awssdk a valid AWS cloud resource of type "aws-vpc"
When awssdk I call resolve on the cloud handler with mocked boto3
Then awssdk a BoundResource should be returned
And awssdk the BoundResource resource_type should be "aws-vpc"
Scenario: resolve raises ValueError when STS call fails
Given awssdk boto3 is available via mock
And awssdk AWS STS raises a ClientError
And awssdk a valid AWS cloud resource of type "aws"
When awssdk I call resolve on the cloud handler with mocked boto3
Then awssdk a ValueError should be raised mentioning "credential verification failed"
Scenario: resolve raises ImportError for AWS when boto3 is not installed
Given awssdk boto3 is not available
And awssdk a valid AWS cloud resource of type "aws-vpc"
When awssdk I call resolve on the cloud handler without boto3
Then awssdk an ImportError should be raised mentioning "cleveragents[aws]"
Scenario: resolve raises NotImplementedError for GCP provider
Given awssdk boto3 is available via mock
And awssdk a valid GCP cloud resource with credentials
When awssdk I call resolve on the cloud handler with mocked boto3
Then awssdk a NotImplementedError should be raised mentioning "gcp"
Scenario: resolve raises NotImplementedError for Azure provider
Given awssdk boto3 is available via mock
And awssdk a valid Azure cloud resource with credentials
When awssdk I call resolve on the cloud handler with mocked boto3
Then awssdk a NotImplementedError should be raised mentioning "azure"
# ── discover_aws_resources ────────────────────────────────────────────────
Scenario: discover_aws_resources returns empty list for unmapped type
Given awssdk boto3 is available via mock
And awssdk a mock boto3 session
And awssdk a cloud resource of type "aws-unknown-type"
When awssdk I call discover_aws_resources
Then awssdk the discovery result should be an empty list
Scenario: discover_aws_resources discovers VPCs from EC2
Given awssdk boto3 is available via mock
And awssdk EC2 describe_vpcs returns 2 VPCs
And awssdk a cloud resource of type "aws-vpc"
When awssdk I call discover_aws_resources
Then awssdk the discovery result should have 2 items
And awssdk each discovery item should have an "id" key
And awssdk each discovery item should have an "arn" key
Scenario: discover_aws_resources discovers S3 buckets
Given awssdk boto3 is available via mock
And awssdk S3 list_buckets returns 3 buckets
And awssdk a cloud resource of type "aws-s3-bucket"
When awssdk I call discover_aws_resources
Then awssdk the discovery result should have 3 items
And awssdk each discovery item arn should start with "arn:aws:s3:::"
Scenario: discover_aws_resources discovers ECS clusters
Given awssdk boto3 is available via mock
And awssdk ECS list_clusters returns 2 cluster ARNs
And awssdk a cloud resource of type "aws-ecs-cluster"
When awssdk I call discover_aws_resources
Then awssdk the discovery result should have 2 items
Scenario: discover_aws_resources handles API errors gracefully
Given awssdk boto3 is available via mock
And awssdk a mock boto3 session that raises an exception
And awssdk a cloud resource of type "aws-vpc"
When awssdk I call discover_aws_resources
Then awssdk the discovery result should be an empty list
# ── CloudResourceHandler.discover_children ────────────────────────────────
Scenario: discover_children raises NotImplementedError for non-AWS provider
Given awssdk a CloudResourceHandler instance
And awssdk a cloud resource of type "gcp-project"
When awssdk I call discover_children on the cloud handler
Then awssdk a NotImplementedError should be raised mentioning "aws"
Scenario: discover_children raises ImportError when boto3 is not installed
Given awssdk boto3 is not available
And awssdk a CloudResourceHandler instance
And awssdk a valid AWS cloud resource of type "aws-vpc"
When awssdk I call discover_children on the cloud handler without boto3
Then awssdk an ImportError should be raised mentioning "cleveragents[aws]"
Scenario: discover_children returns Resource objects for discovered VPCs
Given awssdk boto3 is available via mock
And awssdk a CloudResourceHandler instance
And awssdk EC2 describe_vpcs returns 2 VPCs
And awssdk a valid AWS cloud resource of type "aws-vpc"
When awssdk I call discover_children on the cloud handler with mocked boto3
Then awssdk the aws discovery result should be a list of Resource objects
And awssdk the aws discovery result should have 2 items
# ── CloudSandboxStrategy AWS implementation ───────────────────────────────
Scenario: CloudSandboxStrategy.create succeeds for AWS with boto3 available
Given awssdk boto3 is available via mock
And awssdk a cloud sandbox strategy for "aws"
When awssdk I call create on the AWS sandbox strategy with plan "PLAN-001"
Then awssdk no exception should be raised
Scenario: CloudSandboxStrategy.create raises ImportError without boto3
Given awssdk boto3 is not available
And awssdk a cloud sandbox strategy for "aws"
When awssdk I call create on the AWS sandbox strategy with plan "PLAN-001"
Then awssdk an ImportError should be raised mentioning "cleveragents[aws]"
Scenario: CloudSandboxStrategy.create raises NotImplementedError for GCP
Given awssdk boto3 is available via mock
And awssdk a cloud sandbox strategy for "gcp"
When awssdk I call create on the AWS sandbox strategy with plan "PLAN-001"
Then awssdk a NotImplementedError should be raised
Scenario: CloudSandboxStrategy.commit succeeds for AWS with boto3 available
Given awssdk boto3 is available via mock
And awssdk a cloud sandbox strategy for "aws"
When awssdk I call commit on the AWS sandbox strategy with plan "PLAN-001"
Then awssdk no exception should be raised
Scenario: CloudSandboxStrategy.commit raises ImportError without boto3
Given awssdk boto3 is not available
And awssdk a cloud sandbox strategy for "aws"
When awssdk I call commit on the AWS sandbox strategy with plan "PLAN-001"
Then awssdk an ImportError should be raised mentioning "cleveragents[aws]"
Scenario: CloudSandboxStrategy.commit raises NotImplementedError for Azure
Given awssdk boto3 is available via mock
And awssdk a cloud sandbox strategy for "azure"
When awssdk I call commit on the AWS sandbox strategy with plan "PLAN-001"
Then awssdk a NotImplementedError should be raised
Scenario: CloudSandboxStrategy.rollback succeeds for AWS with boto3 available
Given awssdk boto3 is available via mock
And awssdk a cloud sandbox strategy for "aws"
When awssdk I call rollback on the AWS sandbox strategy with plan "PLAN-001"
Then awssdk no exception should be raised
Scenario: CloudSandboxStrategy.rollback raises ImportError without boto3
Given awssdk boto3 is not available
And awssdk a cloud sandbox strategy for "aws"
When awssdk I call rollback on the AWS sandbox strategy with plan "PLAN-001"
Then awssdk an ImportError should be raised mentioning "cleveragents[aws]"
Scenario: CloudSandboxStrategy.rollback raises NotImplementedError for GCP
Given awssdk boto3 is available via mock
And awssdk a cloud sandbox strategy for "gcp"
When awssdk I call rollback on the AWS sandbox strategy with plan "PLAN-001"
Then awssdk a NotImplementedError should be raised
Scenario: CloudSandboxStrategy.create raises ValueError for empty plan_id
Given awssdk boto3 is available via mock
And awssdk a cloud sandbox strategy for "aws"
When awssdk I call create on the AWS sandbox strategy with plan ""
Then awssdk a ValueError should be raised mentioning "plan_id"
Scenario: CloudSandboxStrategy.commit raises ValueError for empty plan_id
Given awssdk boto3 is available via mock
And awssdk a cloud sandbox strategy for "aws"
When awssdk I call commit on the AWS sandbox strategy with plan ""
Then awssdk a ValueError should be raised mentioning "plan_id"
Scenario: CloudSandboxStrategy.rollback raises ValueError for empty plan_id
Given awssdk boto3 is available via mock
And awssdk a cloud sandbox strategy for "aws"
When awssdk I call rollback on the AWS sandbox strategy with plan ""
Then awssdk a ValueError should be raised mentioning "plan_id"
# ── Credential masking (regression) ──────────────────────────────────────
Scenario: AWS credentials are never logged in plain text
Given awssdk boto3 is available via mock
And awssdk a valid AWS cloud resource of type "aws"
When awssdk I call resolve on the cloud handler with mocked boto3
Then awssdk no raw credential values should appear in log output
# ── _AWS_RESOURCE_MAP coverage ────────────────────────────────────────────
Scenario: _AWS_RESOURCE_MAP contains expected AWS resource types
Given awssdk the cloud handler module is imported
Then awssdk the AWS resource map should contain "aws-vpc"
And awssdk the AWS resource map should contain "aws-subnet"
And awssdk the AWS resource map should contain "aws-instance"
And awssdk the AWS resource map should contain "aws-s3-bucket"
And awssdk the AWS resource map should contain "aws-iam-role"
And awssdk the AWS resource map should contain "aws-rds-instance"
And awssdk the AWS resource map should contain "aws-ecs-cluster"
And awssdk the AWS resource map should contain "aws-lambda-function"
And awssdk the AWS resource map should contain "aws-eks-cluster"