Skip to content

Commit 0ddd7fb

Browse files
docs(aws): add guide for extending existing services (#10924)
Co-authored-by: Mohamed Solaiman <mohamedsolaiman@users.noreply.github.com> Co-authored-by: Daniel Barranquero <74871504+danibarranqueroo@users.noreply.github.com>
1 parent 22b233f commit 0ddd7fb

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

docs/developer-guide/aws-details.mdx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,58 @@ The best reference to understand how to implement a new service is following the
7373
- AWS API calls are wrapped in try/except blocks, with specific handling for `ClientError` and generic exceptions, always logging errors.
7474
- If ARN is not present for some resource, it can be constructed using string interpolation, always including partition, service, region, account, and resource ID.
7575
- Tags and additional attributes that cannot be retrieved from the default call, should be collected and stored for each resource using dedicated methods and threading using the resource object list as iterator.
76+
- When accessing dictionary values from AWS API responses, always use `.get()` with a default value instead of direct dictionary access (e.g., `response.get("Policies", {})` instead of `response["Policies"]`). AWS API responses may not always include all keys, and direct access can cause `KeyError` exceptions that break the entire scan for that service.
77+
78+
### Extending an Existing Service with New Attributes
79+
80+
When adding a new check that requires data not yet collected by an existing service, you need to extend the service by adding new attributes to its resource models and updating the data collection methods. This is a common contributor task that follows a consistent pattern:
81+
82+
1. **Identify the missing data**: Determine which AWS API call provides the data you need and whether it's already being called by the service.
83+
84+
2. **Add new attributes to the resource model**: Extend the Pydantic `BaseModel` class for the resource with the new fields. Use `Optional` types with `None` as the default value to maintain backward compatibility with existing checks.
85+
86+
3. **Update the data collection method**: Modify the existing method that fetches resource details to also extract and store the new attributes. If no existing method fetches the data, add a new method and call it in the constructor using `self.__threading_call__` if possible.
87+
88+
4. **Use safe dictionary access**: When extracting values from API responses, always use `.get()` with appropriate defaults to prevent `KeyError` exceptions when the API doesn't return certain fields.
89+
90+
#### Example: Adding DKIM Status to SES Identities
91+
92+
```python
93+
# Step 1 & 2: Add new fields to the resource model
94+
class Identity(BaseModel):
95+
name: str
96+
arn: str
97+
region: str
98+
type: Optional[str]
99+
policy: Optional[dict] = None
100+
tags: Optional[list] = []
101+
# New attributes for DKIM check
102+
dkim_status: Optional[str] = None
103+
dkim_signing_attributes_origin: Optional[str] = None
104+
105+
# Step 3: Update the data collection method
106+
def _get_email_identities(self, identity):
107+
try:
108+
regional_client = self.regional_clients[identity.region]
109+
identity_attributes = regional_client.get_email_identity(
110+
EmailIdentity=identity.name
111+
)
112+
# Step 4: Use .get() for safe dictionary access
113+
for content_key, content_value in identity_attributes.get("Policies", {}).items():
114+
identity.policy = loads(content)
115+
identity.tags = identity_attributes.get("Tags", [])
116+
# Extract new DKIM attributes
117+
identity.dkim_status = identity_attributes.get("DkimStatus")
118+
identity.dkim_signing_attributes_origin = (
119+
identity_attributes.get("DkimSigningAttributesOrigin")
120+
)
121+
except Exception as error:
122+
logger.error(
123+
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
124+
)
125+
```
126+
127+
5. **Update the service tests**: Add the new attributes to the test mock data and assertions to verify correct data extraction.
76128

77129
## Specific Patterns in AWS Checks
78130

0 commit comments

Comments
 (0)