@microagi/alchemy-gcp 0.11.2 → 0.11.4

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +2 -0
  3. package/lib/ArtifactRegistry/Operations.d.ts +2 -2
  4. package/lib/ArtifactRegistry/Operations.d.ts.map +1 -1
  5. package/lib/ArtifactRegistry/Repository.d.ts +1 -1
  6. package/lib/ArtifactRegistry/RepositoryIamMember.d.ts +40 -0
  7. package/lib/ArtifactRegistry/RepositoryIamMember.d.ts.map +1 -0
  8. package/lib/ArtifactRegistry/RepositoryIamMember.js +110 -0
  9. package/lib/ArtifactRegistry/RepositoryIamMember.js.map +1 -0
  10. package/lib/ArtifactRegistry/Validation.d.ts.map +1 -1
  11. package/lib/ArtifactRegistry/index.d.ts +2 -0
  12. package/lib/ArtifactRegistry/index.d.ts.map +1 -1
  13. package/lib/ArtifactRegistry/index.js +1 -0
  14. package/lib/ArtifactRegistry/index.js.map +1 -1
  15. package/lib/Auth/AuthProvider.d.ts.map +1 -1
  16. package/lib/Auth/AuthProvider.js.map +1 -1
  17. package/lib/Auth/Credentials.d.ts +1 -1
  18. package/lib/Auth/Credentials.d.ts.map +1 -1
  19. package/lib/CloudResourceManager/Project.d.ts +1 -1
  20. package/lib/CloudResourceManager/ProjectIamMember.d.ts.map +1 -1
  21. package/lib/Compute/Address.d.ts +1 -1
  22. package/lib/Compute/Firewall.d.ts +1 -1
  23. package/lib/Compute/ForwardingRule.d.ts +1 -1
  24. package/lib/Compute/GlobalAddress.d.ts +1 -1
  25. package/lib/Compute/Network.d.ts +1 -1
  26. package/lib/Compute/Network.d.ts.map +1 -1
  27. package/lib/Compute/Operations.d.ts +4 -4
  28. package/lib/Compute/Operations.d.ts.map +1 -1
  29. package/lib/Compute/ProjectDefaultNetworkTier.d.ts +18 -0
  30. package/lib/Compute/ProjectDefaultNetworkTier.d.ts.map +1 -0
  31. package/lib/Compute/ProjectDefaultNetworkTier.js +63 -0
  32. package/lib/Compute/ProjectDefaultNetworkTier.js.map +1 -0
  33. package/lib/Compute/Subnetwork.d.ts +1 -1
  34. package/lib/Compute/SubnetworkIamMember.d.ts.map +1 -1
  35. package/lib/Compute/index.d.ts +1 -0
  36. package/lib/Compute/index.d.ts.map +1 -1
  37. package/lib/Compute/index.js +1 -0
  38. package/lib/Compute/index.js.map +1 -1
  39. package/lib/Container/Cluster.d.ts +8 -1
  40. package/lib/Container/Cluster.d.ts.map +1 -1
  41. package/lib/Container/Cluster.js +26 -14
  42. package/lib/Container/Cluster.js.map +1 -1
  43. package/lib/Container/NodePool.d.ts +1 -1
  44. package/lib/Container/NodePool.d.ts.map +1 -1
  45. package/lib/Container/Operations.d.ts +2 -2
  46. package/lib/Container/Operations.d.ts.map +1 -1
  47. package/lib/Iam/ServiceAccount.d.ts +1 -1
  48. package/lib/Iam/ServiceAccountIamMember.d.ts.map +1 -1
  49. package/lib/Kubernetes/Helm.d.ts +1 -1
  50. package/lib/Kubernetes/KubernetesManifest.d.ts +1 -1
  51. package/lib/Kubernetes/Secret.d.ts +1 -1
  52. package/lib/Kubernetes/client.d.ts.map +1 -1
  53. package/lib/Kubernetes/connection.d.ts.map +1 -1
  54. package/lib/ManagedLustre/Instance.d.ts +1 -1
  55. package/lib/Providers.d.ts +1 -1
  56. package/lib/Providers.d.ts.map +1 -1
  57. package/lib/Providers.js +5 -1
  58. package/lib/Providers.js.map +1 -1
  59. package/lib/Run/IamMember.d.ts.map +1 -1
  60. package/lib/Run/IamSync.d.ts.map +1 -1
  61. package/lib/Run/Job.d.ts +1 -1
  62. package/lib/Run/Operations.d.ts +2 -2
  63. package/lib/Run/Operations.d.ts.map +1 -1
  64. package/lib/Run/Service.d.ts +1 -1
  65. package/lib/Run/Validation.d.ts.map +1 -1
  66. package/lib/Sqladmin/Instance.d.ts +1 -1
  67. package/lib/Sqladmin/Operations.d.ts +2 -2
  68. package/lib/Sqladmin/Operations.d.ts.map +1 -1
  69. package/lib/Sqladmin/Types.d.ts.map +1 -1
  70. package/lib/Sqladmin/Validation.d.ts.map +1 -1
  71. package/lib/Storage/Bucket.d.ts +1 -1
  72. package/lib/Storage/BucketIamMember.d.ts.map +1 -1
  73. package/lib/Tags.d.ts.map +1 -1
  74. package/package.json +4 -4
  75. package/src/ArtifactRegistry/RepositoryIamMember.ts +205 -0
  76. package/src/ArtifactRegistry/index.ts +8 -0
  77. package/src/Compute/ProjectDefaultNetworkTier.ts +101 -0
  78. package/src/Compute/index.ts +1 -0
  79. package/src/Container/Cluster.ts +41 -16
  80. package/src/Providers.ts +12 -0
