alchemy-effect 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/alchemy-effect.js +618 -260
- package/bin/alchemy-effect.js.map +1 -1
- package/lib/apply.d.ts +4 -4
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +444 -159
- package/lib/apply.js.map +1 -1
- package/lib/aws/dynamodb/table.provider.d.ts.map +1 -1
- package/lib/aws/dynamodb/table.provider.js +11 -2
- package/lib/aws/dynamodb/table.provider.js.map +1 -1
- package/lib/aws/ec2/index.d.ts +8 -0
- package/lib/aws/ec2/index.d.ts.map +1 -1
- package/lib/aws/ec2/index.js +8 -0
- package/lib/aws/ec2/index.js.map +1 -1
- package/lib/aws/ec2/internet-gateway.d.ts +65 -0
- package/lib/aws/ec2/internet-gateway.d.ts.map +1 -0
- package/lib/aws/ec2/internet-gateway.js +4 -0
- package/lib/aws/ec2/internet-gateway.js.map +1 -0
- package/lib/aws/ec2/internet-gateway.provider.d.ts +6 -0
- package/lib/aws/ec2/internet-gateway.provider.d.ts.map +1 -0
- package/lib/aws/ec2/internet-gateway.provider.js +193 -0
- package/lib/aws/ec2/internet-gateway.provider.js.map +1 -0
- package/lib/aws/ec2/route-table-association.d.ts +63 -0
- package/lib/aws/ec2/route-table-association.d.ts.map +1 -0
- package/lib/aws/ec2/route-table-association.js +4 -0
- package/lib/aws/ec2/route-table-association.js.map +1 -0
- package/lib/aws/ec2/route-table-association.provider.d.ts +4 -0
- package/lib/aws/ec2/route-table-association.provider.d.ts.map +1 -0
- package/lib/aws/ec2/route-table-association.provider.js +121 -0
- package/lib/aws/ec2/route-table-association.provider.js.map +1 -0
- package/lib/aws/ec2/route-table.d.ts +159 -0
- package/lib/aws/ec2/route-table.d.ts.map +1 -0
- package/lib/aws/ec2/route-table.js +4 -0
- package/lib/aws/ec2/route-table.js.map +1 -0
- package/lib/aws/ec2/route-table.provider.d.ts +6 -0
- package/lib/aws/ec2/route-table.provider.d.ts.map +1 -0
- package/lib/aws/ec2/route-table.provider.js +213 -0
- package/lib/aws/ec2/route-table.provider.js.map +1 -0
- package/lib/aws/ec2/route.d.ts +155 -0
- package/lib/aws/ec2/route.d.ts.map +1 -0
- package/lib/aws/ec2/route.js +3 -0
- package/lib/aws/ec2/route.js.map +1 -0
- package/lib/aws/ec2/route.provider.d.ts +4 -0
- package/lib/aws/ec2/route.provider.d.ts.map +1 -0
- package/lib/aws/ec2/route.provider.js +166 -0
- package/lib/aws/ec2/route.provider.js.map +1 -0
- package/lib/aws/ec2/subnet.provider.d.ts.map +1 -1
- package/lib/aws/ec2/subnet.provider.js +1 -1
- package/lib/aws/ec2/subnet.provider.js.map +1 -1
- package/lib/aws/ec2/vpc.d.ts +1 -0
- package/lib/aws/ec2/vpc.d.ts.map +1 -1
- package/lib/aws/ec2/vpc.provider.d.ts.map +1 -1
- package/lib/aws/ec2/vpc.provider.js +32 -10
- package/lib/aws/ec2/vpc.provider.js.map +1 -1
- package/lib/aws/index.d.ts +2 -3
- package/lib/aws/index.d.ts.map +1 -1
- package/lib/aws/index.js +2 -1
- package/lib/aws/index.js.map +1 -1
- package/lib/aws/lambda/function.provider.d.ts +2 -2
- package/lib/aws/lambda/function.provider.d.ts.map +1 -1
- package/lib/aws/lambda/function.provider.js +39 -42
- package/lib/aws/lambda/function.provider.js.map +1 -1
- package/lib/aws/sqs/queue.provider.d.ts +3 -4
- package/lib/aws/sqs/queue.provider.d.ts.map +1 -1
- package/lib/aws/sqs/queue.provider.js +17 -9
- package/lib/aws/sqs/queue.provider.js.map +1 -1
- package/lib/cli/index.d.ts +183 -100
- package/lib/cli/index.d.ts.map +1 -1
- package/lib/cloudflare/kv/namespace.client.d.ts +1 -1
- package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -1
- package/lib/cloudflare/kv/namespace.provider.js +12 -6
- package/lib/cloudflare/kv/namespace.provider.js.map +1 -1
- package/lib/cloudflare/r2/bucket.binding.js +1 -1
- package/lib/cloudflare/r2/bucket.binding.js.map +1 -1
- package/lib/cloudflare/r2/bucket.d.ts +1 -1
- package/lib/cloudflare/r2/bucket.d.ts.map +1 -1
- package/lib/cloudflare/r2/bucket.provider.d.ts +1 -2
- package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -1
- package/lib/cloudflare/r2/bucket.provider.js +23 -12
- package/lib/cloudflare/r2/bucket.provider.js.map +1 -1
- package/lib/cloudflare/worker/worker.d.ts +2 -2
- package/lib/cloudflare/worker/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.provider.d.ts +2 -3
- package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.provider.js +44 -13
- package/lib/cloudflare/worker/worker.provider.js.map +1 -1
- package/lib/diff.d.ts +8 -6
- package/lib/diff.d.ts.map +1 -1
- package/lib/diff.js +13 -0
- package/lib/diff.js.map +1 -1
- package/lib/event.d.ts +1 -1
- package/lib/event.d.ts.map +1 -1
- package/lib/instance-id.d.ts +12 -0
- package/lib/instance-id.d.ts.map +1 -0
- package/lib/instance-id.js +16 -0
- package/lib/instance-id.js.map +1 -0
- package/lib/output.d.ts +4 -2
- package/lib/output.d.ts.map +1 -1
- package/lib/output.js +18 -4
- package/lib/output.js.map +1 -1
- package/lib/physical-name.d.ts +25 -1
- package/lib/physical-name.d.ts.map +1 -1
- package/lib/physical-name.js +50 -2
- package/lib/physical-name.js.map +1 -1
- package/lib/plan.d.ts +49 -42
- package/lib/plan.d.ts.map +1 -1
- package/lib/plan.js +417 -137
- package/lib/plan.js.map +1 -1
- package/lib/provider.d.ts +26 -10
- package/lib/provider.d.ts.map +1 -1
- package/lib/provider.js +9 -0
- package/lib/provider.js.map +1 -1
- package/lib/resource.d.ts +3 -2
- package/lib/resource.d.ts.map +1 -1
- package/lib/resource.js.map +1 -1
- package/lib/state.d.ts +86 -9
- package/lib/state.d.ts.map +1 -1
- package/lib/state.js +21 -18
- package/lib/state.js.map +1 -1
- package/lib/tags.d.ts +15 -0
- package/lib/tags.d.ts.map +1 -1
- package/lib/tags.js +27 -0
- package/lib/tags.js.map +1 -1
- package/lib/test.d.ts +2 -2
- package/lib/test.d.ts.map +1 -1
- package/lib/test.js +4 -4
- package/lib/test.js.map +1 -1
- package/lib/todo.d.ts +3 -0
- package/lib/todo.d.ts.map +1 -0
- package/lib/todo.js +3 -0
- package/lib/todo.js.map +1 -0
- package/lib/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/apply.ts +742 -348
- package/src/aws/dynamodb/table.provider.ts +16 -4
- package/src/aws/ec2/index.ts +8 -0
- package/src/aws/ec2/internet-gateway.provider.ts +316 -0
- package/src/aws/ec2/internet-gateway.ts +79 -0
- package/src/aws/ec2/route-table-association.provider.ts +214 -0
- package/src/aws/ec2/route-table-association.ts +82 -0
- package/src/aws/ec2/route-table.provider.ts +306 -0
- package/src/aws/ec2/route-table.ts +175 -0
- package/src/aws/ec2/route.provider.ts +213 -0
- package/src/aws/ec2/route.ts +192 -0
- package/src/aws/ec2/subnet.provider.ts +2 -2
- package/src/aws/ec2/vpc.provider.ts +36 -11
- package/src/aws/ec2/vpc.ts +2 -0
- package/src/aws/index.ts +4 -1
- package/src/aws/lambda/function.provider.ts +66 -53
- package/src/aws/sqs/queue.provider.ts +18 -11
- package/src/cloudflare/kv/namespace.provider.ts +19 -14
- package/src/cloudflare/r2/bucket.binding.ts +1 -1
- package/src/cloudflare/r2/bucket.provider.ts +34 -24
- package/src/cloudflare/r2/bucket.ts +1 -1
- package/src/cloudflare/worker/worker.provider.ts +43 -13
- package/src/cloudflare/worker/worker.ts +2 -2
- package/src/diff.ts +35 -17
- package/src/event.ts +6 -0
- package/src/instance-id.ts +20 -0
- package/src/output.ts +29 -5
- package/src/physical-name.ts +79 -2
- package/src/plan.ts +566 -214
- package/src/provider.ts +46 -10
- package/src/resource.ts +65 -8
- package/src/state.ts +150 -35
- package/src/tags.ts +31 -0
- package/src/test.ts +5 -5
- package/src/todo.ts +4 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schedule from "effect/Schedule";
|
|
3
|
+
|
|
4
|
+
import type { EC2 } from "itty-aws/ec2";
|
|
5
|
+
|
|
6
|
+
import { somePropsAreDifferent } from "../../diff.ts";
|
|
7
|
+
import type { ProviderService } from "../../provider.ts";
|
|
8
|
+
import { EC2Client } from "./client.ts";
|
|
9
|
+
import { Route, type RouteAttrs, type RouteProps } from "./route.ts";
|
|
10
|
+
|
|
11
|
+
export const routeProvider = () =>
|
|
12
|
+
Route.provider.effect(
|
|
13
|
+
Effect.gen(function* () {
|
|
14
|
+
const ec2 = yield* EC2Client;
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
diff: Effect.fn(function* ({ news, olds }) {
|
|
18
|
+
// Route table change requires replacement
|
|
19
|
+
if (olds.routeTableId !== news.routeTableId) {
|
|
20
|
+
return { action: "replace" };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Destination change requires replacement
|
|
24
|
+
if (
|
|
25
|
+
somePropsAreDifferent(olds, news, [
|
|
26
|
+
"destinationCidrBlock",
|
|
27
|
+
"destinationIpv6CidrBlock",
|
|
28
|
+
"destinationPrefixListId",
|
|
29
|
+
])
|
|
30
|
+
) {
|
|
31
|
+
return { action: "replace" };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Target change can be done via ReplaceRoute (update)
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
create: Effect.fn(function* ({ news, session }) {
|
|
38
|
+
// Call CreateRoute
|
|
39
|
+
yield* ec2
|
|
40
|
+
.createRoute({
|
|
41
|
+
RouteTableId: news.routeTableId,
|
|
42
|
+
DestinationCidrBlock: news.destinationCidrBlock,
|
|
43
|
+
DestinationIpv6CidrBlock: news.destinationIpv6CidrBlock,
|
|
44
|
+
DestinationPrefixListId: news.destinationPrefixListId,
|
|
45
|
+
GatewayId: news.gatewayId,
|
|
46
|
+
NatGatewayId: news.natGatewayId,
|
|
47
|
+
InstanceId: news.instanceId,
|
|
48
|
+
NetworkInterfaceId: news.networkInterfaceId,
|
|
49
|
+
VpcPeeringConnectionId: news.vpcPeeringConnectionId,
|
|
50
|
+
TransitGatewayId: news.transitGatewayId,
|
|
51
|
+
LocalGatewayId: news.localGatewayId,
|
|
52
|
+
CarrierGatewayId: news.carrierGatewayId,
|
|
53
|
+
EgressOnlyInternetGatewayId: news.egressOnlyInternetGatewayId,
|
|
54
|
+
CoreNetworkArn: news.coreNetworkArn,
|
|
55
|
+
VpcEndpointId: news.vpcEndpointId,
|
|
56
|
+
DryRun: false,
|
|
57
|
+
})
|
|
58
|
+
.pipe(
|
|
59
|
+
Effect.retry({
|
|
60
|
+
// Retry if route table is not yet available
|
|
61
|
+
while: (e) => e._tag === "InvalidRouteTableID.NotFound",
|
|
62
|
+
schedule: Schedule.exponential(100),
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const dest =
|
|
67
|
+
news.destinationCidrBlock ||
|
|
68
|
+
news.destinationIpv6CidrBlock ||
|
|
69
|
+
news.destinationPrefixListId ||
|
|
70
|
+
"unknown";
|
|
71
|
+
yield* session.note(`Route created: ${dest}`);
|
|
72
|
+
|
|
73
|
+
// Describe to get route details
|
|
74
|
+
const route = yield* describeRoute(ec2, news.routeTableId, news);
|
|
75
|
+
|
|
76
|
+
// Return attributes
|
|
77
|
+
return {
|
|
78
|
+
routeTableId: news.routeTableId,
|
|
79
|
+
destinationCidrBlock: news.destinationCidrBlock,
|
|
80
|
+
destinationIpv6CidrBlock: news.destinationIpv6CidrBlock,
|
|
81
|
+
destinationPrefixListId: news.destinationPrefixListId,
|
|
82
|
+
origin: route?.Origin ?? "CreateRoute",
|
|
83
|
+
state: route?.State ?? "active",
|
|
84
|
+
gatewayId: route?.GatewayId,
|
|
85
|
+
natGatewayId: route?.NatGatewayId,
|
|
86
|
+
instanceId: route?.InstanceId,
|
|
87
|
+
networkInterfaceId: route?.NetworkInterfaceId,
|
|
88
|
+
vpcPeeringConnectionId: route?.VpcPeeringConnectionId,
|
|
89
|
+
transitGatewayId: route?.TransitGatewayId,
|
|
90
|
+
localGatewayId: route?.LocalGatewayId,
|
|
91
|
+
carrierGatewayId: route?.CarrierGatewayId,
|
|
92
|
+
egressOnlyInternetGatewayId: route?.EgressOnlyInternetGatewayId,
|
|
93
|
+
coreNetworkArn: route?.CoreNetworkArn,
|
|
94
|
+
} satisfies RouteAttrs<RouteProps>;
|
|
95
|
+
}),
|
|
96
|
+
|
|
97
|
+
update: Effect.fn(function* ({ news, output, session }) {
|
|
98
|
+
// Use ReplaceRoute to update the target
|
|
99
|
+
yield* ec2
|
|
100
|
+
.replaceRoute({
|
|
101
|
+
RouteTableId: news.routeTableId,
|
|
102
|
+
DestinationCidrBlock: news.destinationCidrBlock,
|
|
103
|
+
DestinationIpv6CidrBlock: news.destinationIpv6CidrBlock,
|
|
104
|
+
DestinationPrefixListId: news.destinationPrefixListId,
|
|
105
|
+
GatewayId: news.gatewayId,
|
|
106
|
+
NatGatewayId: news.natGatewayId,
|
|
107
|
+
InstanceId: news.instanceId,
|
|
108
|
+
NetworkInterfaceId: news.networkInterfaceId,
|
|
109
|
+
VpcPeeringConnectionId: news.vpcPeeringConnectionId,
|
|
110
|
+
TransitGatewayId: news.transitGatewayId,
|
|
111
|
+
LocalGatewayId: news.localGatewayId,
|
|
112
|
+
CarrierGatewayId: news.carrierGatewayId,
|
|
113
|
+
EgressOnlyInternetGatewayId: news.egressOnlyInternetGatewayId,
|
|
114
|
+
CoreNetworkArn: news.coreNetworkArn,
|
|
115
|
+
DryRun: false,
|
|
116
|
+
})
|
|
117
|
+
.pipe(
|
|
118
|
+
Effect.tapError(Effect.log),
|
|
119
|
+
Effect.retry({
|
|
120
|
+
while: (e) => e._tag === "InvalidRouteTableID.NotFound",
|
|
121
|
+
schedule: Schedule.exponential(100),
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
yield* session.note("Route target updated");
|
|
126
|
+
|
|
127
|
+
// Describe to get updated route details
|
|
128
|
+
const route = yield* describeRoute(ec2, news.routeTableId, news);
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
...output,
|
|
132
|
+
origin: route?.Origin ?? output.origin,
|
|
133
|
+
state: route?.State ?? output.state,
|
|
134
|
+
gatewayId: route?.GatewayId,
|
|
135
|
+
natGatewayId: route?.NatGatewayId,
|
|
136
|
+
instanceId: route?.InstanceId,
|
|
137
|
+
networkInterfaceId: route?.NetworkInterfaceId,
|
|
138
|
+
vpcPeeringConnectionId: route?.VpcPeeringConnectionId,
|
|
139
|
+
transitGatewayId: route?.TransitGatewayId,
|
|
140
|
+
localGatewayId: route?.LocalGatewayId,
|
|
141
|
+
carrierGatewayId: route?.CarrierGatewayId,
|
|
142
|
+
egressOnlyInternetGatewayId: route?.EgressOnlyInternetGatewayId,
|
|
143
|
+
coreNetworkArn: route?.CoreNetworkArn,
|
|
144
|
+
};
|
|
145
|
+
}),
|
|
146
|
+
|
|
147
|
+
delete: Effect.fn(function* ({ output, session }) {
|
|
148
|
+
const dest =
|
|
149
|
+
output.destinationCidrBlock ||
|
|
150
|
+
output.destinationIpv6CidrBlock ||
|
|
151
|
+
output.destinationPrefixListId ||
|
|
152
|
+
"unknown";
|
|
153
|
+
|
|
154
|
+
yield* session.note(`Deleting route: ${dest}`);
|
|
155
|
+
|
|
156
|
+
// Delete the route
|
|
157
|
+
yield* ec2
|
|
158
|
+
.deleteRoute({
|
|
159
|
+
RouteTableId: output.routeTableId,
|
|
160
|
+
DestinationCidrBlock: output.destinationCidrBlock,
|
|
161
|
+
DestinationIpv6CidrBlock: output.destinationIpv6CidrBlock,
|
|
162
|
+
DestinationPrefixListId: output.destinationPrefixListId,
|
|
163
|
+
DryRun: false,
|
|
164
|
+
})
|
|
165
|
+
.pipe(
|
|
166
|
+
Effect.tapError(Effect.logDebug),
|
|
167
|
+
Effect.catchTag("InvalidRoute.NotFound", () => Effect.void),
|
|
168
|
+
Effect.catchTag(
|
|
169
|
+
"InvalidRouteTableID.NotFound",
|
|
170
|
+
() => Effect.void,
|
|
171
|
+
),
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
yield* session.note(`Route ${dest} deleted successfully`);
|
|
175
|
+
}),
|
|
176
|
+
} satisfies ProviderService<Route>;
|
|
177
|
+
}),
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Find a specific route in a route table
|
|
182
|
+
*/
|
|
183
|
+
const describeRoute = (ec2: EC2, routeTableId: string, props: RouteProps) =>
|
|
184
|
+
Effect.gen(function* () {
|
|
185
|
+
const result = yield* ec2
|
|
186
|
+
.describeRouteTables({ RouteTableIds: [routeTableId] })
|
|
187
|
+
.pipe(
|
|
188
|
+
Effect.catchTag("InvalidRouteTableID.NotFound", () =>
|
|
189
|
+
Effect.succeed({ RouteTables: [] }),
|
|
190
|
+
),
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const routeTable = result.RouteTables?.[0];
|
|
194
|
+
if (!routeTable) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Find the matching route
|
|
199
|
+
const route = routeTable.Routes?.find((r) => {
|
|
200
|
+
if (props.destinationCidrBlock) {
|
|
201
|
+
return r.DestinationCidrBlock === props.destinationCidrBlock;
|
|
202
|
+
}
|
|
203
|
+
if (props.destinationIpv6CidrBlock) {
|
|
204
|
+
return r.DestinationIpv6CidrBlock === props.destinationIpv6CidrBlock;
|
|
205
|
+
}
|
|
206
|
+
if (props.destinationPrefixListId) {
|
|
207
|
+
return r.DestinationPrefixListId === props.destinationPrefixListId;
|
|
208
|
+
}
|
|
209
|
+
return false;
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
return route;
|
|
213
|
+
});
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import type * as EC2 from "itty-aws/ec2";
|
|
2
|
+
import type { Input } from "../../input.ts";
|
|
3
|
+
import { Resource } from "../../resource.ts";
|
|
4
|
+
import type { RouteTableId } from "./route-table.ts";
|
|
5
|
+
|
|
6
|
+
export const Route = Resource<{
|
|
7
|
+
<const ID extends string, const Props extends RouteProps>(
|
|
8
|
+
id: ID,
|
|
9
|
+
props: Props,
|
|
10
|
+
): Route<ID, Props>;
|
|
11
|
+
}>("AWS.EC2.Route");
|
|
12
|
+
|
|
13
|
+
export interface Route<
|
|
14
|
+
ID extends string = string,
|
|
15
|
+
Props extends RouteProps = RouteProps,
|
|
16
|
+
> extends Resource<
|
|
17
|
+
"AWS.EC2.Route",
|
|
18
|
+
ID,
|
|
19
|
+
Props,
|
|
20
|
+
RouteAttrs<Input.Resolve<Props>>,
|
|
21
|
+
Route
|
|
22
|
+
> {}
|
|
23
|
+
|
|
24
|
+
export interface RouteProps {
|
|
25
|
+
/**
|
|
26
|
+
* The ID of the route table where the route will be added.
|
|
27
|
+
* Required.
|
|
28
|
+
*/
|
|
29
|
+
routeTableId: Input<RouteTableId>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The IPv4 CIDR block used for the destination match.
|
|
33
|
+
* Either destinationCidrBlock, destinationIpv6CidrBlock, or destinationPrefixListId is required.
|
|
34
|
+
* @example "0.0.0.0/0"
|
|
35
|
+
*/
|
|
36
|
+
destinationCidrBlock?: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The IPv6 CIDR block used for the destination match.
|
|
40
|
+
* Either destinationCidrBlock, destinationIpv6CidrBlock, or destinationPrefixListId is required.
|
|
41
|
+
* @example "::/0"
|
|
42
|
+
*/
|
|
43
|
+
destinationIpv6CidrBlock?: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The ID of a prefix list used for the destination match.
|
|
47
|
+
* Either destinationCidrBlock, destinationIpv6CidrBlock, or destinationPrefixListId is required.
|
|
48
|
+
*/
|
|
49
|
+
destinationPrefixListId?: string;
|
|
50
|
+
|
|
51
|
+
// ---- Target properties (exactly one required) ----
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The ID of an internet gateway or virtual private gateway.
|
|
55
|
+
*/
|
|
56
|
+
gatewayId?: Input<string>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The ID of a NAT gateway.
|
|
60
|
+
*/
|
|
61
|
+
natGatewayId?: Input<string>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The ID of a NAT instance in your VPC.
|
|
65
|
+
* This operation fails unless exactly one network interface is attached.
|
|
66
|
+
*/
|
|
67
|
+
instanceId?: Input<string>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The ID of a network interface.
|
|
71
|
+
*/
|
|
72
|
+
networkInterfaceId?: Input<string>;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The ID of a VPC peering connection.
|
|
76
|
+
*/
|
|
77
|
+
vpcPeeringConnectionId?: Input<string>;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The ID of a transit gateway.
|
|
81
|
+
*/
|
|
82
|
+
transitGatewayId?: Input<string>;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The ID of a local gateway.
|
|
86
|
+
*/
|
|
87
|
+
localGatewayId?: Input<string>;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The ID of a carrier gateway.
|
|
91
|
+
* Use for Wavelength Zones only.
|
|
92
|
+
*/
|
|
93
|
+
carrierGatewayId?: Input<string>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The ID of an egress-only internet gateway.
|
|
97
|
+
* IPv6 traffic only.
|
|
98
|
+
*/
|
|
99
|
+
egressOnlyInternetGatewayId?: Input<string>;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The Amazon Resource Name (ARN) of the core network.
|
|
103
|
+
*/
|
|
104
|
+
coreNetworkArn?: Input<string>;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The ID of a VPC endpoint for Gateway Load Balancer.
|
|
108
|
+
*/
|
|
109
|
+
vpcEndpointId?: Input<string>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface RouteAttrs<Props extends RouteProps> {
|
|
113
|
+
/**
|
|
114
|
+
* The ID of the route table.
|
|
115
|
+
*/
|
|
116
|
+
routeTableId: Props["routeTableId"];
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The IPv4 CIDR block used for the destination match.
|
|
120
|
+
*/
|
|
121
|
+
destinationCidrBlock?: Props["destinationCidrBlock"];
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The IPv6 CIDR block used for the destination match.
|
|
125
|
+
*/
|
|
126
|
+
destinationIpv6CidrBlock?: Props["destinationIpv6CidrBlock"];
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The ID of a prefix list used for the destination match.
|
|
130
|
+
*/
|
|
131
|
+
destinationPrefixListId?: Props["destinationPrefixListId"];
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Describes how the route was created.
|
|
135
|
+
*/
|
|
136
|
+
origin: EC2.RouteOrigin;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The state of the route.
|
|
140
|
+
*/
|
|
141
|
+
state: EC2.RouteState;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The ID of the gateway (if applicable).
|
|
145
|
+
*/
|
|
146
|
+
gatewayId?: string;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The ID of the NAT gateway (if applicable).
|
|
150
|
+
*/
|
|
151
|
+
natGatewayId?: string;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The ID of the NAT instance (if applicable).
|
|
155
|
+
*/
|
|
156
|
+
instanceId?: string;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The ID of the network interface (if applicable).
|
|
160
|
+
*/
|
|
161
|
+
networkInterfaceId?: string;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* The ID of the VPC peering connection (if applicable).
|
|
165
|
+
*/
|
|
166
|
+
vpcPeeringConnectionId?: string;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The ID of the transit gateway (if applicable).
|
|
170
|
+
*/
|
|
171
|
+
transitGatewayId?: string;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* The ID of the local gateway (if applicable).
|
|
175
|
+
*/
|
|
176
|
+
localGatewayId?: string;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The ID of the carrier gateway (if applicable).
|
|
180
|
+
*/
|
|
181
|
+
carrierGatewayId?: string;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* The ID of the egress-only internet gateway (if applicable).
|
|
185
|
+
*/
|
|
186
|
+
egressOnlyInternetGatewayId?: string;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* The Amazon Resource Name (ARN) of the core network (if applicable).
|
|
190
|
+
*/
|
|
191
|
+
coreNetworkArn?: string;
|
|
192
|
+
}
|
|
@@ -11,8 +11,8 @@ import { EC2Client } from "./client.ts";
|
|
|
11
11
|
import {
|
|
12
12
|
Subnet,
|
|
13
13
|
type SubnetAttrs,
|
|
14
|
-
type SubnetProps,
|
|
15
14
|
type SubnetId,
|
|
15
|
+
type SubnetProps,
|
|
16
16
|
} from "./subnet.ts";
|
|
17
17
|
|
|
18
18
|
export const subnetProvider = () =>
|
|
@@ -22,6 +22,7 @@ export const subnetProvider = () =>
|
|
|
22
22
|
const tagged = yield* createTagger();
|
|
23
23
|
|
|
24
24
|
return {
|
|
25
|
+
stables: ["subnetId", "subnetArn", "ownerId", "vpcId"],
|
|
25
26
|
diff: Effect.fn(function* ({ news, olds }) {
|
|
26
27
|
if (
|
|
27
28
|
somePropsAreDifferent(olds, news, [
|
|
@@ -71,7 +72,6 @@ export const subnetProvider = () =>
|
|
|
71
72
|
})
|
|
72
73
|
.pipe(
|
|
73
74
|
Effect.retry({
|
|
74
|
-
// @ts-expect-error - this is unknown to itty-aws
|
|
75
75
|
while: (e) => e._tag === "InvalidVpcID.NotFound",
|
|
76
76
|
schedule: Schedule.exponential(100),
|
|
77
77
|
}),
|
|
@@ -7,7 +7,7 @@ import type { VpcId } from "./vpc.ts";
|
|
|
7
7
|
import type { ScopedPlanStatusSession } from "../../cli/service.ts";
|
|
8
8
|
import { somePropsAreDifferent } from "../../diff.ts";
|
|
9
9
|
import type { ProviderService } from "../../provider.ts";
|
|
10
|
-
import { createTagger, createTagsList } from "../../tags.ts";
|
|
10
|
+
import { createTagger, createTagsList, diffTags } from "../../tags.ts";
|
|
11
11
|
import { EC2Client } from "./client.ts";
|
|
12
12
|
import { Vpc, type VpcAttrs, type VpcProps } from "./vpc.ts";
|
|
13
13
|
import { Region } from "../region.ts";
|
|
@@ -21,7 +21,17 @@ export const vpcProvider = () =>
|
|
|
21
21
|
const accountId = yield* Account;
|
|
22
22
|
const tagged = yield* createTagger();
|
|
23
23
|
|
|
24
|
+
const createTags = (
|
|
25
|
+
id: string,
|
|
26
|
+
tags?: Record<string, string>,
|
|
27
|
+
): Record<string, string> => ({
|
|
28
|
+
Name: id,
|
|
29
|
+
...tagged(id),
|
|
30
|
+
...tags,
|
|
31
|
+
});
|
|
32
|
+
|
|
24
33
|
return {
|
|
34
|
+
stables: ["vpcId", "vpcArn", "ownerId", "isDefault"],
|
|
25
35
|
diff: Effect.fn(function* ({ news, olds }) {
|
|
26
36
|
if (
|
|
27
37
|
somePropsAreDifferent(olds, news, [
|
|
@@ -37,12 +47,7 @@ export const vpcProvider = () =>
|
|
|
37
47
|
}),
|
|
38
48
|
|
|
39
49
|
create: Effect.fn(function* ({ id, news, session }) {
|
|
40
|
-
// 1.
|
|
41
|
-
const alchemyTags = tagged(id);
|
|
42
|
-
const userTags = news.tags ?? {};
|
|
43
|
-
const allTags = { ...alchemyTags, ...userTags };
|
|
44
|
-
|
|
45
|
-
// 2. Call CreateVpc
|
|
50
|
+
// 1. Call CreateVpc
|
|
46
51
|
const createResult = yield* ec2.createVpc({
|
|
47
52
|
// TODO(sam): add all properties
|
|
48
53
|
AmazonProvidedIpv6CidrBlock: news.amazonProvidedIpv6CidrBlock,
|
|
@@ -59,7 +64,7 @@ export const vpcProvider = () =>
|
|
|
59
64
|
TagSpecifications: [
|
|
60
65
|
{
|
|
61
66
|
ResourceType: "vpc",
|
|
62
|
-
Tags: createTagsList(
|
|
67
|
+
Tags: createTagsList(createTags(id, news.tags)),
|
|
63
68
|
},
|
|
64
69
|
],
|
|
65
70
|
DryRun: false,
|
|
@@ -119,7 +124,7 @@ export const vpcProvider = () =>
|
|
|
119
124
|
} satisfies VpcAttrs<VpcProps>;
|
|
120
125
|
}),
|
|
121
126
|
|
|
122
|
-
update: Effect.fn(function* ({ news, olds, output, session }) {
|
|
127
|
+
update: Effect.fn(function* ({ id, news, olds, output, session }) {
|
|
123
128
|
const vpcId = output.vpcId;
|
|
124
129
|
|
|
125
130
|
// Only DNS and metrics settings can be updated
|
|
@@ -141,9 +146,29 @@ export const vpcProvider = () =>
|
|
|
141
146
|
yield* session.note("Updated DNS hostnames");
|
|
142
147
|
}
|
|
143
148
|
|
|
144
|
-
//
|
|
149
|
+
// Handle user tag updates
|
|
150
|
+
const newTags = createTags(id, news.tags);
|
|
151
|
+
const oldTags = output.tags ?? {};
|
|
152
|
+
const { removed, upsert } = diffTags(oldTags, newTags);
|
|
153
|
+
if (removed.length > 0) {
|
|
154
|
+
yield* ec2.deleteTags({
|
|
155
|
+
Resources: [vpcId],
|
|
156
|
+
Tags: removed.map((key) => ({ Key: key })),
|
|
157
|
+
DryRun: false,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
if (upsert.length > 0) {
|
|
161
|
+
yield* ec2.createTags({
|
|
162
|
+
Resources: [vpcId],
|
|
163
|
+
Tags: upsert,
|
|
164
|
+
DryRun: false,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
145
167
|
|
|
146
|
-
return
|
|
168
|
+
return {
|
|
169
|
+
...output,
|
|
170
|
+
tags: newTags,
|
|
171
|
+
}; // VPC attributes don't change from these updates
|
|
147
172
|
}),
|
|
148
173
|
|
|
149
174
|
delete: Effect.fn(function* ({ output, session }) {
|
package/src/aws/ec2/vpc.ts
CHANGED
package/src/aws/index.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as Layer from "effect/Layer";
|
|
2
2
|
|
|
3
3
|
// oxlint-disable-next-line no-unused-vars - needed or else provider types are transitively resolved through DynamoDB.Provider<..> lol
|
|
4
|
-
import type { Provider } from "../provider.ts";
|
|
5
4
|
|
|
6
5
|
import * as ESBuild from "../esbuild.ts";
|
|
7
6
|
import * as Account from "./account.ts";
|
|
@@ -22,6 +21,10 @@ import "./config.ts";
|
|
|
22
21
|
export const resources = () =>
|
|
23
22
|
Layer.mergeAll(
|
|
24
23
|
DynamoDB.tableProvider(),
|
|
24
|
+
EC2.internetGatewayProvider(),
|
|
25
|
+
EC2.routeProvider(),
|
|
26
|
+
EC2.routeTableAssociationProvider(),
|
|
27
|
+
EC2.routeTableProvider(),
|
|
25
28
|
EC2.subnetProvider(),
|
|
26
29
|
EC2.vpcProvider(),
|
|
27
30
|
Lambda.functionProvider(),
|