Skip to content

Commit ddd22a3

Browse files
mawallaceMichael Wallace
and
Michael Wallace
authored
Add events for CDK custom resource provider framework. (#846)
Co-authored-by: Michael Wallace <michael.a.wallace@icloud.com>
1 parent 731d201 commit ddd22a3

6 files changed

+213
-0
lines changed

lambda-events/src/event/cloudformation/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
22
use serde_json::Value;
33
use std::collections::HashMap;
44

5+
pub mod provider;
6+
57
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
68
#[serde(tag = "RequestType")]
79
pub enum CloudFormationCustomResourceRequest<P1 = Value, P2 = Value>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
//! These events are to be used with the CDK custom resource provider framework.
2+
//!
3+
//! Note that they are similar (but not the same) as the events in the `super` module.
4+
//!
5+
//! See https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.custom_resources-readme.html for details.
6+
7+
use serde::{de::DeserializeOwned, Deserialize, Serialize};
8+
use serde_json::Value;
9+
10+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
11+
#[serde(tag = "RequestType")]
12+
pub enum CloudFormationCustomResourceRequest<P1 = Value, P2 = Value>
13+
where
14+
P1: DeserializeOwned + Serialize,
15+
P2: DeserializeOwned + Serialize,
16+
{
17+
#[serde(bound = "")]
18+
Create(CreateRequest<P2>),
19+
#[serde(bound = "")]
20+
Update(UpdateRequest<P1, P2>),
21+
#[serde(bound = "")]
22+
Delete(DeleteRequest<P2>),
23+
}
24+
25+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
26+
#[serde(rename_all = "PascalCase")]
27+
pub struct CreateRequest<P2 = Value>
28+
where
29+
P2: DeserializeOwned + Serialize,
30+
{
31+
#[serde(flatten, bound = "")]
32+
pub common: CommonRequestParams<P2>,
33+
}
34+
35+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
36+
#[serde(rename_all = "PascalCase")]
37+
pub struct UpdateRequest<P1 = Value, P2 = Value>
38+
where
39+
P1: DeserializeOwned + Serialize,
40+
P2: DeserializeOwned + Serialize,
41+
{
42+
pub physical_resource_id: String,
43+
44+
#[serde(bound = "")]
45+
pub old_resource_properties: P1,
46+
47+
#[serde(flatten, bound = "")]
48+
pub common: CommonRequestParams<P2>,
49+
}
50+
51+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
52+
#[serde(rename_all = "PascalCase")]
53+
pub struct DeleteRequest<P2 = Value>
54+
where
55+
P2: DeserializeOwned + Serialize,
56+
{
57+
pub physical_resource_id: String,
58+
59+
#[serde(flatten, bound = "")]
60+
pub common: CommonRequestParams<P2>,
61+
}
62+
63+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
64+
#[serde(rename_all = "PascalCase")]
65+
pub struct CommonRequestParams<P2 = Value>
66+
where
67+
P2: DeserializeOwned + Serialize,
68+
{
69+
pub logical_resource_id: String,
70+
#[serde(bound = "")]
71+
pub resource_properties: P2,
72+
pub resource_type: String,
73+
pub request_id: String,
74+
pub stack_id: String,
75+
}
76+
77+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, Default)]
78+
#[serde(rename_all = "PascalCase")]
79+
pub struct CloudFormationCustomResourceResponse<D = Value>
80+
where
81+
D: DeserializeOwned + Serialize,
82+
{
83+
pub physical_resource_id: Option<String>,
84+
#[serde(bound = "")]
85+
pub data: D,
86+
pub no_echo: bool,
87+
}
88+
89+
#[cfg(test)]
90+
mod test {
91+
use std::collections::HashMap;
92+
93+
use super::CloudFormationCustomResourceRequest::*;
94+
use super::*;
95+
96+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
97+
#[serde(rename_all = "PascalCase")]
98+
struct TestProperties {
99+
key_1: String,
100+
key_2: Vec<String>,
101+
key_3: HashMap<String, String>,
102+
}
103+
104+
type TestRequest = CloudFormationCustomResourceRequest<TestProperties, TestProperties>;
105+
106+
#[test]
107+
fn example_create_request() {
108+
let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-create-request.json");
109+
let parsed: TestRequest = serde_json::from_slice(data).unwrap();
110+
111+
match parsed {
112+
Create(_) => (),
113+
_ => panic!("expected Create request"),
114+
}
115+
116+
let output: String = serde_json::to_string(&parsed).unwrap();
117+
let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap();
118+
assert_eq!(parsed, reparsed);
119+
}
120+
121+
#[test]
122+
fn example_update_request() {
123+
let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-update-request.json");
124+
let parsed: TestRequest = serde_json::from_slice(data).unwrap();
125+
126+
match parsed {
127+
Update(_) => (),
128+
_ => panic!("expected Update request"),
129+
}
130+
131+
let output: String = serde_json::to_string(&parsed).unwrap();
132+
let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap();
133+
assert_eq!(parsed, reparsed);
134+
}
135+
136+
#[test]
137+
fn example_delete_request() {
138+
let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-delete-request.json");
139+
let parsed: TestRequest = serde_json::from_slice(data).unwrap();
140+
141+
match parsed {
142+
Delete(_) => (),
143+
_ => panic!("expected Delete request"),
144+
}
145+
146+
let output: String = serde_json::to_string(&parsed).unwrap();
147+
let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap();
148+
assert_eq!(parsed, reparsed);
149+
}
150+
151+
#[test]
152+
fn example_response() {
153+
let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-response.json");
154+
let parsed: CloudFormationCustomResourceResponse = serde_json::from_slice(data).unwrap();
155+
let output: String = serde_json::to_string(&parsed).unwrap();
156+
let reparsed: CloudFormationCustomResourceResponse = serde_json::from_slice(output.as_bytes()).unwrap();
157+
assert_eq!(parsed, reparsed);
158+
}
159+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"RequestType" : "Create",
3+
"RequestId" : "82304eb2-bdda-469f-a33b-a3f1406d0a52",
4+
"StackId" : "arn:aws:cloudformation:us-east-1:123456789012:stack/stack-name/16580499-7622-4a9c-b32f-4eba35da93da",
5+
"ResourceType" : "Custom::MyCustomResourceType",
6+
"LogicalResourceId" : "CustomResource",
7+
"ResourceProperties" : {
8+
"Key1" : "string",
9+
"Key2" : [ "list" ],
10+
"Key3" : { "Key4" : "map" }
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"RequestType" : "Delete",
3+
"RequestId" : "ef70561d-d4ba-42a4-801b-33ad88dafc37",
4+
"StackId" : "arn:aws:cloudformation:us-east-1:123456789012:stack/stack-name/16580499-7622-4a9c-b32f-4eba35da93da",
5+
"ResourceType" : "Custom::MyCustomResourceType",
6+
"LogicalResourceId" : "CustomResource",
7+
"PhysicalResourceId" : "custom-resource-f4bd5382-3de3-4caf-b7ad-1be06b899647",
8+
"ResourceProperties" : {
9+
"Key1" : "string",
10+
"Key2" : [ "list" ],
11+
"Key3" : { "Key4" : "map" }
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"PhysicalResourceId": "custom-resource-f4bd5382-3de3-4caf-b7ad-1be06b899647",
3+
"NoEcho": false,
4+
"Data": {
5+
"Key1": "a",
6+
"Key2": "b",
7+
"Key3": "c"
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"RequestType" : "Update",
3+
"RequestId" : "49347ca5-c603-44e5-a34b-10cf1854a887",
4+
"StackId" : "arn:aws:cloudformation:us-east-1:123456789012:stack/stack-name/16580499-7622-4a9c-b32f-4eba35da93da",
5+
"ResourceType" : "Custom::MyCustomResourceType",
6+
"LogicalResourceId" : "CustomResource",
7+
"PhysicalResourceId" : "custom-resource-f4bd5382-3de3-4caf-b7ad-1be06b899647",
8+
"ResourceProperties" : {
9+
"Key1" : "new-string",
10+
"Key2" : [ "new-list" ],
11+
"Key3" : { "Key4" : "new-map" }
12+
},
13+
"OldResourceProperties" : {
14+
"Key1" : "string",
15+
"Key2" : [ "list" ],
16+
"Key3" : { "Key4" : "map" }
17+
}
18+
}

0 commit comments

Comments
 (0)