@@ -0,0 +1,205 @@
1
+ import { ConfigError } from "@distilled.cloud/gcp";
2
+ import * as ar from "@distilled.cloud/gcp/artifactregistry-v1";
3
+ import { Resource } from "alchemy";
4
+ import { isResolved } from "alchemy/Diff";
5
+ import * as Provider from "alchemy/Provider";
6
+ import * as Duration from "effect/Duration";
7
+ import * as Effect from "effect/Effect";
8
+ import * as Schedule from "effect/Schedule";
9
+ import type * as GCP from "../Providers.ts";
10
+
11
+ /**
12
+ * A single unconditional `(role, member)` IAM grant on an Artifact Registry
13
+ * repository. The repository is referenced by its fully-qualified resource
14
+ * name and is not created or deleted by this resource.
15
+ *
16
+ * Reconciliation is an additive read-modify-write: foreign bindings,
17
+ * conditional bindings, members, policy version, and etag are preserved.
18
+ * Deletion revokes only this exact member and removes an emptied binding.
19
+ * The whole cycle retries boundedly on stale-etag conflicts so concurrent
20
+ * policy writers compose safely.
21
+ *
22
+ * @example Read access to one Docker repository
23
+ * ```typescript
24
+ * yield* GCP.ArtifactRegistryRepositoryIamMember("EvalsAppsReader", {
25
+ * repository: apps.fullyQualifiedName,
26
+ * role: "roles/artifactregistry.reader",
27
+ * member: "serviceAccount:evals@example-project.iam.gserviceaccount.com",
28
+ * });
29
+ * ```
30
+ */
31
+ export type ArtifactRegistryRepositoryIamMemberProps = {
32
+ /**
33
+ * Fully-qualified repository resource name:
34
+ * `projects/{project}/locations/{location}/repositories/{repository}`.
35
+ * Immutable — changing it replaces the grant.
36
+ */
37
+ repository: string;
38
+ /** IAM role, e.g. `roles/artifactregistry.reader`. Immutable. */
39
+ role: string;
40
+ /** IAM member string, e.g. `serviceAccount:name@project.iam.gserviceaccount.com`. Immutable. */
41
+ member: string;
42
+ };
43
+
44
+ export type ArtifactRegistryRepositoryIamMemberAttributes =
45
+ ArtifactRegistryRepositoryIamMemberProps;
46
+
47
+ export type ArtifactRegistryRepositoryIamMember = Resource<
48
+ "GCP.ArtifactRegistryRepositoryIamMember",
49
+ ArtifactRegistryRepositoryIamMemberProps,
50
+ ArtifactRegistryRepositoryIamMemberAttributes,
51
+ never,
52
+ GCP.Providers
53
+ >;
54
+
55
+ export const ArtifactRegistryRepositoryIamMember =
56
+ Resource<ArtifactRegistryRepositoryIamMember>(
57
+ "GCP.ArtifactRegistryRepositoryIamMember",
58
+ );
59
+
60
+ export const ArtifactRegistryRepositoryIamMemberProvider = () =>
61
+ Provider.effect(
62
+ ArtifactRegistryRepositoryIamMember,
63
+ Effect.gen(function* () {
64
+ const getIamPolicy = yield* ar.getIamPolicyProjectsLocationsRepositories;
65
+ const setIamPolicy = yield* ar.setIamPolicyProjectsLocationsRepositories;
66
+
67
+ const hasMember = (policy: ar.Policy, role: string, member: string) =>
68
+ (policy.bindings ?? []).some(
69
+ (binding) =>
70
+ binding.role === role &&
71
+ !binding.condition &&
72
+ (binding.members ?? []).includes(member),
73
+ );
74
+
75
+ const conflictRetry = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
76
+ effect.pipe(
77
+ Effect.retry({
78
+ while: (error) => (error as { _tag?: string })?._tag === "Conflict",
79
+ schedule: Schedule.exponential(Duration.millis(250)).pipe(
80
+ Schedule.both(Schedule.recurs(8)),
81
+ ),
82
+ }),
83
+ );
84
+
85
+ const readPolicy = (repository: string) =>
86
+ getIamPolicy({
87
+ resource: repository,
88
+ "options.requestedPolicyVersion": 3,
89
+ });
90
+
91
+ return {
92
+ stables: ["repository", "role", "member"],
93
+ diff: Effect.fn(function* ({ news, olds = {}, output }) {
94
+ if (!isResolved(news)) return undefined;
95
+ const priorRepository = output?.repository || olds.repository;
96
+ const priorRole = output?.role || olds.role;
97
+ const priorMember = output?.member || olds.member;
98
+ if (
99
+ (priorRepository && priorRepository !== news.repository) ||
100
+ (priorRole && priorRole !== news.role) ||
101
+ (priorMember && priorMember !== news.member)
102
+ ) {
103
+ return { action: "replace" } as const;
104
+ }
105
+ return undefined;
106
+ }),
107
+ reconcile: Effect.fn(function* ({ news }) {
108
+ yield* conflictRetry(
109
+ Effect.gen(function* () {
110
+ const current = yield* readPolicy(news.repository).pipe(
111
+ Effect.catchTag("NotFound", () =>
112
+ Effect.fail(
113
+ new ConfigError({
114
+ message: `Artifact Registry repository ${news.repository} does not exist — RepositoryIamMember grants on existing repositories only.`,
115
+ }),
116
+ ),
117
+ ),
118
+ );
119
+ if (hasMember(current, news.role, news.member)) return;
120
+
121
+ const bindings = (current.bindings ?? []).map((binding) => ({
122
+ ...binding,
123
+ members: [...(binding.members ?? [])],
124
+ }));
125
+ const existing = bindings.find(
126
+ (binding) => binding.role === news.role && !binding.condition,
127
+ );
128
+ if (existing) {
129
+ existing.members = [...(existing.members ?? []), news.member];
130
+ } else {
131
+ bindings.push({ role: news.role, members: [news.member] });
132
+ }
133
+
134
+ yield* setIamPolicy({
135
+ resource: news.repository,
136
+ body: {
137
+ policy: { ...current, bindings, version: 3 },
138
+ },
139
+ });
140
+ }),
141
+ );
142
+ return {
143
+ repository: news.repository,
144
+ role: news.role,
145
+ member: news.member,
146
+ };
147
+ }),
148
+ delete: Effect.fn(function* ({ output }) {
149
+ if (!output.repository || !output.role || !output.member) return;
150
+ yield* conflictRetry(
151
+ Effect.gen(function* () {
152
+ const current = yield* readPolicy(output.repository).pipe(
153
+ Effect.catchTag("NotFound", () =>
154
+ Effect.succeed(undefined as ar.Policy | undefined),
155
+ ),
156
+ );
157
+ if (!current || !hasMember(current, output.role, output.member)) {
158
+ return;
159
+ }
160
+
161
+ const bindings = (current.bindings ?? [])
162
+ .map((binding) =>
163
+ binding.role === output.role && !binding.condition
164
+ ? {
165
+ ...binding,
166
+ members: (binding.members ?? []).filter(
167
+ (member) => member !== output.member,
168
+ ),
169
+ }
170
+ : {
171
+ ...binding,
172
+ members: [...(binding.members ?? [])],
173
+ },
174
+ )
175
+ .filter((binding) => (binding.members?.length ?? 0) > 0);
176
+
177
+ yield* setIamPolicy({
178
+ resource: output.repository,
179
+ body: {
180
+ policy: { ...current, bindings, version: 3 },
181
+ },
182
+ }).pipe(Effect.catchTag("NotFound", () => Effect.void));
183
+ }),
184
+ );
185
+ }),
186
+ read: Effect.fn(function* ({ output, olds }) {
187
+ const repository = output?.repository ?? olds?.repository;
188
+ const role = output?.role ?? olds?.role;
189
+ const member = output?.member ?? olds?.member;
190
+ if (!repository || !role || !member) return undefined;
191
+
192
+ const current = yield* readPolicy(repository).pipe(
193
+ Effect.catchTag("NotFound", () =>
194
+ Effect.succeed(undefined as ar.Policy | undefined),
195
+ ),
196
+ Effect.catchTag("Forbidden", () =>
197
+ Effect.succeed(undefined as ar.Policy | undefined),
198
+ ),
199
+ );
200
+ if (!current || !hasMember(current, role, member)) return undefined;
201
+ return { repository, role, member };
202
+ }),
203
+ };
204
+ }),
205
+ );
@@ -7,4 +7,12 @@ export type {
7
7
  ArtifactRegistryRepositoryAttributes,
8
8
  ArtifactRegistryRepositoryProps,
9
9
  } from "./Repository.ts";
