@microagi/alchemy-gcp 0.11.6 → 0.11.8

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 (164) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/lib/ArtifactRegistry/Operations.d.ts +1 -1
  3. package/lib/ArtifactRegistry/Repository.d.ts +2 -2
  4. package/lib/ArtifactRegistry/Repository.d.ts.map +1 -1
  5. package/lib/ArtifactRegistry/Repository.js +5 -5
  6. package/lib/ArtifactRegistry/Repository.js.map +1 -1
  7. package/lib/ArtifactRegistry/RepositoryIamMember.d.ts +2 -1
  8. package/lib/ArtifactRegistry/RepositoryIamMember.d.ts.map +1 -1
  9. package/lib/ArtifactRegistry/RepositoryIamMember.js +1 -1
  10. package/lib/CloudResourceManager/Project.d.ts +2 -1
  11. package/lib/CloudResourceManager/Project.d.ts.map +1 -1
  12. package/lib/CloudResourceManager/Project.js +6 -6
  13. package/lib/CloudResourceManager/Project.js.map +1 -1
  14. package/lib/Compute/Address.d.ts +2 -1
  15. package/lib/Compute/Address.d.ts.map +1 -1
  16. package/lib/Compute/Address.js +4 -4
  17. package/lib/Compute/Address.js.map +1 -1
  18. package/lib/Compute/Firewall.d.ts +2 -1
  19. package/lib/Compute/Firewall.d.ts.map +1 -1
  20. package/lib/Compute/Firewall.js +1 -1
  21. package/lib/Compute/ForwardingRule.d.ts +2 -1
  22. package/lib/Compute/ForwardingRule.d.ts.map +1 -1
  23. package/lib/Compute/ForwardingRule.js +4 -4
  24. package/lib/Compute/ForwardingRule.js.map +1 -1
  25. package/lib/Compute/GlobalAddress.d.ts +2 -1
  26. package/lib/Compute/GlobalAddress.d.ts.map +1 -1
  27. package/lib/Compute/GlobalAddress.js +4 -4
  28. package/lib/Compute/GlobalAddress.js.map +1 -1
  29. package/lib/Compute/Network.d.ts +2 -1
  30. package/lib/Compute/Network.d.ts.map +1 -1
  31. package/lib/Compute/Network.js +1 -1
  32. package/lib/Compute/Operations.d.ts +1 -1
  33. package/lib/Compute/ProjectDefaultNetworkTier.d.ts +2 -1
  34. package/lib/Compute/ProjectDefaultNetworkTier.d.ts.map +1 -1
  35. package/lib/Compute/ProjectDefaultNetworkTier.js +1 -1
  36. package/lib/Compute/SharedVpcHost.d.ts +2 -1
  37. package/lib/Compute/SharedVpcHost.d.ts.map +1 -1
  38. package/lib/Compute/SharedVpcHost.js +1 -1
  39. package/lib/Compute/SharedVpcServiceProject.d.ts +2 -1
  40. package/lib/Compute/SharedVpcServiceProject.d.ts.map +1 -1
  41. package/lib/Compute/SharedVpcServiceProject.js +1 -1
  42. package/lib/Compute/Subnetwork.d.ts +2 -1
  43. package/lib/Compute/Subnetwork.d.ts.map +1 -1
  44. package/lib/Compute/Subnetwork.js +2 -2
  45. package/lib/Compute/Subnetwork.js.map +1 -1
  46. package/lib/Container/Cluster.d.ts +4 -2
  47. package/lib/Container/Cluster.d.ts.map +1 -1
  48. package/lib/Container/Cluster.js +28 -10
  49. package/lib/Container/Cluster.js.map +1 -1
  50. package/lib/Container/NodePool.d.ts +2 -2
  51. package/lib/Container/NodePool.d.ts.map +1 -1
  52. package/lib/Container/NodePool.js +22 -12
  53. package/lib/Container/NodePool.js.map +1 -1
  54. package/lib/Container/Operations.d.ts +1 -1
  55. package/lib/Iam/Operations.d.ts +42 -0
  56. package/lib/Iam/Operations.d.ts.map +1 -0
  57. package/lib/Iam/Operations.js +48 -0
  58. package/lib/Iam/Operations.js.map +1 -0
  59. package/lib/Iam/ServiceAccount.d.ts +2 -1
  60. package/lib/Iam/ServiceAccount.d.ts.map +1 -1
  61. package/lib/Iam/ServiceAccount.js +1 -1
  62. package/lib/Iam/ServiceAccountKey.d.ts +2 -1
  63. package/lib/Iam/ServiceAccountKey.d.ts.map +1 -1
  64. package/lib/Iam/ServiceAccountKey.js +1 -1
  65. package/lib/Iam/WorkloadIdentityPool.d.ts +101 -0
  66. package/lib/Iam/WorkloadIdentityPool.d.ts.map +1 -0
  67. package/lib/Iam/WorkloadIdentityPool.js +175 -0
  68. package/lib/Iam/WorkloadIdentityPool.js.map +1 -0
  69. package/lib/Iam/WorkloadIdentityPoolProvider.d.ts +125 -0
  70. package/lib/Iam/WorkloadIdentityPoolProvider.d.ts.map +1 -0
  71. package/lib/Iam/WorkloadIdentityPoolProvider.js +222 -0
  72. package/lib/Iam/WorkloadIdentityPoolProvider.js.map +1 -0
  73. package/lib/Iam/index.d.ts +4 -0
  74. package/lib/Iam/index.d.ts.map +1 -1
  75. package/lib/Iam/index.js +2 -0
  76. package/lib/Iam/index.js.map +1 -1
  77. package/lib/Kubernetes/Secret.d.ts.map +1 -1
  78. package/lib/Kubernetes/Secret.js.map +1 -1
  79. package/lib/ManagedLustre/Instance.d.ts +2 -1
  80. package/lib/ManagedLustre/Instance.d.ts.map +1 -1
  81. package/lib/ManagedLustre/Instance.js +6 -6
  82. package/lib/ManagedLustre/Instance.js.map +1 -1
  83. package/lib/Providers.d.ts.map +1 -1
  84. package/lib/Providers.js +5 -1
  85. package/lib/Providers.js.map +1 -1
  86. package/lib/Run/IamSync.d.ts +1 -1
  87. package/lib/Run/Job.d.ts +3 -3
  88. package/lib/Run/Job.d.ts.map +1 -1
  89. package/lib/Run/Job.js +5 -5
  90. package/lib/Run/Job.js.map +1 -1
  91. package/lib/Run/Operations.d.ts +1 -1
  92. package/lib/Run/Service.d.ts +2 -2
  93. package/lib/Run/Service.d.ts.map +1 -1
  94. package/lib/Run/Service.js +9 -7
  95. package/lib/Run/Service.js.map +1 -1
  96. package/lib/Run/index.d.ts +2 -2
  97. package/lib/ServiceNetworking/PsaConnection.d.ts +2 -1
  98. package/lib/ServiceNetworking/PsaConnection.d.ts.map +1 -1
  99. package/lib/ServiceNetworking/PsaConnection.js +1 -1
  100. package/lib/ServiceUsage/ApiEnable.d.ts +2 -1
  101. package/lib/ServiceUsage/ApiEnable.d.ts.map +1 -1
  102. package/lib/ServiceUsage/ApiEnable.js +1 -1
  103. package/lib/Sqladmin/Database.d.ts +2 -1
  104. package/lib/Sqladmin/Database.d.ts.map +1 -1
  105. package/lib/Sqladmin/Database.js +1 -1
  106. package/lib/Sqladmin/Instance.d.ts +2 -1
  107. package/lib/Sqladmin/Instance.d.ts.map +1 -1
  108. package/lib/Sqladmin/Instance.js +7 -7
  109. package/lib/Sqladmin/Instance.js.map +1 -1
  110. package/lib/Sqladmin/Operations.d.ts +1 -1
  111. package/lib/Sqladmin/User.d.ts +2 -1
  112. package/lib/Sqladmin/User.d.ts.map +1 -1
  113. package/lib/Sqladmin/User.js +1 -1
  114. package/lib/Storage/Bucket.d.ts +2 -2
  115. package/lib/Storage/Bucket.d.ts.map +1 -1
  116. package/lib/Storage/Bucket.js +1 -1
  117. package/lib/Storage/StorageBucketIamMember.d.ts +2 -1
  118. package/lib/Storage/StorageBucketIamMember.d.ts.map +1 -1
  119. package/lib/Storage/StorageBucketIamMember.js +1 -1
  120. package/lib/Tags.d.ts +3 -1
  121. package/lib/Tags.d.ts.map +1 -1
  122. package/lib/Tags.js +9 -1
  123. package/lib/Tags.js.map +1 -1
  124. package/package.json +9 -9
  125. package/src/ArtifactRegistry/Operations.ts +1 -1
  126. package/src/ArtifactRegistry/Repository.ts +5 -5
  127. package/src/ArtifactRegistry/RepositoryIamMember.ts +1 -1
  128. package/src/CloudResourceManager/Project.ts +6 -6
  129. package/src/Compute/Address.ts +4 -4
  130. package/src/Compute/Firewall.ts +1 -1
  131. package/src/Compute/ForwardingRule.ts +4 -4
  132. package/src/Compute/GlobalAddress.ts +4 -4
  133. package/src/Compute/Network.ts +1 -1
  134. package/src/Compute/Operations.ts +1 -1
  135. package/src/Compute/ProjectDefaultNetworkTier.ts +1 -1
  136. package/src/Compute/SharedVpcHost.ts +1 -1
  137. package/src/Compute/SharedVpcServiceProject.ts +1 -1
  138. package/src/Compute/Subnetwork.ts +2 -2
  139. package/src/Container/Cluster.ts +36 -11
  140. package/src/Container/NodePool.ts +30 -13
  141. package/src/Container/Operations.ts +1 -1
  142. package/src/Iam/Operations.ts +81 -0
  143. package/src/Iam/ServiceAccount.ts +1 -1
  144. package/src/Iam/ServiceAccountKey.ts +1 -1
  145. package/src/Iam/WorkloadIdentityPool.ts +309 -0
  146. package/src/Iam/WorkloadIdentityPoolProvider.ts +429 -0
  147. package/src/Iam/index.ts +10 -0
  148. package/src/Kubernetes/Secret.ts +4 -1
  149. package/src/ManagedLustre/Instance.ts +6 -6
  150. package/src/Providers.ts +12 -0
  151. package/src/Run/IamSync.ts +1 -1
  152. package/src/Run/Job.ts +6 -6
  153. package/src/Run/Operations.ts +1 -1
  154. package/src/Run/Service.ts +9 -7
  155. package/src/Run/index.ts +2 -2
  156. package/src/ServiceNetworking/PsaConnection.ts +1 -1
  157. package/src/ServiceUsage/ApiEnable.ts +1 -1
  158. package/src/Sqladmin/Database.ts +1 -1
  159. package/src/Sqladmin/Instance.ts +13 -7
  160. package/src/Sqladmin/Operations.ts +1 -1
  161. package/src/Sqladmin/User.ts +1 -1
  162. package/src/Storage/Bucket.ts +1 -1
  163. package/src/Storage/StorageBucketIamMember.ts +1 -1
  164. package/src/Tags.ts +16 -1
