1import * as r53r from "@distilled.cloud/aws/route53resolver";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Binding from "../../Binding.ts";
5import { isBindingHost } from "../Lambda/Function.ts";
6import { ListResolverRuleAssociations } from "./ListResolverRuleAssociations.ts";
7import type { ResolverRule } from "./ResolverRule.ts";
8
9/**
10 * Bespoke (not via `BindingHttp.ts`): the operation is filter-based rather
11 * than ID-keyed, so the rule is injected as a `ResolverRuleId` filter instead
12 * of a request field. The IAM grant is `Resource: "*"` — verified live:
13 * `route53resolver:ListResolverRuleAssociations` does not support
14 * resource-level permissions (a rule-ARN-scoped grant is AccessDenied), the
15 * runtime callable's injected filter is what scopes results to the bound
16 * rule. The operation also internally describes the associated VPCs, so
17 * `ec2:DescribeVpcs` is required alongside it (also verified live — without
18 * it the call fails with `InvalidParameterException: You are not authorized
19 * to perform this operation ... ec2:DescribeVpcs`).
20 */
21export const ListResolverRuleAssociationsHttp = Layer.effect(
22 ListResolverRuleAssociations,
23 Effect.gen(function* () {
24 const op = yield* r53r.listResolverRuleAssociations;
25
26 return Effect.fn(function* (rule: ResolverRule) {
27 const ResolverRuleId = yield* rule.resolverRuleId;
28 if (!globalThis.__ALCHEMY_RUNTIME__) {
29 const host = yield* Binding.Host;
30 if (isBindingHost(host)) {
31 yield* host.bind`Allow(${host}, AWS.Route53Resolver.ListResolverRuleAssociations(${rule}))`(
32 {
33 policyStatements: [
34 {
35 Effect: "Allow",
36 Action: [
37 "route53resolver:ListResolverRuleAssociations",
38 "ec2:DescribeVpcs",
39 ],
40 Resource: ["*"],
41 },
42 ],
43 },
44 );
45 }
46 }
47 return Effect.fn(
48 `AWS.Route53Resolver.ListResolverRuleAssociations(${rule.LogicalId})`,
49 )(function* (
50 request?: Omit<r53r.ListResolverRuleAssociationsRequest, "Filters">,
51 ) {
52 return yield* op({
53 ...request,
54 Filters: [
55 { Name: "ResolverRuleId", Values: [yield* ResolverRuleId] },
56 ],
57 });
58 });
59 });
60 }),
61);