s3/kms: IAM IResourcePolicyFactory, function in object
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the issue
Whilst working on the Ruby documentation I noticed the following issue which could probably do with some investigation, the S3[1] and KMS[2] docs when referencing IResourcePolicyFactory were generating the following in Ruby:
```ruby
require 'aws-cdk-lib'
require 'constructs'
scope = nil # Constructs::Construct
class MyFactory
include AWSCDK::IAM::IResourcePolicyFactory
def for_resource(resource)
return {
env: resource.env,
def add_to_resource_policy(statement)
# custom implementation to add the statement to the resource policy
return {statement_added: true, policy_dependable: resource}
end,
}
end
end
AWSCDK::IAM::ResourceWithPolicies.register(scope, "AWS::S3::Bucket", MyFactory.new)
```
The backing TypeScript[3] is:
```typescript
import { CfnResource } from 'aws-cdk-lib';
import { IResourcePolicyFactory, IResourceWithPolicyV2, PolicyStatement, ResourceWithPolicies } from 'aws-cdk-lib/aws-iam';
import { Construct, IConstruct } from 'constructs';
declare const scope: Construct;
class MyFactory implements IResourcePolicyFactory {
forResource(resource: CfnResource): IResourceWithPolicyV2 {
return {
env: resource.env,
addToResourcePolicy(statement: PolicyStatement) {
// custom implementation to add the statement to the resource policy
return { statementAdded: true, policyDependable: resource };
}
}
}
}
ResourceWithPolicies.register(scope, 'AWS::S3::Bucket', new MyFactory());
```
There are a few issues here:
- Python documentation[4] and Java documentation[5] are similarly broken
- How exactly should we handle this?
In Java we have
```java
import software.amazon.awscdk.CfnResource;
import software.amazon.awscdk.services.iam.IResourcePolicyFactory;
import software.amazon.awscdk.services.iam.IResourceWithPolicyV2;
import software.amazon.awscdk.services.iam.PolicyStatement;
import software.amazon.awscdk.services.iam.ResourceWithPolicies;
import software.constructs.Construct;
import software.constructs.IConstruct;
Construct scope;
public class MyFactory implements IResourcePolicyFactory {
public IResourceWithPolicyV2 forResource(CfnResource resource) {
return Map.of(
"env", resource.getEnv(),
public Map addToResourcePolicy(PolicyStatement statement) {
// custom implementation to add the statement to the resource policy
return AddToResourcePolicyResult.builder()"statementAdded", true"policyDependable", resource.build();
});
}
}
ResourceWithPolicies.register(scope, "AWS::S3::Bucket", new MyFactory());
```
In Python, we have:
```python
from aws_cdk.aws_iam import AddToResourcePolicyResult
from aws_cdk import CfnResource
from aws_cdk.aws_iam import IResourcePolicyFactory, IResourceWithPolicyV2, PolicyStatement, ResourceWithPolicies
from constructs import Construct, IConstruct
# scope: Construct
@jsii.implements(IResourcePolicyFactory)
class MyFactory:
def for_resource(self, resource):
return {
"env": resource.env,
def add_to_resource_policy(self, statement):
# custom implementation to add the statement to the resource policy
return AddToResourcePolicyResult("statement_added"=True, "policy_dependable"=resource)
}
ResourceWithPolicies.register(scope, "AWS::S3::Bucket", MyFactory())
```
A potential fix for something comparable in Ruby would be:
```ruby
class MyFactory
include AWSCDK::IAM::IResourcePolicyFactory
def for_resource(resource)
return Class.new do
include AWSCDK::IAM::IResourceWithPolicyV2
define_method(:env) { resource.env }
define_method(:add_to_resource_policy) do |statement|
return {statement_added: true, policy_dependable: resource}
end
end.new
end
end
```
However this doesn't look great and introduces meta-programming like smells (both `Class.new {}.new` and `define_method`), a stabby proc `->(statement) { return { ... } }` is not acceptable here because to execute, we would have to use h[:add_to_resource_policy].call(statement) which is not what the CDK does.
### Links
[1] https://rubygems.omarqureshi.net/docs/AWSCDK/S3/index.html
[2] https://rubygems.omarqureshi.net/docs/AWSCDK/KMS/index.html
[3] https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3-readme.html
[4] https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_s3/README.html
[5] https://docs.aws.amazon.com/cdk/api/v2/java/software/amazon/awscdk/services/s3/package-summary.html
Contributor guide
Research direction
Start by comparing the generated S3 and KMS documentation linked in [1]-[5] with the TypeScript IResourcePolicyFactory example in [3]. Determine how the documentation generation should represent callback-bearing interfaces in Ruby, Python, and Java; done means the affected examples are valid and consistent across those languages.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, python, ruby, typescript
- Domain
- documentation
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100