@@ -1,5 +1,5 @@
1
1
  import { ConfigError } from "@distilled.cloud/gcp";
2
- import * as storage from "@distilled.cloud/gcp/storage-v1";
2
+ import * as storage from "@distilled.cloud/gcp/storage_v1";
3
3
  import { Resource } from "alchemy";
4
4
  import { Unowned } from "alchemy/AdoptPolicy";
5
5
  import { isResolved } from "alchemy/Diff";
@@ -1,3 +1,4 @@
1
+ import * as storage from "@distilled.cloud/gcp/storage_v1";
1
2
  import { Resource } from "alchemy";
2
3
  import * as Provider from "alchemy/Provider";
3
4
  import type * as GCP from "../Providers.ts";
@@ -114,5 +115,5 @@ export type StorageBucketIamMemberAttributes = {
114
115
  };
115
116
  export type StorageBucketIamMember = Resource<"GCP.StorageBucketIamMember", StorageBucketIamMemberProps, StorageBucketIamMemberAttributes, never, GCP.Providers>;
116
117
  export declare const StorageBucketIamMember: import("alchemy").ResourceClass<StorageBucketIamMember>;
117
- export declare const StorageBucketIamMemberProvider: () => import("effect/Layer").Layer<Provider.Provider<StorageBucketIamMember>, never, import("@distilled.cloud/gcp").Credentials | import("effect/unstable/http/HttpClient").HttpClient>;
118
+ export declare const StorageBucketIamMemberProvider: () => import("effect/Layer").Layer<Provider.Provider<StorageBucketIamMember>, never, storage.GcpOpContext>;
118
119
  //# sourceMappingURL=StorageBucketIamMember.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StorageBucketIamMember.d.ts","sourceRoot":"","sources":["../../src/Storage/StorageBucketIamMember.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAI7C,OAAO,KAAK,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,+BAA+B,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,SAAS,CAAC,EAAE,+BAA+B,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAC3C,4BAA4B,EAC5B,2BAA2B,EAC3B,gCAAgC,EAChC,KAAK,EACL,GAAG,CAAC,SAAS,CACd,CAAC;AAEF,eAAO,MAAM,sBAAsB,yDAElC,CAAC;AAEF,eAAO,MAAM,8BAA8B,yLA4OxC,CAAC"}