10
+ export {
11
+ ArtifactRegistryRepositoryIamMember,
12
+ ArtifactRegistryRepositoryIamMemberProvider,
13
+ } from "./RepositoryIamMember.ts";
14
+ export type {
15
+ ArtifactRegistryRepositoryIamMemberAttributes,
16
+ ArtifactRegistryRepositoryIamMemberProps,
17
+ } from "./RepositoryIamMember.ts";
10
18
  export type { ArtifactRegistryFormat, ArtifactRegistryMode } from "./Types.ts";
@@ -0,0 +1,101 @@
1
+ import * as compute from "@distilled.cloud/gcp/compute-v1";
2
+ import { Resource } from "alchemy";
3
+ import { isResolved } from "alchemy/Diff";
4
+ import * as Provider from "alchemy/Provider";
5
+ import * as Effect from "effect/Effect";
6
+ import type * as GCP from "../Providers.ts";
7
+ import { makeAwaitGlobalOperation } from "./Operations.ts";
8
+
9
+ export type ProjectDefaultNetworkTierProps = {
10
+ /** GCP project whose default network tier is managed. Immutable. */
11
+ project: string;
12
+ /** Default tier applied to newly created Compute resources. */
13
+ networkTier: "PREMIUM" | "STANDARD";
14
+ };
15
+
16
+ export type ProjectDefaultNetworkTierAttributes = {
17
+ project: string;
18
+ networkTier: "PREMIUM" | "STANDARD";
19
+ };
20
+
21
+ export type ProjectDefaultNetworkTier = Resource<
22
+ "GCP.ProjectDefaultNetworkTier",
23
+ ProjectDefaultNetworkTierProps,
24
+ ProjectDefaultNetworkTierAttributes,
25
+ never,
26
+ GCP.Providers
27
+ >;
28
+ export const ProjectDefaultNetworkTier = Resource<ProjectDefaultNetworkTier>(
29
+ "GCP.ProjectDefaultNetworkTier",
30
+ );
31
+
32
+ const isProjectNetworkTier = (
33
+ value: string | undefined,
34
+ ): value is ProjectDefaultNetworkTierAttributes["networkTier"] =>
35
+ value === "PREMIUM" || value === "STANDARD";
36
+
37
+ /** Manage the Compute Engine project-wide default network service tier. */
38
+ export const ProjectDefaultNetworkTierProvider = () =>
39
+ Provider.effect(
40
+ ProjectDefaultNetworkTier,
41
+ Effect.gen(function* () {
42
+ const getProjects = yield* compute.getProjects;
43
+ const setDefaultNetworkTier = yield* compute.setDefaultNetworkTierProjects;
44
+ const getGlobalOperations = yield* compute.getGlobalOperations;
45
+ const awaitOp = makeAwaitGlobalOperation(getGlobalOperations);
46
+
47
+ const observe = (project: string) =>
48
+ getProjects({ project }).pipe(
49
+ Effect.catchTag("NotFound", () =>
50
+ Effect.succeed(undefined as compute.Project | undefined),
51
+ ),
52
+ Effect.catchTag("Forbidden", () =>
53
+ Effect.succeed(undefined as compute.Project | undefined),
54
+ ),
55
+ );
56
+
57
+ return {
58
+ stables: ["project"],
59
+ diff: Effect.fn(function* ({ news, olds = {} }) {
60
+ if (!isResolved(news)) return undefined;
61
+ if (olds.project !== undefined && olds.project !== news.project) {
62
+ return { action: "replace" } as const;
63
+ }
64
+
65
+ // This project-scoped setting can drift independently of Alchemy's
66
+ // persisted props (for example through the Cloud Console or gcloud).
67
+ // Existing resources do not pass through `read`, so consult the live
68
+ // project here and force reconcile whenever reality differs.
69
+ const observed = yield* observe(news.project);
70
+ if (observed?.defaultNetworkTier !== news.networkTier) {
71
+ return { action: "update" } as const;
72
+ }
73
+ return undefined;
74
+ }),
75
+ reconcile: Effect.fn(function* ({ news, session }) {
76
+ const observed = yield* observe(news.project);
77
+ if (observed?.defaultNetworkTier !== news.networkTier) {
78
+ const op = yield* setDefaultNetworkTier({
79
+ project: news.project,
80
+ body: { networkTier: news.networkTier },
81
+ });
82
+ if (op.name) yield* awaitOp(news.project, op.name, session);
83
+ }
84
+ return { project: news.project, networkTier: news.networkTier };
85
+ }),
86
+ // Project defaults are shared project-level policy. Removing this
87
+ // declaration must not silently revert the project's selected tier.
88
+ delete: Effect.fn(function* () {
89
+ return yield* Effect.void;
90
+ }),
91
+ read: Effect.fn(function* ({ output, olds }) {
92
+ const project = output?.project ?? olds?.project;
93
+ if (!project) return undefined;
94
+ const observed = yield* observe(project);
95
+ const networkTier = observed?.defaultNetworkTier;
96
+ if (!isProjectNetworkTier(networkTier)) return undefined;
97
+ return { project, networkTier };
98
+ }),
99
+ };
100
+ }),
101
+ );
@@ -3,6 +3,7 @@ export * from "./Firewall.ts";
3
3
  export * from "./ForwardingRule.ts";