1
+ {"version":3,"file":"StorageBucketIamMember.d.ts","sourceRoot":"","sources":["../../src/Storage/StorageBucketIamMember.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,iCAAiC,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAI7C,OAAO,KAAK,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,+BAA+B,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,SAAS,CAAC,EAAE,+BAA+B,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAC3C,4BAA4B,EAC5B,2BAA2B,EAC3B,gCAAgC,EAChC,KAAK,EACL,GAAG,CAAC,SAAS,CACd,CAAC;AAEF,eAAO,MAAM,sBAAsB,yDAElC,CAAC;AAEF,eAAO,MAAM,8BAA8B,4GA4OxC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { ConfigError } from "@distilled.cloud/gcp";
2
- import * as storage from "@distilled.cloud/gcp/storage-v1";
2
+ import * as storage from "@distilled.cloud/gcp/storage_v1";
3
3
  import { Resource } from "alchemy";
4
4
  import { isResolved } from "alchemy/Diff";
5
5
  import * as Provider from "alchemy/Provider";
package/lib/Tags.d.ts CHANGED
@@ -19,6 +19,8 @@ import { Stage } from "alchemy/Stage";
19
19
  declare const LABEL_KEY_APP = "alchemy_app";
20
20
  declare const LABEL_KEY_STAGE = "alchemy_stage";
21
21
  declare const LABEL_KEY_ID = "alchemy_id";
22
+ /** Normalize an SDK string map by omitting absent values at the boundary. */
23
+ export declare const normalizeStringMap: (value: Record<string, string | undefined> | undefined) => Record<string, string> | undefined;
22
24
  /**
23
25
  * Compute the alchemy-internal label set for a Resource. Merge the
24
26
  * result with user-provided labels (user wins on key collision is
@@ -34,7 +36,7 @@ export declare const gcpInternalLabels: (id: string) => Effect.Effect<{
34
36
  * values matching this stack/stage/id. Used in `read` to decide
35
37
  * adoption ownership.
36
38
  */
37
- export declare const hasAlchemyLabels: (id: string, labels: Record<string, string> | undefined) => Effect.Effect<boolean, never, Stack | Stage>;
39
+ export declare const hasAlchemyLabels: (id: string, labels: Record<string, string | undefined> | undefined) => Effect.Effect<boolean, never, Stack | Stage>;
38
40
  export { LABEL_KEY_APP as ALCHEMY_LABEL_APP, LABEL_KEY_STAGE as ALCHEMY_LABEL_STAGE, LABEL_KEY_ID as ALCHEMY_LABEL_ID, };
39
41
  /**
40
42
  * Compose `[alchemy:...] <userDescription?>`. Pass through to the
package/lib/Tags.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Tags.d.ts","sourceRoot":"","sources":["../src/Tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AAEH,QAAA,MAAM,aAAa,gBAAgB,CAAC;AACpC,QAAA,MAAM,eAAe,kBAAkB,CAAC;AACxC,QAAA,MAAM,YAAY,eAAe,CAAC;AAQlC;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;wBAQ5B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,0GAW3B,CAAC;AAEH,OAAO,EACL,aAAa,IAAI,iBAAiB,EAClC,eAAe,IAAI,mBAAmB,EACtC,YAAY,IAAI,gBAAgB,GACjC,CAAC;AAsBF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,mGAQhC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,+FAStC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,gBAAiB,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAI7E,CAAC"}
1
+ {"version":3,"file":"Tags.d.ts","sourceRoot":"","sources":["../src/Tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AAEH,QAAA,MAAM,aAAa,gBAAgB,CAAC;AACpC,QAAA,MAAM,eAAe,kBAAkB,CAAC;AACxC,QAAA,MAAM,YAAY,eAAe,CAAC;AAQlC,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,UACtB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,KACpD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAOrB,CAAC;AAER;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;wBAQ5B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,sHAc3B,CAAC;AAEH,OAAO,EACL,aAAa,IAAI,iBAAiB,EAClC,eAAe,IAAI,mBAAmB,EACtC,YAAY,IAAI,gBAAgB,GACjC,CAAC;AAsBF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,mGAQhC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,+FAStC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,gBAAiB,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAI7E,CAAC"}
package/lib/Tags.js CHANGED
@@ -24,6 +24,10 @@ const sanitizeLabelValue = (raw) => {
24
24
  const replaced = lowered.replace(/[^a-z0-9_-]/g, "-");
25
25
  return replaced.slice(0, 63);
26
26
  };
27
+ /** Normalize an SDK string map by omitting absent values at the boundary. */
28
+ export const normalizeStringMap = (value) => value === undefined
29
+ ? undefined
30
+ : Object.fromEntries(Object.entries(value).filter((entry) => entry[1] !== undefined));
27
31
  /**
28
32
  * Compute the alchemy-internal label set for a Resource. Merge the
29
33
  * result with user-provided labels (user wins on key collision is
@@ -43,7 +47,11 @@ export const gcpInternalLabels = Effect.fnUntraced(function* (id) {
43
47
  * values matching this stack/stage/id. Used in `read` to decide
44
48
  * adoption ownership.
45
49
  */
46
- export const hasAlchemyLabels = Effect.fnUntraced(function* (id, labels) {
50
+ export const hasAlchemyLabels = Effect.fnUntraced(function* (id,
51
+ // Distilled's generated Kubernetes/GCP map types have index signatures that
52
+ // include `undefined` (`{ [k: string]: string | undefined }`), so accept the
53
+ // wider shape — the equality checks below are unaffected.
54
+ labels) {
47
55
  if (!labels)
48
56
  return false;
49
57
  const expected = yield* gcpInternalLabels(id);
package/lib/Tags.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Tags.js","sourceRoot":"","sources":["../src/Tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AAEH,MAAM,aAAa,GAAG,aAAa,CAAC;AACpC,MAAM,eAAe,GAAG,eAAe,CAAC;AACxC,MAAM,YAAY,GAAG,YAAY,CAAC;AAElC,MAAM,kBAAkB,GAAG,CAAC,GAAW,EAAU,EAAE;IACjD,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACtD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/B,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAU;IACtE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC;IAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC;IAC3B,OAAO;QACL,CAAC,aAAa,CAAC,EAAE,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC;QAC/C,CAAC,eAAe,CAAC,EAAE,kBAAkB,CAAC,KAAK,CAAC;QAC5C,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC,EAAE,CAAC;KACN,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EACzD,EAAU,EACV,MAA0C;IAE1C,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAC9C,OAAO,CACL,MAAM,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC,aAAa,CAAC;QACjD,MAAM,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,eAAe,CAAC;QACrD,MAAM,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC,YAAY,CAAC,CAChD,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,OAAO,EACL,aAAa,IAAI,iBAAiB,EAClC,eAAe,IAAI,mBAAmB,EACtC,YAAY,IAAI,gBAAgB,GACjC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAU,EAAE,CAClD,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAE9D,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAE,KAAa,EAAE,EAAU,EAAU,EAAE,CAC3E,gBAAgB,mBAAmB,CAAC,GAAG,CAAC,UAAU,mBAAmB,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,EAAE,CAAC,GAAG,CAAC;AAEhH;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAC9D,EAAU,EACV,eAAwB;IAExB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC;IAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC;IAC3B,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,eAAe,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EACpE,EAAU,EACV,WAA+B;IAE/B,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC;IAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC;IAC3B,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1D,OAAO,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,WAA+B,EAAsB,EAAE;IACxF,IAAI,CAAC,WAAW;QAAE,OAAO,WAAW,CAAC;IACrC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACtD,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;AACvE,CAAC,CAAC"}
1
+ {"version":3,"file":"Tags.js","sourceRoot":"","sources":["../src/Tags.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microagi/alchemy-gcp",
3
- "version": "0.11.6",
3
+ "version": "0.11.8",
4
4
  "description": "GCP provider for Alchemy v2 (Effect-based IaC). Resources for Project, ServiceAccount, Cluster, NodePool, Compute, ManagedLustre, ServiceUsage, ServiceNetworking, Cloud Run (Service + Job + IAM), Cloud SQL (Instance + Database + User with IAM database authn), Artifact Registry (Docker repositories, standard + remote pull-through caches), Kubernetes (typed Secret + generic SSA Manifest + Helm release), with ADC-backed credentials and target-side IAM bindings.",
5
5
  "keywords": [
6
6
  "alchemy",
@@ -53,18 +53,18 @@
53
53
  "google-auth-library": "^10.4.0"
54
54
  },
55
55
  "peerDependencies": {
56
- "@distilled.cloud/gcp": ">=0.30.2",
57
- "@distilled.cloud/kubernetes": ">=0.30.2",
58
- "alchemy": ">=2.0.0-beta.65",
59
- "effect": ">=4.0.0-beta.100 || >=4.0.0"
56
+ "@distilled.cloud/gcp": ">=1.0.0-rc.4",
57
+ "@distilled.cloud/kubernetes": ">=1.0.0-rc.4",
58
+ "alchemy": ">=2.0.0-beta.72",
59
+ "effect": ">=4.0.0-beta.105 || >=4.0.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@distilled.cloud/gcp": "0.30.2",
63
- "@distilled.cloud/kubernetes": "0.30.2",
62
+ "@distilled.cloud/gcp": "1.0.0-rc.4",
63
+ "@distilled.cloud/kubernetes": "1.0.0-rc.4",
64
64
  "@types/bun": "latest",
65
65
  "@types/node": "latest",
66
- "alchemy": "2.0.0-beta.65",
67
- "effect": ">=4.0.0-beta.100 || >=4.0.0",
66
+ "alchemy": "2.0.0-beta.72",
67
+ "effect": ">=4.0.0-beta.105 || >=4.0.0",
68
68
  "typescript": "^7.0.2"
69
69
  },
70
70
  "publishConfig": {
@@ -1,5 +1,5 @@
1
1
  import { ConfigError } from "@distilled.cloud/gcp";
2
- import * as ar from "@distilled.cloud/gcp/artifactregistry-v1";
2
+ import * as ar from "@distilled.cloud/gcp/artifactregistry_v1";
3
3
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
4
4
  import * as Duration from "effect/Duration";
5
5
  import * as Effect from "effect/Effect";
@@ -1,4 +1,4 @@
1
- import * as ar from "@distilled.cloud/gcp/artifactregistry-v1";
1
+ import * as ar from "@distilled.cloud/gcp/artifactregistry_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { Unowned } from "alchemy/AdoptPolicy";
4
4
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
@@ -10,7 +10,7 @@ import * as Duration from "effect/Duration";
10
10
  import * as Effect from "effect/Effect";
11
11
  import * as Schedule from "effect/Schedule";
12
12
  import type * as GCP from "../Providers.ts";
13
- import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.ts";
13
+ import { gcpInternalLabels, hasAlchemyLabels, normalizeStringMap } from "../Tags.ts";
14
14
  import { makeAwaitOperation } from "./Operations.ts";
15
15
  import type { ArtifactRegistryFormat, ArtifactRegistryMode } from "./Types.ts";
16
16
  import {
@@ -399,7 +399,7 @@ const toAttributes = (
399
399
  sizeBytes: r.sizeBytes,
400
400
  satisfiesPzs: r.satisfiesPzs,
401
401
  satisfiesPzi: r.satisfiesPzi,
402
- labels: { ...(r.labels ?? {}) },
402
+ labels: normalizeStringMap(r.labels) ?? {},
403
403
  createTime: r.createTime ?? "",
404
404
  updateTime: r.updateTime ?? "",
405
405
  });
@@ -441,7 +441,7 @@ export const ArtifactRegistryRepositoryProvider = () =>
441
441
  }
442
442
 
443
443
  const labelDiff = diffTags(
444
- { ...(args.observed.labels ?? {}) },
444
+ normalizeStringMap(args.observed.labels) ?? {},
445
445
  args.desiredLabels,
446
446
  );
447
447
  if (labelDiff.removed.length > 0 || labelDiff.upsert.length > 0) {
@@ -623,7 +623,7 @@ export const ArtifactRegistryRepositoryProvider = () =>
623
623
  const observed = yield* observe(project, location, name);
624
624
  if (!observed) return undefined;
625
625
  const attrs = toAttributes(observed, { project, location, name });
626
- return (yield* hasAlchemyLabels(id, observed.labels))
626
+ return (yield* hasAlchemyLabels(id, normalizeStringMap(observed.labels)))
627
627
  ? attrs
628
628
  : Unowned(attrs);
629
629
  }),
@@ -1,5 +1,5 @@
1
1
  import { ConfigError } from "@distilled.cloud/gcp";
2
- import * as ar from "@distilled.cloud/gcp/artifactregistry-v1";
2
+ import * as ar from "@distilled.cloud/gcp/artifactregistry_v1";
3
3
  import { Resource } from "alchemy";
4
4
  import { isResolved } from "alchemy/Diff";
5
5
  import * as Provider from "alchemy/Provider";
@@ -1,6 +1,6 @@
1
1
  import { ConfigError } from "@distilled.cloud/gcp";
2
- import * as billing from "@distilled.cloud/gcp/cloudbilling-v1";
3
- import * as crm from "@distilled.cloud/gcp/cloudresourcemanager-v3";
2
+ import * as billing from "@distilled.cloud/gcp/cloudbilling_v1";
3
+ import * as crm from "@distilled.cloud/gcp/cloudresourcemanager_v3";
4
4
  import { Resource } from "alchemy";
5
5
  import { Unowned } from "alchemy/AdoptPolicy";
6
6
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
@@ -11,7 +11,7 @@ import { diffTags } from "alchemy/Tags";
11
11
  import * as Duration from "effect/Duration";
12
12
  import * as Effect from "effect/Effect";
13
13
  import * as Schedule from "effect/Schedule";
14
- import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.ts";
14
+ import { gcpInternalLabels, hasAlchemyLabels, normalizeStringMap } from "../Tags.ts";
15
15
  import type * as GCP from "../Providers.ts";
16
16
 
17
17
  /**
@@ -205,7 +205,7 @@ const toAttributes = (
205
205
  state: p.state ?? "ACTIVE",
206
206
  parent: p.parent ?? "",
207
207
  createTime: p.createTime,
208
- labels: { ...(p.labels ?? {}) },
208
+ labels: normalizeStringMap(p.labels) ?? {},
209
209
  // GCP returns `billingAccountName` as a plain string but its format
210
210
  // is always `billingAccounts/{id}` — narrow at the boundary.
211
211
  billingAccount: (billingInfo?.billingAccountName || undefined) as
@@ -387,7 +387,7 @@ export const ProjectProvider = () =>
387
387
  desired: { displayName: string | undefined; labels: Record<string, string> },
388
388
  session: ScopedPlanStatusSession,
389
389
  ) {
390
- const observedLabels = { ...(observed.labels ?? {}) };
390
+ const observedLabels = normalizeStringMap(observed.labels) ?? {};
391
391
  const updateMaskFields: string[] = [];
392
392
  if (desired.displayName !== observed.displayName) {
393
393
  updateMaskFields.push("display_name");
@@ -601,7 +601,7 @@ export const ProjectProvider = () =>
601
601
  // created outside this stack/stage/id. The engine surfaces
602
602
  // `Unowned(attrs)` to the user as "exists but is not ours" —
603
603
  // adoption requires `--adopt` (or `adopt(true)`).
604
- return (yield* hasAlchemyLabels(id, observed.labels))
604
+ return (yield* hasAlchemyLabels(id, normalizeStringMap(observed.labels)))
605
605
  ? attrs
606
606
  : Unowned(attrs);
607
607
  }),
@@ -1,4 +1,4 @@
1
- import * as compute from "@distilled.cloud/gcp/compute-v1";
1
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { Unowned } from "alchemy/AdoptPolicy";
4
4
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
@@ -6,7 +6,7 @@ import { deepEqual, isResolved, somePropsAreDifferent } from "alchemy/Diff";
6
6
  import { createPhysicalName } from "alchemy/PhysicalName";
7
7
  import * as Provider from "alchemy/Provider";
8
8
  import * as Effect from "effect/Effect";
9
- import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.ts";
9
+ import { gcpInternalLabels, hasAlchemyLabels, normalizeStringMap } from "../Tags.ts";
10
10
  import type * as GCP from "../Providers.ts";
11
11
  import { makeAwaitRegionOperation } from "./Operations.ts";
12
12
 
@@ -125,7 +125,7 @@ const toAddressAttributes = (
125
125
  purpose: a.purpose,
126
126
  subnetwork: a.subnetwork,
127
127
  status: a.status,
128
- labels: { ...(a.labels ?? {}) },
128
+ labels: normalizeStringMap(a.labels) ?? {},
129
129
  });
130
130
 
131
131
  export const AddressProvider = () =>
@@ -283,7 +283,7 @@ export const AddressProvider = () =>
283
283
  const observed = yield* observe(project, region, name);
284
284
  if (!observed) return undefined;
285
285
  const attrs = toAddressAttributes(observed, { project, region });
286
- return (yield* hasAlchemyLabels(id, observed.labels))
286
+ return (yield* hasAlchemyLabels(id, normalizeStringMap(observed.labels)))
287
287
  ? attrs
288
288
  : Unowned(attrs);
289
289
  }),
@@ -1,4 +1,4 @@
1
- import * as compute from "@distilled.cloud/gcp/compute-v1";
1
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { Unowned } from "alchemy/AdoptPolicy";
4
4
  import { deepEqual, isResolved, somePropsAreDifferent } from "alchemy/Diff";
@@ -1,4 +1,4 @@
1
- import * as compute from "@distilled.cloud/gcp/compute-v1";
1
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { Unowned } from "alchemy/AdoptPolicy";
4
4
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
@@ -6,7 +6,7 @@ import { deepEqual, isResolved, somePropsAreDifferent } from "alchemy/Diff";
6
6
  import { createPhysicalName } from "alchemy/PhysicalName";
7
7
  import * as Provider from "alchemy/Provider";
8
8
  import * as Effect from "effect/Effect";
9
- import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.ts";
9
+ import { gcpInternalLabels, hasAlchemyLabels, normalizeStringMap } from "../Tags.ts";
10
10
  import type * as GCP from "../Providers.ts";
11
11
  import { makeAwaitRegionOperation } from "./Operations.ts";
12
12
 
@@ -135,7 +135,7 @@ const toForwardingRuleAttributes = (
135
135
  allowPscGlobalAccess: f.allowPscGlobalAccess ?? false,
136
136
  pscConnectionId: f.pscConnectionId,
137
137
  pscConnectionStatus: f.pscConnectionStatus,
138
- labels: { ...(f.labels ?? {}) },
138
+ labels: normalizeStringMap(f.labels) ?? {},
139
139
  });
140
140
 
141
141
  export const ForwardingRuleProvider = () =>
@@ -296,7 +296,7 @@ export const ForwardingRuleProvider = () =>
296
296
  project,
297
297
  region,
298
298
  });
299
- return (yield* hasAlchemyLabels(id, observed.labels))
299
+ return (yield* hasAlchemyLabels(id, normalizeStringMap(observed.labels)))
300
300
  ? attrs
301
301
  : Unowned(attrs);
302
302
  }),
@@ -1,4 +1,4 @@
1
- import * as compute from "@distilled.cloud/gcp/compute-v1";
1
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { Unowned } from "alchemy/AdoptPolicy";
4
4
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
@@ -6,7 +6,7 @@ import { deepEqual, isResolved, somePropsAreDifferent } from "alchemy/Diff";
6
6
  import { createPhysicalName } from "alchemy/PhysicalName";
7
7
  import * as Provider from "alchemy/Provider";
8
8
  import * as Effect from "effect/Effect";
9
- import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.ts";
9
+ import { gcpInternalLabels, hasAlchemyLabels, normalizeStringMap } from "../Tags.ts";
10
10
  import type * as GCP from "../Providers.ts";
11
11
  import { makeAwaitGlobalOperation } from "./Operations.ts";
12
12
 
@@ -133,7 +133,7 @@ const toGlobalAddressAttributes = (
133
133
  purpose: a.purpose,
134
134
  network: a.network,
135
135
  status: a.status,
136
- labels: { ...(a.labels ?? {}) },
136
+ labels: normalizeStringMap(a.labels) ?? {},
137
137
  });
138
138
 
139
139
  export const GlobalAddressProvider = () =>
@@ -278,7 +278,7 @@ export const GlobalAddressProvider = () =>
278
278
  const observed = yield* observe(project, name);
279
279
  if (!observed) return undefined;
280
280
  const attrs = toGlobalAddressAttributes(observed, { project });
281
- return (yield* hasAlchemyLabels(id, observed.labels))
281
+ return (yield* hasAlchemyLabels(id, normalizeStringMap(observed.labels)))
282
282
  ? attrs
283
283
  : Unowned(attrs);
284
284
  }),
@@ -1,4 +1,4 @@
1
- import * as compute from "@distilled.cloud/gcp/compute-v1";
1
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { Unowned } from "alchemy/AdoptPolicy";
4
4
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
@@ -1,5 +1,5 @@
1
1
  import { ConfigError } from "@distilled.cloud/gcp";
2
- import * as compute from "@distilled.cloud/gcp/compute-v1";
2
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
3
3
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
4
4
  import * as Duration from "effect/Duration";
5
5
  import * as Effect from "effect/Effect";
@@ -1,4 +1,4 @@
1
- import * as compute from "@distilled.cloud/gcp/compute-v1";
1
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { isResolved } from "alchemy/Diff";
4
4
  import * as Provider from "alchemy/Provider";
@@ -1,4 +1,4 @@
1
- import * as compute from "@distilled.cloud/gcp/compute-v1";
1
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { isResolved } from "alchemy/Diff";
4
4
  import * as Provider from "alchemy/Provider";
@@ -1,4 +1,4 @@
1
- import * as compute from "@distilled.cloud/gcp/compute-v1";
1
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
4
4
  import { isResolved } from "alchemy/Diff";
@@ -1,4 +1,4 @@
1
- import * as compute from "@distilled.cloud/gcp/compute-v1";
1
+ import * as compute from "@distilled.cloud/gcp/compute_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { Unowned } from "alchemy/AdoptPolicy";
4
4
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
@@ -291,7 +291,7 @@ export const SubnetworkProvider = () =>
291
291
  );
292
292
  const desiredRanges = sortedSecondaryRanges(args.news.secondaryIpRanges);
293
293
  if (!deepEqual(obsRanges, desiredRanges)) {
294
- body.secondaryIpRanges = desiredRanges as ReadonlyArray<compute.SubnetworkSecondaryRange>;
294
+ body.secondaryIpRanges = [...desiredRanges];
295
295
  }
296
296
  if (
297
297
  args.news.privateIpGoogleAccess !== undefined &&
@@ -1,4 +1,4 @@
1
- import * as cont from "@distilled.cloud/gcp/container-v1";
1
+ import * as cont from "@distilled.cloud/gcp/container_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { Unowned } from "alchemy/AdoptPolicy";
4
4
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
@@ -8,7 +8,7 @@ import * as Provider from "alchemy/Provider";
8
8
  import * as Duration from "effect/Duration";
9
9
  import * as Effect from "effect/Effect";
10
10
  import * as Schedule from "effect/Schedule";
11
- import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.ts";
11
+ import { gcpInternalLabels, hasAlchemyLabels, normalizeStringMap } from "../Tags.ts";
12
12
  import type * as GCP from "../Providers.ts";
13
13
  import { type NodePoolProps, toNodeConfigCreateBody } from "./NodePool.ts";
14
14
  import { makeAwaitOperation, qualifyOperationName } from "./Operations.ts";
@@ -297,7 +297,7 @@ const toInitialNodePoolBody = (
297
297
  ): cont.NodePool => ({
298
298
  name: spec.name,
299
299
  initialNodeCount: spec.initialNodeCount,
300
- ...(spec.nodeLocations ? { locations: spec.nodeLocations } : {}),
300
+ ...(spec.nodeLocations ? { locations: [...spec.nodeLocations] } : {}),
301
301
  config: toNodeConfigCreateBody(spec.config, {
302
302
  ...(spec.config.resourceLabels ?? {}),
303
303
  ...clusterInternalLabels,
@@ -320,9 +320,25 @@ const toClusterAttributes = (
320
320
  currentMasterVersion: c.currentMasterVersion,
321
321
  status: c.status,
322
322
  releaseChannel: c.releaseChannel,
323
- resourceLabels: { ...(c.resourceLabels ?? {}) },
323
+ resourceLabels: normalizeStringMap(c.resourceLabels) ?? {},
324
324
  });
325
325
 
326
+ /** Ignore server bookkeeping when diffing; carry its concurrency token on writes. */
327
+ export const clusterMaintenancePolicyUpdate = (
328
+ observed: cont.MaintenancePolicy | undefined,
329
+ desired: ClusterProps["maintenancePolicy"],
330
+ ): cont.MaintenancePolicy | undefined => {
331
+ if (!desired) return undefined;
332
+ const { resourceVersion, ...current } = observed ?? {};
333
+ // Daily window duration is computed by GKE and cannot be configured.
334
+ if (current.window?.dailyMaintenanceWindow) {
335
+ const { duration: _, ...daily } = current.window.dailyMaintenanceWindow;
336
+ current.window = { ...current.window, dailyMaintenanceWindow: daily };
337
+ }
338
+ if (deepEqual(current, desired)) return undefined;
339
+ return { ...desired, ...(resourceVersion ? { resourceVersion } : {}) };
340
+ };
341
+
326
342
  export const ClusterProvider = () =>
327
343
  Provider.effect(
328
344
  Cluster,
@@ -389,15 +405,21 @@ export const ClusterProvider = () =>
389
405
 
390
406
  const syncClusterMaintenance = Effect.fn(function* (args: {
391
407
  fqName: string;
392
- observed: cont.Cluster;
393
408
  news: ClusterProps;
394
409
  session: ScopedPlanStatusSession;
395
410
  }) {
396
411
  if (!args.news.maintenancePolicy) return;
397
- if (deepEqual(args.observed.maintenancePolicy, args.news.maintenancePolicy)) return;
412
+ // Earlier sync steps can update the cluster. Read immediately before
413
+ // setting the policy to obtain its current optimistic-concurrency token.
414
+ const current = yield* getClusters({ name: args.fqName });
415
+ const maintenancePolicy = clusterMaintenancePolicyUpdate(
416
+ current.maintenancePolicy,
417
+ args.news.maintenancePolicy,
418
+ );
419
+ if (!maintenancePolicy) return;
398
420
  const op = yield* setMaintenance({
399
421
  name: args.fqName,
400
- body: { maintenancePolicy: args.news.maintenancePolicy },
422
+ body: { maintenancePolicy },
401
423
  });
402
424
  if (op.name) yield* awaitOperation(qualifyOp(args.fqName, op.name), args.session);
403
425
  });
@@ -412,7 +434,7 @@ export const ClusterProvider = () =>
412
434
  if (deepEqual(args.observed.locations ?? [], args.news.nodeLocations)) return;
413
435
  const op = yield* setLocations({
414
436
  name: args.fqName,
415
- body: { locations: args.news.nodeLocations },
437
+ body: { locations: [...args.news.nodeLocations] },
416
438
  });
417
439
  if (op.name) yield* awaitOperation(qualifyOp(args.fqName, op.name), args.session);
418
440
  });
@@ -587,7 +609,7 @@ export const ClusterProvider = () =>
587
609
  ...(news.initialClusterVersion
588
610
  ? { initialClusterVersion: news.initialClusterVersion }
589
611
  : {}),
590
- ...(news.nodeLocations ? { locations: news.nodeLocations } : {}),
612
+ ...(news.nodeLocations ? { locations: [...news.nodeLocations] } : {}),
591
613
  resourceLabels: desiredLabels,
592
614
  nodePools: [initialPoolBody],
593
615
  },
@@ -628,7 +650,7 @@ export const ClusterProvider = () =>
628
650
  session,
629
651
  });
630
652
  yield* syncClusterAddons({ fqName, observed, news, session });
631
- yield* syncClusterMaintenance({ fqName, observed, news, session });
653
+ yield* syncClusterMaintenance({ fqName, news, session });
632
654
  yield* syncClusterLocations({ fqName, observed, news, session });
633
655
  yield* syncClusterNetworkPolicy({ fqName, observed, news, session });
634
656
  yield* syncClusterLogging({ fqName, observed, news, session });
@@ -667,7 +689,10 @@ export const ClusterProvider = () =>
667
689
  );
668
690
  if (!observed) return undefined;
669
691
  const attrs = toClusterAttributes(observed, { project, location });
670
- return (yield* hasAlchemyLabels(id, observed.resourceLabels))
692
+ return (yield* hasAlchemyLabels(
693
+ id,
694
+ normalizeStringMap(observed.resourceLabels),
695
+ ))
671
696
  ? attrs
672
697
  : Unowned(attrs);
673
698
  }),
@@ -1,4 +1,4 @@
1
- import * as cont from "@distilled.cloud/gcp/container-v1";
1
+ import * as cont from "@distilled.cloud/gcp/container_v1";
2
2
  import { Resource } from "alchemy";
3
3
  import { Unowned } from "alchemy/AdoptPolicy";
4
4
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
@@ -6,7 +6,7 @@ import { deepEqual, isResolved, somePropsAreDifferent } from "alchemy/Diff";
6
6
  import { createPhysicalName } from "alchemy/PhysicalName";
7
7
  import * as Provider from "alchemy/Provider";
8
8
  import * as Effect from "effect/Effect";
9
- import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.ts";
9
+ import { gcpInternalLabels, hasAlchemyLabels, normalizeStringMap } from "../Tags.ts";
10
10
  import type * as GCP from "../Providers.ts";
11
11
  import { makeAwaitOperation, qualifyOperationName } from "./Operations.ts";
12
12
 
@@ -262,7 +262,7 @@ export const nodePoolSizeNeedsSync = (
262
262
  */
263
263
  const toAcceleratorConfig = (
264
264
  accelerators: NodePoolProps["config"]["accelerators"] | undefined,
265
- ): ReadonlyArray<cont.AcceleratorConfig> | undefined =>
265
+ ): cont.AcceleratorConfig[] | undefined =>
266
266
  accelerators?.map((a) => ({
267
267
  acceleratorType: a.type,
268
268
  acceleratorCount: String(a.count),
@@ -293,19 +293,30 @@ export const toNodeConfigCreateBody = (
293
293
  ...(config.imageType ? { imageType: config.imageType } : {}),
294
294
  ...(accelerators ? { accelerators } : {}),
295
295
  ...(config.serviceAccount ? { serviceAccount: config.serviceAccount } : {}),
296
- ...(config.oauthScopes ? { oauthScopes: config.oauthScopes } : {}),
297
- ...(config.taints ? { taints: config.taints } : {}),
296
+ ...(config.oauthScopes ? { oauthScopes: [...config.oauthScopes] } : {}),
297
+ ...(config.taints ? { taints: [...config.taints] } : {}),
298
298
  ...(config.labels ? { labels: config.labels } : {}),
299
299
  resourceLabels: desiredResourceLabels,
300
300
  ...(config.metadata ? { metadata: config.metadata } : {}),
301
- ...(config.tags ? { tags: config.tags } : {}),
301
+ ...(config.tags ? { tags: [...config.tags] } : {}),
302
302
  ...(config.minCpuPlatform ? { minCpuPlatform: config.minCpuPlatform } : {}),
303
303
  ...(config.bootDiskKmsKey ? { bootDiskKmsKey: config.bootDiskKmsKey } : {}),
304
304
  ...(config.sandboxConfig ? { sandboxConfig: config.sandboxConfig } : {}),
305
305
  ...(config.preemptible !== undefined ? { preemptible: config.preemptible } : {}),
306
306
  ...(config.spot !== undefined ? { spot: config.spot } : {}),
307
307
  ...(config.reservationAffinity
308
- ? { reservationAffinity: config.reservationAffinity }
308
+ ? {
309
+ reservationAffinity: {
310
+ consumeReservationType:
311
+ config.reservationAffinity.consumeReservationType,
312
+ ...(config.reservationAffinity.key
313
+ ? { key: config.reservationAffinity.key }
314
+ : {}),
315
+ ...(config.reservationAffinity.values
316
+ ? { values: [...config.reservationAffinity.values] }
317
+ : {}),
318
+ },
319
+ }
309
320
  : {}),
310
321
  ...(config.shieldedInstanceConfig
311
322
  ? { shieldedInstanceConfig: config.shieldedInstanceConfig }
@@ -371,13 +382,13 @@ const toNodePoolUpdateBody = (
371
382
  }
372
383
 
373
384
  if (nc.tags && !deepEqual(oc.tags ?? [], nc.tags)) {
374
- body.tags = { tags: nc.tags };
385
+ body.tags = { tags: [...nc.tags] };
375
386
  }
376
387
  if (nc.labels && !deepEqual(oc.labels ?? {}, nc.labels)) {
377
388
  body.labels = { labels: nc.labels };
378
389
  }
379
390
  if (nc.taints && !deepEqual(oc.taints ?? [], nc.taints)) {
380
- body.taints = { taints: nc.taints };
391
+ body.taints = { taints: [...nc.taints] };
381
392
  }
382
393
  // GKE injects its own `goog-*` resource labels (accelerator type,
383
394
  // provisioning model, …) after create. Treat them as server-managed:
@@ -529,7 +540,7 @@ export const NodePoolProvider = () =>
529
540
  ) {
530
541
  const op = yield* updateNodePools({
531
542
  name: args.fqName,
532
- body: { locations: args.news.nodeLocations },
543
+ body: { locations: [...args.news.nodeLocations] },
533
544
  });
534
545
  if (op.name) yield* awaitOperation(qualifyOp(args.fqName, op.name), args.session);
535
546
  }
@@ -627,7 +638,7 @@ export const NodePoolProvider = () =>
627
638
  nodePool: {
628
639
  name: desiredName,
629
640
  initialNodeCount: createNodeCount,
630
- ...(news.nodeLocations ? { locations: news.nodeLocations } : {}),
641
+ ...(news.nodeLocations ? { locations: [...news.nodeLocations] } : {}),
631
642
  config,
632
643
  ...(news.autoscaling ? { autoscaling: news.autoscaling } : {}),
633
644
  ...(news.management ? { management: news.management } : {}),
@@ -707,7 +718,10 @@ export const NodePoolProvider = () =>
707
718
  );
708
719
  for (const candidate of page?.nodePools ?? []) {
709
720
  if (
710
- yield* hasAlchemyLabels(id, candidate.config?.resourceLabels)
721
+ yield* hasAlchemyLabels(
722
+ id,
723
+ normalizeStringMap(candidate.config?.resourceLabels),
724
+ )
711
725
  ) {
712
726
  observed = candidate;
713
727
  break;
@@ -720,7 +734,10 @@ export const NodePoolProvider = () =>
720
734
  location,
721
735
  clusterName,
722
736
  });
723
- return (yield* hasAlchemyLabels(id, observed.config?.resourceLabels))
737
+ return (yield* hasAlchemyLabels(
738
+ id,
739
+ normalizeStringMap(observed.config?.resourceLabels),
740
+ ))
724
741
  ? attrs
725
742
  : Unowned(attrs);
726
743
  }),
@@ -1,5 +1,5 @@
1
1
  import { ConfigError } from "@distilled.cloud/gcp";
2
- import * as cont from "@distilled.cloud/gcp/container-v1";
2
+ import * as cont from "@distilled.cloud/gcp/container_v1";
3
3
  import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
4
4
  import * as Duration from "effect/Duration";
5
5
  import * as Effect from "effect/Effect";