4
4
  export * from "./GlobalAddress.ts";
5
5
  export * from "./Network.ts";
6
+ export * from "./ProjectDefaultNetworkTier.ts";
6
7
  export * from "./SharedVpcHost.ts";
7
8
  export * from "./SharedVpcServiceProject.ts";
8
9
  export * from "./Subnetwork.ts";
@@ -73,6 +73,8 @@ export type ClusterProps = {
73
73
  servicesIpv4CidrBlock?: string;
74
74
  clusterSecondaryRangeName?: string;
75
75
  servicesSecondaryRangeName?: string;
76
+ /** Cluster egress network service tier. Mutable via `update`. */
77
+ networkTierConfig?: cont.NetworkTierConfig;
76
78
  };
77
79
  /**
78
80
  * Cluster-level network settings. `datapathProvider:
@@ -251,6 +253,32 @@ export type Cluster = Resource<
251
253
  >;
252
254
  export const Cluster = Resource<Cluster>("GCP.Cluster");
253
255
 
256
+ /** @internal Pure replacement decision, exported for focused unit tests. */
257
+ export const diffClusterProps = (
258
+ olds: Partial<ClusterProps>,
259
+ news: ClusterProps,
260
+ ): { action: "replace" } | undefined => {
261
+ if (
262
+ somePropsAreDifferent(olds as ClusterProps, news, [
263
+ "project",
264
+ "location",
265
+ "name",
266
+ "network",
267
+ "subnetwork",
268
+ ])
269
+ ) {
270
+ return { action: "replace" };
271
+ }
272
+ const { networkTierConfig: _oldTier, ...oldIpAllocationPolicy } =
273
+ olds.ipAllocationPolicy ?? {};
274
+ const { networkTierConfig: _newTier, ...newIpAllocationPolicy } =
275
+ news.ipAllocationPolicy ?? {};
276
+ if (!deepEqual(oldIpAllocationPolicy, newIpAllocationPolicy)) {
277
+ return { action: "replace" };
278
+ }
279
+ return undefined;
280
+ };
281
+
254
282
  /**
255
283
  * Build the inline `NodePool` entry for the cluster create body.
256
284
  *
@@ -435,7 +463,8 @@ export const ClusterProvider = () =>
435
463
  });
436
464
 
437
465
  // Catch-all generic update for fields without dedicated setters:
438
- // currently `releaseChannel` and `workloadIdentityConfig`. The
466
+ // currently `releaseChannel`, `workloadIdentityConfig`, and the
467
+ // cluster network tier. The
439
468
  // API auto-derives the field mask from which `desired*` keys are
440
469
  // populated — no `updateMask` parameter needed.
441
470
  const syncClusterUpdate = Effect.fn(function* (args: {
@@ -457,6 +486,16 @@ export const ClusterProvider = () =>
457
486
  ) {
458
487
  update.desiredWorkloadIdentityConfig = args.news.workloadIdentityConfig;
459
488
  }
489
+ if (
490
+ args.news.ipAllocationPolicy?.networkTierConfig &&
491
+ !deepEqual(
492
+ args.observed.ipAllocationPolicy?.networkTierConfig,
493
+ args.news.ipAllocationPolicy.networkTierConfig,
494
+ )
495
+ ) {
496
+ update.desiredNetworkTierConfig =
497
+ args.news.ipAllocationPolicy.networkTierConfig;
498
+ }
460
499
  if (Object.keys(update).length === 0) return;
461
500
  const op = yield* updateClusters({
462
501
  name: args.fqName,
@@ -476,25 +515,11 @@ export const ClusterProvider = () =>
476
515
  ],
477
516
  diff: Effect.fn(function* ({ news, olds = {} }) {
478
517
  if (!isResolved(news)) return undefined;
479
- if (
480
- somePropsAreDifferent(olds as ClusterProps, news, [
481
- "project",
482
- "location",
483
- "name",
484
- "network",
485
- "subnetwork",
486
- ])
487
- ) {
488
- return { action: "replace" } as const;
489
- }
490
- if (!deepEqual(olds.ipAllocationPolicy, news.ipAllocationPolicy)) {
491
- return { action: "replace" } as const;
492
- }
493
518
  // `initialNodePool` and `networkConfig` are intentionally NOT
494
519
  // part of diff — both are consumed only on create. See the
495
520
  // ClusterProps JSDoc (networkConfig explains why a same-name
496
521
  // replace would be destructive).
497
- return undefined;
522
+ return diffClusterProps(olds, news);
498
523
  }),
499
524
  reconcile: Effect.fn(function* ({ id, news, session }) {
500
525
  const internalLabels = yield* gcpInternalLabels(id);
package/src/Providers.ts CHANGED
@@ -4,6 +4,10 @@ import {
4
4
  ArtifactRegistryRepository,
5
5
  ArtifactRegistryRepositoryProvider,
6
6
  } from "./ArtifactRegistry/Repository.ts";
7
+ import {
8
+ ArtifactRegistryRepositoryIamMember,
9
+ ArtifactRegistryRepositoryIamMemberProvider,
10
+ } from "./ArtifactRegistry/RepositoryIamMember.ts";
7
11
  import { GCPAuth } from "./Auth/AuthProvider.ts";
8
12
  import { fromAuthProvider } from "./Auth/Credentials.ts";
9
13
  import { Project, ProjectProvider } from "./CloudResourceManager/Project.ts";
@@ -15,6 +19,10 @@ import {
15
19
  } from "./Compute/ForwardingRule.ts";
16
20
  import { GlobalAddress, GlobalAddressProvider } from "./Compute/GlobalAddress.ts";
17
21
  import { Network, NetworkProvider } from "./Compute/Network.ts";
22
+ import {
23
+ ProjectDefaultNetworkTier,
24
+ ProjectDefaultNetworkTierProvider,
25
+ } from "./Compute/ProjectDefaultNetworkTier.ts";
18
26
  import { SharedVpcHost, SharedVpcHostProvider } from "./Compute/SharedVpcHost.ts";
19
27
  import {
20
28
  SharedVpcServiceProject,
@@ -94,6 +102,7 @@ export const providers = () =>
94
102
  NodePool,
95
103
  ApiEnable,
96
104
  Network,
105
+ ProjectDefaultNetworkTier,
97
106
  Subnetwork,
98
107
  Firewall,
99
108
  Address,
@@ -111,6 +120,7 @@ export const providers = () =>
111
120
  SqlDatabase,
112
121
  SqlUser,
113
122
  ArtifactRegistryRepository,
123
+ ArtifactRegistryRepositoryIamMember,
114
124
  ServiceAccount,
115
125
  ServiceAccountKey,
116
126
  KubernetesSecret,
@@ -125,6 +135,7 @@ export const providers = () =>
125
135
  NodePoolProvider(),
126
136
  ApiEnableProvider(),
127
137
  NetworkProvider(),
138
+ ProjectDefaultNetworkTierProvider(),
128
139
  SubnetworkProvider(),
129
140
  FirewallProvider(),
130
141
  AddressProvider(),
@@ -142,6 +153,7 @@ export const providers = () =>
142
153
  SqlDatabaseProvider(),
143
154
  SqlUserProvider(),
144
155
  ArtifactRegistryRepositoryProvider(),
156
+ ArtifactRegistryRepositoryIamMemberProvider(),
145
157
  ServiceAccountProvider(),
146
158
  ServiceAccountKeyProvider(),
147
159
  KubernetesSecretProvider(),