@intentius/chant-lexicon-gcp 0.41.20 → 0.44.1

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 (563) hide show
  1. package/dist/composites/index.d.ts +2 -0
  2. package/dist/composites/index.d.ts.map +1 -1
  3. package/dist/composites/landing-zone.d.ts +67 -0
  4. package/dist/composites/landing-zone.d.ts.map +1 -0
  5. package/dist/deep-observe-hooks.d.ts +16 -3
  6. package/dist/deep-observe-hooks.d.ts.map +1 -1
  7. package/dist/deep-observe.d.ts +68 -139
  8. package/dist/deep-observe.d.ts.map +1 -1
  9. package/dist/describe-resources.d.ts +27 -3
  10. package/dist/describe-resources.d.ts.map +1 -1
  11. package/dist/governance.d.ts +101 -0
  12. package/dist/governance.d.ts.map +1 -0
  13. package/dist/index.d.ts +4 -2
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/integrity.json +5 -2
  16. package/dist/lint/audit-catalog.d.ts.map +1 -1
  17. package/dist/lint/post-synth/index.d.ts.map +1 -1
  18. package/dist/lint/post-synth/wgc501.d.ts +18 -0
  19. package/dist/lint/post-synth/wgc501.d.ts.map +1 -0
  20. package/dist/lint/post-synth/wgc502.d.ts +10 -0
  21. package/dist/lint/post-synth/wgc502.d.ts.map +1 -0
  22. package/dist/lint/post-synth/wgc503.d.ts +11 -0
  23. package/dist/lint/post-synth/wgc503.d.ts.map +1 -0
  24. package/dist/manifest.json +1 -1
  25. package/dist/okf/index.md +519 -0
  26. package/dist/okf/rules/WGC001.md +15 -0
  27. package/dist/okf/rules/WGC002.md +16 -0
  28. package/dist/okf/rules/WGC003.md +15 -0
  29. package/dist/okf/rules/WGC101.md +16 -0
  30. package/dist/okf/rules/WGC102.md +15 -0
  31. package/dist/okf/rules/WGC103.md +15 -0
  32. package/dist/okf/rules/WGC104.md +15 -0
  33. package/dist/okf/rules/WGC105.md +15 -0
  34. package/dist/okf/rules/WGC106.md +15 -0
  35. package/dist/okf/rules/WGC107.md +15 -0
  36. package/dist/okf/rules/WGC108.md +15 -0
  37. package/dist/okf/rules/WGC109.md +11 -0
  38. package/dist/okf/rules/WGC110.md +15 -0
  39. package/dist/okf/rules/WGC111.md +15 -0
  40. package/dist/okf/rules/WGC112.md +15 -0
  41. package/dist/okf/rules/WGC113.md +16 -0
  42. package/dist/okf/rules/WGC201.md +15 -0
  43. package/dist/okf/rules/WGC202.md +11 -0
  44. package/dist/okf/rules/WGC203.md +11 -0
  45. package/dist/okf/rules/WGC204.md +15 -0
  46. package/dist/okf/rules/WGC301.md +15 -0
  47. package/dist/okf/rules/WGC302.md +15 -0
  48. package/dist/okf/rules/WGC303.md +15 -0
  49. package/dist/okf/rules/WGC401.md +15 -0
  50. package/dist/okf/rules/WGC402.md +15 -0
  51. package/dist/okf/rules/WGC403.md +15 -0
  52. package/dist/okf/rules/WGC501.md +15 -0
  53. package/dist/okf/rules/WGC502.md +11 -0
  54. package/dist/okf/rules/WGC503.md +15 -0
  55. package/dist/okf/types/API.md +21 -0
  56. package/dist/okf/types/APIConfig.md +15 -0
  57. package/dist/okf/types/APIQuotaAdjusterSettings.md +15 -0
  58. package/dist/okf/types/APIQuotaPreference.md +15 -0
  59. package/dist/okf/types/AccessBoundaryPolicy.md +15 -0
  60. package/dist/okf/types/AccessLevel.md +15 -0
  61. package/dist/okf/types/AccessLevelCondition.md +15 -0
  62. package/dist/okf/types/AccessPolicy.md +15 -0
  63. package/dist/okf/types/AddonsConfig.md +15 -0
  64. package/dist/okf/types/AgentPool.md +15 -0
  65. package/dist/okf/types/AiplatformModel.md +15 -0
  66. package/dist/okf/types/AistreamsCluster.md +15 -0
  67. package/dist/okf/types/AlertPolicy.md +15 -0
  68. package/dist/okf/types/AlloydbBackup.md +15 -0
  69. package/dist/okf/types/AlloydbCluster.md +15 -0
  70. package/dist/okf/types/AlloydbInstance.md +15 -0
  71. package/dist/okf/types/AnalyticsAccount.md +15 -0
  72. package/dist/okf/types/AndroidApp.md +15 -0
  73. package/dist/okf/types/AnywhereCache.md +15 -0
  74. package/dist/okf/types/ApigatewayGateway.md +15 -0
  75. package/dist/okf/types/ApigeeEnvironment.md +15 -0
  76. package/dist/okf/types/ApigeeInstance.md +15 -0
  77. package/dist/okf/types/ApihubDeployment.md +15 -0
  78. package/dist/okf/types/ApikeysKey.md +15 -0
  79. package/dist/okf/types/AppConnection.md +15 -0
  80. package/dist/okf/types/AppConnector.md +15 -0
  81. package/dist/okf/types/AppGateway.md +15 -0
  82. package/dist/okf/types/AppProfile.md +15 -0
  83. package/dist/okf/types/Application.md +15 -0
  84. package/dist/okf/types/ArtifactRegistryRepository.md +15 -0
  85. package/dist/okf/types/Assignment.md +15 -0
  86. package/dist/okf/types/Attestor.md +15 -0
  87. package/dist/okf/types/AuthorizationPolicy.md +15 -0
  88. package/dist/okf/types/AuthorizedView.md +15 -0
  89. package/dist/okf/types/AutokeyConfig.md +15 -0
  90. package/dist/okf/types/Automation.md +15 -0
  91. package/dist/okf/types/Autoscaler.md +15 -0
  92. package/dist/okf/types/AutoscalingPolicy.md +15 -0
  93. package/dist/okf/types/BQJob.md +15 -0
  94. package/dist/okf/types/BackendBucket.md +15 -0
  95. package/dist/okf/types/BackendBucketSignedURLKey.md +15 -0
  96. package/dist/okf/types/BackendService.md +15 -0
  97. package/dist/okf/types/BackendServiceSignedURLKey.md +15 -0
  98. package/dist/okf/types/BackupPlanAssociation.md +15 -0
  99. package/dist/okf/types/BackupPolicy.md +15 -0
  100. package/dist/okf/types/BackupdrBackupPlan.md +15 -0
  101. package/dist/okf/types/BackupdrBackupVault.md +15 -0
  102. package/dist/okf/types/Batch.md +15 -0
  103. package/dist/okf/types/BatchJob.md +15 -0
  104. package/dist/okf/types/BatchTask.md +15 -0
  105. package/dist/okf/types/BigLakeCatalog.md +15 -0
  106. package/dist/okf/types/BigLakeDatabase.md +15 -0
  107. package/dist/okf/types/BigLakeTable.md +15 -0
  108. package/dist/okf/types/BigQueryDataPolicy.md +15 -0
  109. package/dist/okf/types/BigQueryDataset.md +15 -0
  110. package/dist/okf/types/BigQueryExport.md +15 -0
  111. package/dist/okf/types/BigQueryTable.md +15 -0
  112. package/dist/okf/types/BigqueryconnectionConnection.md +15 -0
  113. package/dist/okf/types/BigquerydatatransferConfig.md +15 -0
  114. package/dist/okf/types/BigqueryreservationReservation.md +15 -0
  115. package/dist/okf/types/BigtableInstance.md +15 -0
  116. package/dist/okf/types/BigtableTable.md +15 -0
  117. package/dist/okf/types/BillingAccount.md +15 -0
  118. package/dist/okf/types/BinaryauthorizationPolicy.md +15 -0
  119. package/dist/okf/types/Brand.md +15 -0
  120. package/dist/okf/types/BtBackup.md +15 -0
  121. package/dist/okf/types/BtCluster.md +15 -0
  122. package/dist/okf/types/Bucket.md +15 -0
  123. package/dist/okf/types/BucketAccessControl.md +15 -0
  124. package/dist/okf/types/Budget.md +15 -0
  125. package/dist/okf/types/CAPool.md +15 -0
  126. package/dist/okf/types/CapacityCommitment.md +15 -0
  127. package/dist/okf/types/CertificateAuthority.md +15 -0
  128. package/dist/okf/types/CertificateIssuanceConfig.md +15 -0
  129. package/dist/okf/types/CertificateMap.md +15 -0
  130. package/dist/okf/types/CertificateMapEntry.md +15 -0
  131. package/dist/okf/types/CertificateTemplate.md +15 -0
  132. package/dist/okf/types/CertificatemanagerCertificate.md +15 -0
  133. package/dist/okf/types/ClientConnectorService.md +15 -0
  134. package/dist/okf/types/ClientTLSPolicy.md +15 -0
  135. package/dist/okf/types/CloudBatchResourceAllowance.md +15 -0
  136. package/dist/okf/types/CloudFunction.md +15 -0
  137. package/dist/okf/types/CloudRunJob.md +15 -0
  138. package/dist/okf/types/CloudRunService.md +15 -0
  139. package/dist/okf/types/CloudbuildTrigger.md +15 -0
  140. package/dist/okf/types/ClouddmsPrivateConnection.md +15 -0
  141. package/dist/okf/types/CloudidentityGroup.md +15 -0
  142. package/dist/okf/types/CloudidentityMembership.md +15 -0
  143. package/dist/okf/types/CloudidsEndpoint.md +15 -0
  144. package/dist/okf/types/CloudschedulerJob.md +15 -0
  145. package/dist/okf/types/ComposerEnvironment.md +15 -0
  146. package/dist/okf/types/ComputeAddress.md +15 -0
  147. package/dist/okf/types/ComputeDisk.md +15 -0
  148. package/dist/okf/types/ComputeFirewallPolicy.md +15 -0
  149. package/dist/okf/types/ComputeHealthCheck.md +15 -0
  150. package/dist/okf/types/ComputeInstance.md +19 -0
  151. package/dist/okf/types/ComputeNetworkPeering.md +15 -0
  152. package/dist/okf/types/ComputeNodeGroup.md +15 -0
  153. package/dist/okf/types/ComputeReservation.md +15 -0
  154. package/dist/okf/types/ComputeRoute.md +15 -0
  155. package/dist/okf/types/ComputeSnapshot.md +15 -0
  156. package/dist/okf/types/ConfigcontrollerInstance.md +15 -0
  157. package/dist/okf/types/ConnectionProfile.md +15 -0
  158. package/dist/okf/types/ConnectivityTest.md +15 -0
  159. package/dist/okf/types/Connector.md +28 -0
  160. package/dist/okf/types/ConsentStore.md +15 -0
  161. package/dist/okf/types/ConsumerGroup.md +15 -0
  162. package/dist/okf/types/ConsumerQuotaOverride.md +15 -0
  163. package/dist/okf/types/Contact.md +15 -0
  164. package/dist/okf/types/ContainerattachedCluster.md +15 -0
  165. package/dist/okf/types/ConversionWorkspace.md +15 -0
  166. package/dist/okf/types/CryptoKeyVersion.md +15 -0
  167. package/dist/okf/types/CustomClass.md +15 -0
  168. package/dist/okf/types/CustomConstraint.md +15 -0
  169. package/dist/okf/types/CustomRole.md +15 -0
  170. package/dist/okf/types/CustomTargetType.md +15 -0
  171. package/dist/okf/types/DICOMStore.md +15 -0
  172. package/dist/okf/types/DNSAuthorization.md +15 -0
  173. package/dist/okf/types/DNSManagedZone.md +15 -0
  174. package/dist/okf/types/DNSRecordSet.md +15 -0
  175. package/dist/okf/types/Dashboard.md +15 -0
  176. package/dist/okf/types/DataExchange.md +15 -0
  177. package/dist/okf/types/DataLabelingJob.md +15 -0
  178. package/dist/okf/types/DataPolicy.md +15 -0
  179. package/dist/okf/types/DataStore.md +15 -0
  180. package/dist/okf/types/DataStoreTargetSite.md +15 -0
  181. package/dist/okf/types/Database.md +15 -0
  182. package/dist/okf/types/DatacatalogEntryGroup.md +15 -0
  183. package/dist/okf/types/DataflowJob.md +15 -0
  184. package/dist/okf/types/DataformRepository.md +15 -0
  185. package/dist/okf/types/DatafusionInstance.md +15 -0
  186. package/dist/okf/types/DataplexEntryGroup.md +15 -0
  187. package/dist/okf/types/DataplexTask.md +15 -0
  188. package/dist/okf/types/DataprocCluster.md +15 -0
  189. package/dist/okf/types/DataprocJob.md +15 -0
  190. package/dist/okf/types/DataprocNodeGroup.md +15 -0
  191. package/dist/okf/types/DataprocSession.md +15 -0
  192. package/dist/okf/types/DatasetAccess.md +15 -0
  193. package/dist/okf/types/DatastoreIndex.md +15 -0
  194. package/dist/okf/types/DatastreamPrivateConnection.md +15 -0
  195. package/dist/okf/types/DatastreamRoute.md +15 -0
  196. package/dist/okf/types/DefaultObjectAccessControl.md +15 -0
  197. package/dist/okf/types/DefaultSupportedIDPConfig.md +15 -0
  198. package/dist/okf/types/DeidentifyTemplate.md +15 -0
  199. package/dist/okf/types/DeliveryPipeline.md +15 -0
  200. package/dist/okf/types/DenyPolicy.md +15 -0
  201. package/dist/okf/types/DeployPolicy.md +15 -0
  202. package/dist/okf/types/DeploymentResourcePool.md +15 -0
  203. package/dist/okf/types/DeploymentmanagerDeployment.md +15 -0
  204. package/dist/okf/types/Device.md +15 -0
  205. package/dist/okf/types/DeviceRegistry.md +15 -0
  206. package/dist/okf/types/DevicestreamingSession.md +15 -0
  207. package/dist/okf/types/DialogflowAgent.md +15 -0
  208. package/dist/okf/types/DialogflowEntityType.md +15 -0
  209. package/dist/okf/types/DialogflowIntent.md +15 -0
  210. package/dist/okf/types/DialogflowcxAgent.md +15 -0
  211. package/dist/okf/types/DialogflowcxEntityType.md +15 -0
  212. package/dist/okf/types/DialogflowcxIntent.md +15 -0
  213. package/dist/okf/types/DiscoveredService.md +15 -0
  214. package/dist/okf/types/DiscoveredWorkload.md +15 -0
  215. package/dist/okf/types/DiskResourcePolicyAttachment.md +15 -0
  216. package/dist/okf/types/DnsPolicy.md +15 -0
  217. package/dist/okf/types/Document.md +15 -0
  218. package/dist/okf/types/DomainMapping.md +15 -0
  219. package/dist/okf/types/EdgeCacheKeyset.md +15 -0
  220. package/dist/okf/types/EdgeCacheOrigin.md +15 -0
  221. package/dist/okf/types/EdgeCacheService.md +15 -0
  222. package/dist/okf/types/EdgecontainerCluster.md +15 -0
  223. package/dist/okf/types/EdgecontainerNodePool.md +15 -0
  224. package/dist/okf/types/EdgenetworkNetwork.md +15 -0
  225. package/dist/okf/types/EndpointAttachment.md +15 -0
  226. package/dist/okf/types/EndpointPolicy.md +15 -0
  227. package/dist/okf/types/Engine.md +15 -0
  228. package/dist/okf/types/Enrollment.md +15 -0
  229. package/dist/okf/types/Entitlement.md +15 -0
  230. package/dist/okf/types/Entry.md +15 -0
  231. package/dist/okf/types/EntryType.md +15 -0
  232. package/dist/okf/types/Envgroup.md +15 -0
  233. package/dist/okf/types/EnvgroupAttachment.md +15 -0
  234. package/dist/okf/types/EventarcChannel.md +15 -0
  235. package/dist/okf/types/EventarcTrigger.md +15 -0
  236. package/dist/okf/types/ExampleStore.md +15 -0
  237. package/dist/okf/types/ExternalAccessRule.md +15 -0
  238. package/dist/okf/types/ExternalAddress.md +15 -0
  239. package/dist/okf/types/ExternalVPNGateway.md +15 -0
  240. package/dist/okf/types/FHIRStore.md +15 -0
  241. package/dist/okf/types/Feature.md +15 -0
  242. package/dist/okf/types/FeatureMembership.md +15 -0
  243. package/dist/okf/types/Featurestore.md +15 -0
  244. package/dist/okf/types/FeaturestoreEntityType.md +15 -0
  245. package/dist/okf/types/FeaturestoreEntityTypeFeature.md +15 -0
  246. package/dist/okf/types/Federation.md +15 -0
  247. package/dist/okf/types/Feed.md +15 -0
  248. package/dist/okf/types/Field.md +15 -0
  249. package/dist/okf/types/FilestoreBackup.md +15 -0
  250. package/dist/okf/types/FilestoreInstance.md +15 -0
  251. package/dist/okf/types/FilestoreSnapshot.md +15 -0
  252. package/dist/okf/types/FirebaseProject.md +15 -0
  253. package/dist/okf/types/FirebasedatabaseInstance.md +15 -0
  254. package/dist/okf/types/FirebasehostingChannel.md +15 -0
  255. package/dist/okf/types/FirestoreBackupSchedule.md +15 -0
  256. package/dist/okf/types/FirestoreIndex.md +15 -0
  257. package/dist/okf/types/Firewall.md +15 -0
  258. package/dist/okf/types/FirewallPolicyAssociation.md +15 -0
  259. package/dist/okf/types/FirewallPolicyRule.md +15 -0
  260. package/dist/okf/types/FirewallRule.md +15 -0
  261. package/dist/okf/types/FlexTemplateJob.md +15 -0
  262. package/dist/okf/types/FlexibleAppVersion.md +15 -0
  263. package/dist/okf/types/Flow.md +15 -0
  264. package/dist/okf/types/FolderFeed.md +15 -0
  265. package/dist/okf/types/ForwardingRule.md +15 -0
  266. package/dist/okf/types/Fulfillment.md +15 -0
  267. package/dist/okf/types/Function.md +15 -0
  268. package/dist/okf/types/FutureReservation.md +15 -0
  269. package/dist/okf/types/GCPServiceAccount.md +15 -0
  270. package/dist/okf/types/GCPUserAccessBinding.md +15 -0
  271. package/dist/okf/types/GCPolicy.md +15 -0
  272. package/dist/okf/types/GKECluster.md +15 -0
  273. package/dist/okf/types/GRPCRoute.md +15 -0
  274. package/dist/okf/types/GcsFolder.md +15 -0
  275. package/dist/okf/types/GkebackupBackup.md +15 -0
  276. package/dist/okf/types/GkebackupBackupPlan.md +15 -0
  277. package/dist/okf/types/GkehubMembership.md +15 -0
  278. package/dist/okf/types/GkehubNamespace.md +15 -0
  279. package/dist/okf/types/GlobalNetworkEndpoint.md +15 -0
  280. package/dist/okf/types/GlobalNetworkEndpointGroup.md +15 -0
  281. package/dist/okf/types/GoogleChannelConfig.md +15 -0
  282. package/dist/okf/types/GuestPolicy.md +15 -0
  283. package/dist/okf/types/HL7V2Store.md +15 -0
  284. package/dist/okf/types/HMACKey.md +15 -0
  285. package/dist/okf/types/HTTPHealthCheck.md +15 -0
  286. package/dist/okf/types/HTTPRoute.md +15 -0
  287. package/dist/okf/types/HTTPSHealthCheck.md +15 -0
  288. package/dist/okf/types/HealthcareDataset.md +15 -0
  289. package/dist/okf/types/Hub.md +15 -0
  290. package/dist/okf/types/IAMAuditConfig.md +20 -0
  291. package/dist/okf/types/IAMPolicy.md +15 -0
  292. package/dist/okf/types/IAMPolicyMember.md +15 -0
  293. package/dist/okf/types/IdentityAwareProxyClient.md +15 -0
  294. package/dist/okf/types/IdentityplatformConfig.md +15 -0
  295. package/dist/okf/types/Image.md +15 -0
  296. package/dist/okf/types/ImportJob.md +15 -0
  297. package/dist/okf/types/InboundSAMLConfig.md +15 -0
  298. package/dist/okf/types/IndexEndpoint.md +15 -0
  299. package/dist/okf/types/InspectTemplate.md +15 -0
  300. package/dist/okf/types/InstanceAttachment.md +15 -0
  301. package/dist/okf/types/InstanceConfig.md +15 -0
  302. package/dist/okf/types/InstanceEndpoint.md +15 -0
  303. package/dist/okf/types/InstanceGroup.md +15 -0
  304. package/dist/okf/types/InstanceGroupManager.md +15 -0
  305. package/dist/okf/types/InstanceGroupNamedPort.md +15 -0
  306. package/dist/okf/types/InstanceTemplate.md +15 -0
  307. package/dist/okf/types/InterceptDeployment.md +15 -0
  308. package/dist/okf/types/InterceptEndpointGroup.md +15 -0
  309. package/dist/okf/types/Interconnect.md +15 -0
  310. package/dist/okf/types/InterconnectAttachment.md +15 -0
  311. package/dist/okf/types/InternalRange.md +15 -0
  312. package/dist/okf/types/JobTrigger.md +15 -0
  313. package/dist/okf/types/KMSCryptoKey.md +19 -0
  314. package/dist/okf/types/KMSKeyRing.md +15 -0
  315. package/dist/okf/types/KeyHandle.md +15 -0
  316. package/dist/okf/types/KeyRingImportJob.md +15 -0
  317. package/dist/okf/types/LBRouteExtension.md +15 -0
  318. package/dist/okf/types/Lake.md +15 -0
  319. package/dist/okf/types/Lien.md +15 -0
  320. package/dist/okf/types/Link.md +15 -0
  321. package/dist/okf/types/Listing.md +15 -0
  322. package/dist/okf/types/LocationTagBinding.md +15 -0
  323. package/dist/okf/types/LogBucket.md +15 -0
  324. package/dist/okf/types/LogExclusion.md +15 -0
  325. package/dist/okf/types/LogMetric.md +15 -0
  326. package/dist/okf/types/LogSink.md +15 -0
  327. package/dist/okf/types/LogView.md +15 -0
  328. package/dist/okf/types/LogicalView.md +15 -0
  329. package/dist/okf/types/Machine.md +15 -0
  330. package/dist/okf/types/MachineImage.md +15 -0
  331. package/dist/okf/types/ManagedFolder.md +15 -0
  332. package/dist/okf/types/ManagedSSLCertificate.md +15 -0
  333. package/dist/okf/types/ManagedkafkaCluster.md +15 -0
  334. package/dist/okf/types/ManagedkafkaTopic.md +15 -0
  335. package/dist/okf/types/ManagementServer.md +15 -0
  336. package/dist/okf/types/MaterializedView.md +15 -0
  337. package/dist/okf/types/MembershipBinding.md +15 -0
  338. package/dist/okf/types/MemcacheInstance.md +15 -0
  339. package/dist/okf/types/MemorystoreInstance.md +15 -0
  340. package/dist/okf/types/Mesh.md +15 -0
  341. package/dist/okf/types/MetadataStore.md +15 -0
  342. package/dist/okf/types/MetastoreBackup.md +15 -0
  343. package/dist/okf/types/MetastoreService.md +15 -0
  344. package/dist/okf/types/MetricDescriptor.md +15 -0
  345. package/dist/okf/types/MigrationJob.md +15 -0
  346. package/dist/okf/types/MlengineModel.md +15 -0
  347. package/dist/okf/types/MonGroup.md +15 -0
  348. package/dist/okf/types/MonService.md +15 -0
  349. package/dist/okf/types/MonitoredProject.md +15 -0
  350. package/dist/okf/types/MuteConfig.md +15 -0
  351. package/dist/okf/types/NATAddress.md +15 -0
  352. package/dist/okf/types/NetappBackupVault.md +15 -0
  353. package/dist/okf/types/NetworkAttachment.md +15 -0
  354. package/dist/okf/types/NetworkEdgeSecurityService.md +15 -0
  355. package/dist/okf/types/NetworkEndpoint.md +15 -0
  356. package/dist/okf/types/NetworkEndpointGroup.md +15 -0
  357. package/dist/okf/types/NetworkFirewallPolicy.md +15 -0
  358. package/dist/okf/types/NetworkFirewallPolicyAssociation.md +15 -0
  359. package/dist/okf/types/NetworkFirewallPolicyRule.md +15 -0
  360. package/dist/okf/types/NetworkPeeringRoutesConfig.md +15 -0
  361. package/dist/okf/types/NetworkPolicy.md +15 -0
  362. package/dist/okf/types/NetworkservicesGateway.md +15 -0
  363. package/dist/okf/types/Node.md +21 -0
  364. package/dist/okf/types/NodePool.md +15 -0
  365. package/dist/okf/types/NodeTemplate.md +15 -0
  366. package/dist/okf/types/Note.md +15 -0
  367. package/dist/okf/types/NotebookInstance.md +15 -0
  368. package/dist/okf/types/NotebooksEnvironment.md +15 -0
  369. package/dist/okf/types/Notification.md +15 -0
  370. package/dist/okf/types/NotificationChannel.md +15 -0
  371. package/dist/okf/types/NotificationConfig.md +15 -0
  372. package/dist/okf/types/OAuthIDPConfig.md +15 -0
  373. package/dist/okf/types/OSPolicyAssignment.md +15 -0
  374. package/dist/okf/types/Occurrence.md +15 -0
  375. package/dist/okf/types/Organization.md +15 -0
  376. package/dist/okf/types/OrganizationFeed.md +15 -0
  377. package/dist/okf/types/OrganizationSecurityPolicy.md +15 -0
  378. package/dist/okf/types/OrganizationSecurityPolicyAssociation.md +15 -0
  379. package/dist/okf/types/OrganizationSecurityPolicyRule.md +15 -0
  380. package/dist/okf/types/OrgpolicyPolicy.md +15 -0
  381. package/dist/okf/types/PacketMirroring.md +15 -0
  382. package/dist/okf/types/Page.md +15 -0
  383. package/dist/okf/types/Parameter.md +15 -0
  384. package/dist/okf/types/ParameterVersion.md +15 -0
  385. package/dist/okf/types/PartialPolicy.md +15 -0
  386. package/dist/okf/types/PatchDeployment.md +15 -0
  387. package/dist/okf/types/PeeredDNSDomain.md +15 -0
  388. package/dist/okf/types/PerInstanceConfig.md +15 -0
  389. package/dist/okf/types/PhraseSet.md +15 -0
  390. package/dist/okf/types/PlatformPolicy.md +15 -0
  391. package/dist/okf/types/PolicyTag.md +15 -0
  392. package/dist/okf/types/PrivateCloud.md +15 -0
  393. package/dist/okf/types/PrivatecaCertificate.md +15 -0
  394. package/dist/okf/types/Processor.md +15 -0
  395. package/dist/okf/types/ProcessorDefaultVersion.md +15 -0
  396. package/dist/okf/types/ProcessorVersion.md +15 -0
  397. package/dist/okf/types/ProjectDefaultConfig.md +15 -0
  398. package/dist/okf/types/ProjectFeed.md +15 -0
  399. package/dist/okf/types/ProjectMetadata.md +15 -0
  400. package/dist/okf/types/PubSubSnapshot.md +15 -0
  401. package/dist/okf/types/PubSubSubscription.md +15 -0
  402. package/dist/okf/types/PubSubTopic.md +15 -0
  403. package/dist/okf/types/PubsubliteReservation.md +15 -0
  404. package/dist/okf/types/PubsubliteTopic.md +15 -0
  405. package/dist/okf/types/RecaptchaenterpriseFirewallPolicy.md +15 -0
  406. package/dist/okf/types/RecaptchaenterpriseKey.md +15 -0
  407. package/dist/okf/types/Recognizer.md +15 -0
  408. package/dist/okf/types/RedisCluster.md +15 -0
  409. package/dist/okf/types/RedisInstance.md +15 -0
  410. package/dist/okf/types/RegionAutoscaler.md +15 -0
  411. package/dist/okf/types/RegionDiskResourcePolicyAttachment.md +15 -0
  412. package/dist/okf/types/RegionNetworkEndpointGroup.md +15 -0
  413. package/dist/okf/types/RegionPerInstanceConfig.md +15 -0
  414. package/dist/okf/types/RegionSSLPolicy.md +15 -0
  415. package/dist/okf/types/RegionalEndpoint.md +15 -0
  416. package/dist/okf/types/ResourceBundle.md +15 -0
  417. package/dist/okf/types/ResourcePolicy.md +15 -0
  418. package/dist/okf/types/ResourcemanagerFolder.md +15 -0
  419. package/dist/okf/types/ResourcemanagerPolicy.md +15 -0
  420. package/dist/okf/types/ResourcemanagerProject.md +15 -0
  421. package/dist/okf/types/ResponsePolicy.md +15 -0
  422. package/dist/okf/types/ResponsePolicyRule.md +15 -0
  423. package/dist/okf/types/Restore.md +15 -0
  424. package/dist/okf/types/RestorePlan.md +15 -0
  425. package/dist/okf/types/Router.md +15 -0
  426. package/dist/okf/types/RouterInterface.md +15 -0
  427. package/dist/okf/types/RouterNAT.md +15 -0
  428. package/dist/okf/types/RouterPeer.md +15 -0
  429. package/dist/okf/types/Routine.md +15 -0
  430. package/dist/okf/types/Runtime.md +15 -0
  431. package/dist/okf/types/RuntimeTemplate.md +15 -0
  432. package/dist/okf/types/SQLDatabase.md +15 -0
  433. package/dist/okf/types/SQLInstance.md +21 -0
  434. package/dist/okf/types/SQLUser.md +15 -0
  435. package/dist/okf/types/SSHPublicKey.md +15 -0
  436. package/dist/okf/types/SSLCert.md +15 -0
  437. package/dist/okf/types/SSLCertificate.md +15 -0
  438. package/dist/okf/types/SSLPolicy.md +15 -0
  439. package/dist/okf/types/SavedQuery.md +15 -0
  440. package/dist/okf/types/Schema.md +15 -0
  441. package/dist/okf/types/Scope.md +15 -0
  442. package/dist/okf/types/ScopeRBACRoleBinding.md +15 -0
  443. package/dist/okf/types/SecretCiphertext.md +15 -0
  444. package/dist/okf/types/SecretManagerSecret.md +15 -0
  445. package/dist/okf/types/SecretManagerSecretVersion.md +15 -0
  446. package/dist/okf/types/SecuresourcemanagerInstance.md +15 -0
  447. package/dist/okf/types/SecuresourcemanagerRepository.md +15 -0
  448. package/dist/okf/types/SecurityPolicy.md +15 -0
  449. package/dist/okf/types/ServerTLSPolicy.md +15 -0
  450. package/dist/okf/types/ServiceAccountKey.md +15 -0
  451. package/dist/okf/types/ServiceAttachment.md +15 -0
  452. package/dist/okf/types/ServiceBinding.md +15 -0
  453. package/dist/okf/types/ServiceConnectionPolicy.md +15 -0
  454. package/dist/okf/types/ServiceIdentity.md +15 -0
  455. package/dist/okf/types/ServiceLevelObjective.md +15 -0
  456. package/dist/okf/types/ServicePerimeter.md +19 -0
  457. package/dist/okf/types/ServicePerimeterResource.md +15 -0
  458. package/dist/okf/types/ServiceProjectAttachment.md +15 -0
  459. package/dist/okf/types/ServiceSplitTraffic.md +15 -0
  460. package/dist/okf/types/ServicedirectoryEndpoint.md +15 -0
  461. package/dist/okf/types/ServicedirectoryNamespace.md +15 -0
  462. package/dist/okf/types/ServicedirectoryService.md +15 -0
  463. package/dist/okf/types/ServicenetworkingConnection.md +15 -0
  464. package/dist/okf/types/ServiceusageService.md +15 -0
  465. package/dist/okf/types/Settings.md +15 -0
  466. package/dist/okf/types/SharedVPCHostProject.md +15 -0
  467. package/dist/okf/types/SharedVPCServiceProject.md +15 -0
  468. package/dist/okf/types/Site.md +15 -0
  469. package/dist/okf/types/Source.md +15 -0
  470. package/dist/okf/types/SourcerepoRepository.md +15 -0
  471. package/dist/okf/types/SpannerBackupSchedule.md +15 -0
  472. package/dist/okf/types/SpannerDatabase.md +15 -0
  473. package/dist/okf/types/SpannerInstance.md +15 -0
  474. package/dist/okf/types/Spoke.md +15 -0
  475. package/dist/okf/types/StandardAppVersion.md +15 -0
  476. package/dist/okf/types/StorageBucket.md +21 -0
  477. package/dist/okf/types/StoragetransferJob.md +15 -0
  478. package/dist/okf/types/StoredInfoType.md +15 -0
  479. package/dist/okf/types/Stream.md +15 -0
  480. package/dist/okf/types/Subnet.md +15 -0
  481. package/dist/okf/types/Subnetwork.md +15 -0
  482. package/dist/okf/types/Subscription.md +15 -0
  483. package/dist/okf/types/SyncAuthorization.md +15 -0
  484. package/dist/okf/types/TCPRoute.md +15 -0
  485. package/dist/okf/types/TLSRoute.md +15 -0
  486. package/dist/okf/types/Tag.md +15 -0
  487. package/dist/okf/types/TagBinding.md +15 -0
  488. package/dist/okf/types/TagKey.md +15 -0
  489. package/dist/okf/types/TagTemplate.md +15 -0
  490. package/dist/okf/types/TagValue.md +15 -0
  491. package/dist/okf/types/Target.md +15 -0
  492. package/dist/okf/types/TargetGRPCProxy.md +15 -0
  493. package/dist/okf/types/TargetHTTPProxy.md +15 -0
  494. package/dist/okf/types/TargetHTTPSProxy.md +15 -0
  495. package/dist/okf/types/TargetInstance.md +15 -0
  496. package/dist/okf/types/TargetPool.md +15 -0
  497. package/dist/okf/types/TargetSSLProxy.md +15 -0
  498. package/dist/okf/types/TargetTCPProxy.md +15 -0
  499. package/dist/okf/types/TargetVPNGateway.md +15 -0
  500. package/dist/okf/types/TasksQueue.md +15 -0
  501. package/dist/okf/types/Taxonomy.md +15 -0
  502. package/dist/okf/types/Tenant.md +15 -0
  503. package/dist/okf/types/TenantDefaultSupportedIDPConfig.md +15 -0
  504. package/dist/okf/types/TenantInboundSAMLConfig.md +15 -0
  505. package/dist/okf/types/TenantOAuthIDPConfig.md +15 -0
  506. package/dist/okf/types/Tensorboard.md +15 -0
  507. package/dist/okf/types/URLMap.md +15 -0
  508. package/dist/okf/types/UptimeCheckConfig.md +15 -0
  509. package/dist/okf/types/User.md +15 -0
  510. package/dist/okf/types/VPCNetwork.md +15 -0
  511. package/dist/okf/types/VPNGateway.md +15 -0
  512. package/dist/okf/types/VPNTunnel.md +15 -0
  513. package/dist/okf/types/VertexaiDataset.md +15 -0
  514. package/dist/okf/types/VertexaiEndpoint.md +15 -0
  515. package/dist/okf/types/VertexaiIndex.md +15 -0
  516. package/dist/okf/types/VirtualMachine.md +15 -0
  517. package/dist/okf/types/VmwareengineNetwork.md +15 -0
  518. package/dist/okf/types/VmwareengineNetworkPeering.md +15 -0
  519. package/dist/okf/types/VpnConnection.md +15 -0
  520. package/dist/okf/types/WasmPlugin.md +15 -0
  521. package/dist/okf/types/WebApp.md +15 -0
  522. package/dist/okf/types/Webhook.md +15 -0
  523. package/dist/okf/types/WorkerPool.md +15 -0
  524. package/dist/okf/types/Workflow.md +15 -0
  525. package/dist/okf/types/WorkflowTemplate.md +15 -0
  526. package/dist/okf/types/WorkflowsExecution.md +15 -0
  527. package/dist/okf/types/WorkforcePool.md +15 -0
  528. package/dist/okf/types/WorkforcePoolProvider.md +15 -0
  529. package/dist/okf/types/Workload.md +15 -0
  530. package/dist/okf/types/WorkloadIdentityPool.md +15 -0
  531. package/dist/okf/types/WorkloadIdentityPoolProvider.md +15 -0
  532. package/dist/okf/types/Workstation.md +15 -0
  533. package/dist/okf/types/WorkstationCluster.md +15 -0
  534. package/dist/okf/types/WorkstationConfig.md +15 -0
  535. package/dist/okf/types/Zone.md +19 -0
  536. package/dist/rules/wgc501.ts +73 -0
  537. package/dist/rules/wgc502.ts +41 -0
  538. package/dist/rules/wgc503.ts +56 -0
  539. package/dist/serializer.d.ts +12 -0
  540. package/dist/serializer.d.ts.map +1 -1
  541. package/package.json +2 -2
  542. package/src/composites/index.ts +6 -0
  543. package/src/composites/landing-zone.test.ts +67 -0
  544. package/src/composites/landing-zone.ts +173 -0
  545. package/src/deep-observe-hooks.ts +87 -21
  546. package/src/deep-observe.test.ts +158 -13
  547. package/src/deep-observe.ts +143 -142
  548. package/src/describe-resources.test.ts +46 -1
  549. package/src/describe-resources.ts +64 -13
  550. package/src/governance.test.ts +59 -0
  551. package/src/governance.ts +179 -0
  552. package/src/index.ts +10 -0
  553. package/src/lifecycle-integration.test.ts +3 -3
  554. package/src/lint/audit-catalog.ts +5 -0
  555. package/src/lint/post-synth/index.ts +6 -0
  556. package/src/lint/post-synth/wgc501.test.ts +87 -0
  557. package/src/lint/post-synth/wgc501.ts +73 -0
  558. package/src/lint/post-synth/wgc502.test.ts +64 -0
  559. package/src/lint/post-synth/wgc502.ts +41 -0
  560. package/src/lint/post-synth/wgc503.test.ts +77 -0
  561. package/src/lint/post-synth/wgc503.ts +56 -0
  562. package/src/plugin.test.ts +4 -1
  563. package/src/serializer.ts +6 -1
@@ -1,132 +1,60 @@
1
1
  /**
2
- * GCP deep observation (#1087) — the GCP row of the deep-observe contract
3
- * (#1014), reusing the k8s row (#1076) rather than writing a second one, per
4
- * the issue and #1173's own per-row checklist: "A Config Connector resource
5
- * *is* a Kubernetes object, so it carries managed-fields for the same
6
- * reason. Share the hooks rather than writing a second implementation."
2
+ * GCP deep observation (#1087, re-landed on direct REST by #1209/#1210) — the
3
+ * GCP row of the deep-observe contract (#1014).
7
4
  *
8
- * ## A Config Connector CR is a Kubernetes object
5
+ * ## The reader is the applier's transport, pointed at reads
9
6
  *
10
- * `kubectl get <kind>.<group> -o json` against a Config Connector-enabled
11
- * cluster (`./describe-resources.ts`'s own transport, reused here) returns a
12
- * real Kubernetes API object: `metadata.managedFields`, `status`,
13
- * `metadata.{uid,resourceVersion,generation,creationTimestamp}` are all
14
- * present for the identical reason they're present on a Deployment — the API
15
- * server that served the read is the same kind of API server. The epic's own
16
- * table lists `metadata.managedFields` under GCP's "field noise" to prune; it
17
- * is the opposite of noise, and it is available here for exactly the reason
18
- * chant #1076 reads it on the k8s row.
7
+ * chant applies GCP cluster-free over direct REST (#706), and since #1209 it
8
+ * observes the same way: every GET here is built by the same
9
+ * `ResourceMapper.plan().getUrl` the applier writes through (see
10
+ * ./api/read-client.ts), so reader and applier cannot disagree about where a
11
+ * resource lives. `GCP_ENDPOINT_URL` redirects the whole reader at a local
12
+ * floci-gcp; unset means real GCP, exactly as it does for the applier.
13
+ * Coverage is the applier's own dispatch table — a kind with no mapper cannot
14
+ * be applied either, and reports NOT-OBSERVED with `unsupported-kind` (#1089)
15
+ * rather than being dropped.
19
16
  *
20
- * So this reader reuses, unchanged, from `@intentius/chant/managed-fields`:
17
+ * ## Two shapes, one diff
21
18
  *
22
- * - `K8S_OBJECT_ENVELOPE_PRUNE_PATTERNS` — the generic Kubernetes object
23
- * envelope (`status`, `metadata.{uid,resourceVersion,generation,
24
- * creationTimestamp,managedFields,selfLink}`).
25
- * - `k8sListMapOrderKey` — Kubernetes' own list-map-key conventions, needed
26
- * because some CNRM kinds embed genuinely k8s-shaped substructures (Cloud
27
- * Run's `RunService` wraps a Knative pod spec with
28
- * `containers`/`env`/`ports`, keyed the same way a Deployment's are).
29
- * - `buildOwnershipSets`/`pruneByOwnership` — the managed-fields ownership
30
- * walk itself: chant #1076's actual contribution, and the piece this row
31
- * exists to reuse rather than reimplement.
19
+ * The declared side is a CNRM spec as a declarable authors it (`{ metadata:
20
+ * { name }, location, storageClass }`); the REST APIs return their own shapes
21
+ * (`name` is usually the full resource path, a bucket's `iamConfiguration`
22
+ * nests what CNRM flattens, a subscription's `topic` is a path where CNRM
23
+ * writes `topicRef`). Diffed raw, every such field drifts twice: once as
24
+ * `declared -> <absent>` and once as `<undeclared> -> live`.
25
+ * {@link restToCnrmShape} plus the per-kind {@link CNRM_REFINERS} put the live
26
+ * payload into the declared vocabulary before the diff runs — the same move
27
+ * the AWS row makes with its per-type `toModel` (#1207/#1269), and it lives
28
+ * next to the read for the same reason: translation is the price of the
29
+ * richer read, and it does not belong inside the diff.
32
30
  *
33
- * These live in core, not in the k8s lexicon, specifically so this file can
34
- * reuse them without adding a dependency on the k8s lexicon package or (never,
35
- * per the issue) on `@intentius/chant-k8s-client` — this reader shells
36
- * `kubectl` exactly like `./describe-resources.ts` already does. Chant
37
- * #1177/#1180 kept GCP off the typed client deliberately ("a separate
38
- * lexicon and a separate decision"); this row does not revisit that.
31
+ * ## Noise is a static table, not an ownership walk
39
32
  *
40
- * ## The GCP twist: who is "chant" on this path?
41
- *
42
- * Chant #1076's rule treats a field as always-diffable when *any* chant field
43
- * manager (`chant`, `chant:<stack>` — chant #1075's SSA identity) owns it.
44
- * That identity is only ever set by the k8s lexicon's typed client, applying
45
- * with an explicit `--field-manager`. GCP has no equivalent apply activity:
46
- * every gcp example's own deploy script (e.g.
47
- * `examples/cockroachdb-multi-region-gke/scripts/deploy.sh`) runs plain
48
- * `kubectl apply -f dist/*.yaml` — classic client-side apply, no
49
- * `--server-side`, no `--field-manager`. kubectl's own hardcoded default
50
- * field manager for that command is `kubectl-client-side-apply`, identical
51
- * to what a human's `kubectl apply -f their-own-file.yaml` would record.
52
- * **There is no field-manager name on GCP's real deploy path that
53
- * distinguishes "chant applied this" from "a person applied this".**
54
- * (Config Connector's own controller is distinguishable — its reconciler
55
- * records itself as `cnrm-controller-manager`, per the k8s-config-connector
56
- * source's own `ControllerManagedFieldManager` constant — just chant isn't,
57
- * on this path.)
58
- *
59
- * That sounds like it breaks question 1 of the three-question rule
60
- * (`isChantManager`) below. It doesn't, because question 3 already covers
61
- * it: chant's own kubectl apply always applies the *exact* built manifest, so
62
- * any field chant's own most recent apply set is, by construction, also in
63
- * `declaredRoot` (`props`) on the very next read — chant never authors a
64
- * field it does not also declare. Working through what that means per field:
65
- *
66
- * - A field only chant's own applies have ever touched: not recognized as
67
- * `chantOwned` (its manager is `kubectl-client-side-apply`, not `chant`),
68
- * but foreign-owned *and* declared → contested → kept diffable anyway.
69
- * Same outcome as being chant-owned would have been.
70
- * - A field CNRM's controller sets and chant never declares: foreign-owned,
71
- * undeclared → pruned. Correct regardless of whether "chant" is recognized.
72
- * - A field a human sets by hand (`kubectl edit`, or their own `kubectl apply
73
- * -f`) that chant *does* declare: foreign-owned (manager is `kubectl-edit`
74
- * or `kubectl-client-side-apply`) and declared → contested → surfaces as
75
- * drift. This is #1087's acceptance criterion 1.
76
- *
77
- * `isGcpChantFieldManager` below still checks the `chant`/`chant:<stack>`
78
- * family, so a future GCP apply path that *does* route through server-side
79
- * apply with an explicit chant field manager (matching the k8s lexicon's own
80
- * path) is recognized with no change needed here. On today's plain-apply
81
- * path it is inert — proven inert by this module's own test suite (the
82
- * "managers-specific case") — and the contested-field rule (question 3) is
83
- * what actually keeps GCP's drift semantics correct without it.
84
- *
85
- * ## What's genuinely GCP-specific
86
- *
87
- * - No typed operation surface (chant #1177's `operationFor` is a k8s
88
- * lexicon/typed-client concept, generated from cluster discovery this
89
- * reader never touches) — `./describe-resources.ts`'s `deriveGVK` stands in.
90
- * - CNRM's own observed-state annotations (`./deep-observe-hooks.ts`'s
91
- * `gcpDeepNormalizationHooks`) — bookkeeping the controller writes into
92
- * `metadata.annotations` for GCP-side properties the CRD schema has no
93
- * field for. See that module's doc for why the list is narrow.
94
- *
95
- * ## Deliberately out of scope
96
- *
97
- * `status.conditions` staleness as its own signal — the issue's own
98
- * "Proposed" section floats this as worth *deciding*, not worth doing here.
99
- * `status` is pruned outright (matching k8s, and the acceptance criteria),
100
- * and a CNRM projection lagging real GCP state is a genuine gap, but
101
- * detecting it means reading the actual GCP API, not the CR — a different
102
- * read than this contract's "normalize what Kubernetes reports" scope.
103
- * Flagged, not papered over.
33
+ * The kubectl-era reader pruned by CNRM `metadata.managedFields`. A REST
34
+ * payload never says who wrote a field, so the noise rules are static
35
+ * (./deep-observe-hooks.ts): server-assigned names, chant's own ownership
36
+ * labels, CNRM-only declared fields, and per-kind provider defaults gated on
37
+ * "source never declared it". Core applies the same hooks to both trees.
104
38
  *
105
39
  * ## The build-path boundary
106
40
  *
107
- * This module imports `./describe-resources.ts` for the live kubectl
108
- * transport, which imports `node:child_process`. `gcpPlugin.ts` reaches this
109
- * file only via `await import("./deep-observe")` inside
110
- * `observeResourcesDeep` — never statically — the same way it already
111
- * dynamic-imports `describeResources`/`exportResources`, so `chant build`
112
- * never resolves a process-spawning module just to synthesize a template.
113
- * `deepNormalizationHooks` is plain data with no such dependency
114
- * (`./deep-observe-hooks.ts`) and is imported statically from `plugin.ts`,
115
- * because core normalizes the *declared* tree with it whether or not a
116
- * cluster read ever happens.
41
+ * `gcpPlugin.ts` reaches this file only via `await import("./deep-observe")`
42
+ * inside `observeResourcesDeep` — never statically — so `chant build` never
43
+ * resolves the live transport just to synthesize a template.
44
+ * `deepNormalizationHooks` is plain data (./deep-observe-hooks.ts) and is
45
+ * imported statically from `plugin.ts`, because core normalizes the
46
+ * *declared* tree with it whether or not a live read ever happens.
117
47
  */
118
48
 
119
49
  import type {
120
- DeepNormalizationHooks,
121
50
  DeepObservationResult,
122
51
  DeepResourceObservation,
123
52
  UnobservedEntity,
124
53
  } from "@intentius/chant/lexicon";
125
54
  import { deepObservation, normalizeDeepProperties } from "@intentius/chant/deep-observation";
126
55
  import { hasOwnershipMarker, type ChannelKeys } from "@intentius/chant/ownership";
127
- import { deriveGVK } from "./describe-resources";
56
+ import { deriveGVK, manifestProjectAnnotations, resolveReadProject } from "./describe-resources";
128
57
  import { getResource, mapperForKind, GcpReadError, isNotFound, type GcpReadClientOptions } from "./api/read-client";
129
- import { resolveGcpProject } from "./op/activities/gcp-apply";
130
58
  import { gcpDeepNormalizationHooks } from "./deep-observe-hooks";
131
59
 
132
60
  /** The labels the applier stamps — see describe-resources.ts. */
@@ -152,38 +80,24 @@ export interface GcpDeepObserveOptions {
152
80
  }
153
81
 
154
82
  /**
155
- * Reshape a GCP REST body into the CNRM shape the declared source is written in.
156
- *
157
- * This is the half of the port that is not transport (#1209). chant's GCP
158
- * source declares Config Connector custom resources — `{ metadata: { name },
159
- * spec: { location, storageClass } }` — while the REST APIs return their own
160
- * flat shape, `{ name, location, storageClass }`. Diffing one against the other
161
- * makes every field drift twice: once as `spec.location: US -> <absent>` and
162
- * again as `location: <undeclared> -> US`.
163
- *
164
- * Verified against floci-gcp before this existed: a bucket that matched its
165
- * declaration exactly reported **7 property drifts**, all of them shape.
166
- *
167
- * chant has met this before. #1207 records it for AWS: Cloud Control returns
168
- * the CloudFormation resource model and lines up for free, while the EC2 API
169
- * returns the EC2 shape and needs mapping onto the declared shape before the
170
- * diff can compare. GCP is the EC2 case.
171
- *
172
- * The mapping is CNRM's own convention rather than a per-kind table: identity
173
- * and labels live under `metadata`, everything else is `spec`. That holds for
174
- * every kind the applier can write, and a per-kind table would be a second
175
- * place to forget a field.
83
+ * Reshape a GCP REST body into the shape the declared props are written in:
84
+ * identity and labels under `metadata`, everything else at the root — a CNRM
85
+ * spec as a chant declarable authors it (`new StorageBucket({ metadata,
86
+ * location, storageClass })`). Kind-specific vocabulary differences on top of
87
+ * it are {@link CNRM_REFINERS}' job. Verified against floci-gcp: diffed raw, a
88
+ * bucket that matched its declaration exactly reported every field as drift
89
+ * twice, once per shape.
176
90
  */
177
91
  export function restToCnrmShape(body: Record<string, unknown>): Record<string, unknown> {
178
92
  const metadata: Record<string, unknown> = {};
179
- const spec: Record<string, unknown> = {};
93
+ const rest: Record<string, unknown> = {};
180
94
  for (const [key, value] of Object.entries(body)) {
181
95
  if (key === "name" || key === "labels" || key === "annotations") metadata[key] = value;
182
- else spec[key] = value;
96
+ else rest[key] = value;
183
97
  }
184
98
  return {
185
99
  ...(Object.keys(metadata).length ? { metadata } : {}),
186
- ...(Object.keys(spec).length ? { spec } : {}),
100
+ ...rest,
187
101
  };
188
102
  }
189
103
 
@@ -195,19 +109,105 @@ function propertiesTreeOf(obj: Record<string, unknown>): Record<string, unknown>
195
109
  return rest;
196
110
  }
197
111
 
112
+ /** What a refiner may need beyond the tree: the read's project, and the REST
113
+ * payload's own full resource name (`projects/p/locations/l/services/s`). */
114
+ interface RefineContext {
115
+ project: string;
116
+ restName?: string;
117
+ }
118
+
119
+ type CnrmTree = Record<string, unknown> & { metadata?: Record<string, unknown> };
120
+
121
+ /**
122
+ * Per-kind REST -> CNRM vocabulary mapping, applied after the generic
123
+ * {@link restToCnrmShape}. Each entry translates exactly the fields where the
124
+ * REST API and the CNRM schema disagree about names or nesting — kept next to
125
+ * the kind, like the applier's forward mapping in gcp-apply.ts, so adding a
126
+ * field means touching one kind in one file per direction.
127
+ */
128
+ const CNRM_REFINERS: Record<string, (tree: CnrmTree, ctx: RefineContext) => void> = {
129
+ StorageBucket(tree) {
130
+ // CNRM flattens GCS's `iamConfiguration` envelope.
131
+ const iam = tree.iamConfiguration as
132
+ | { uniformBucketLevelAccess?: { enabled?: unknown }; publicAccessPrevention?: unknown }
133
+ | undefined;
134
+ if (iam) {
135
+ if (iam.uniformBucketLevelAccess?.enabled !== undefined) {
136
+ tree.uniformBucketLevelAccess = iam.uniformBucketLevelAccess.enabled;
137
+ }
138
+ if (iam.publicAccessPrevention !== undefined) tree.publicAccessPrevention = iam.publicAccessPrevention;
139
+ delete tree.iamConfiguration;
140
+ }
141
+ // `lifecycle.rule` -> `lifecycleRule`, the inverse of bucketInsertBody.
142
+ const lifecycle = tree.lifecycle as { rule?: unknown } | undefined;
143
+ if (lifecycle) {
144
+ if (lifecycle.rule !== undefined) tree.lifecycleRule = lifecycle.rule;
145
+ delete tree.lifecycle;
146
+ }
147
+ },
148
+ PubSubSubscription(tree, ctx) {
149
+ const topic = tree.topic;
150
+ if (typeof topic !== "string") return;
151
+ // The declared side writes a `topicRef`; a same-project path maps to the
152
+ // `name` form the manifest overwhelmingly uses, anything else to `external`.
153
+ const prefix = `projects/${ctx.project}/topics/`;
154
+ tree.topicRef = topic.startsWith(prefix) ? { name: topic.slice(prefix.length) } : { external: topic };
155
+ delete tree.topic;
156
+ },
157
+ SecretManagerSecret(tree) {
158
+ // CNRM spells automatic replication as a boolean; the REST API as `{}`.
159
+ const replication = tree.replication as { automatic?: unknown } | undefined;
160
+ if (replication && typeof replication.automatic === "object" && replication.automatic !== null) {
161
+ replication.automatic = true;
162
+ }
163
+ },
164
+ IAMServiceAccount(tree, ctx) {
165
+ // The REST identity is the derived email; the declared name is the account
166
+ // id it was derived from (see gcpServiceAccountMapper).
167
+ const name = tree.metadata?.name;
168
+ if (typeof name === "string" && name.endsWith(`@${ctx.project}.iam.gserviceaccount.com`)) {
169
+ tree.metadata!.name = name.slice(0, name.indexOf("@"));
170
+ }
171
+ },
172
+ RunService(tree, ctx) {
173
+ // The v2 payload carries no `location` field — it lives in the resource
174
+ // name. The declared side writes it as `location`.
175
+ const m = ctx.restName ? /\/locations\/([^/]+)\//.exec(ctx.restName) : null;
176
+ if (m) tree.location = m[1];
177
+ },
178
+ };
179
+
180
+ /**
181
+ * A REST payload as a CNRM-shaped property tree, in the declared side's
182
+ * vocabulary. The generic reshape runs first, then the full resource path is
183
+ * shortened to the declared `metadata.name` (`projects/p/topics/t` -> `t`),
184
+ * then the kind's own refiner translates what the two schemas name
185
+ * differently.
186
+ */
187
+ export function toCnrmTree(kind: string, body: Record<string, unknown>, ctx: RefineContext): Record<string, unknown> {
188
+ const tree = restToCnrmShape(propertiesTreeOf(body)) as CnrmTree;
189
+ const restName = typeof body.name === "string" ? body.name : undefined;
190
+ const name = tree.metadata?.name;
191
+ if (typeof name === "string" && name.includes("/")) {
192
+ tree.metadata!.name = name.slice(name.lastIndexOf("/") + 1);
193
+ }
194
+ CNRM_REFINERS[kind]?.(tree, { ...ctx, restName });
195
+ return tree as Record<string, unknown>;
196
+ }
197
+
198
198
  /**
199
- * Read the live property tree for each declared entity via `kubectl get
200
- * <kind>.<group> -o json`, pruning by `metadata.managedFields` (see the
201
- * module doc). Reuses `./describe-resources.ts`'s exact cluster-binding
202
- * resolution and kubectl mechanics — the binding check (chant #1100) still
203
- * refuses before any resource is touched, and a connect failure still
204
- * becomes NOT-OBSERVED for every declared entity rather than an empty result.
199
+ * Read the live property tree for each declared entity over the applier's
200
+ * REST transport, normalized into the declared CNRM shape (see the module
201
+ * doc). A connect failure becomes NOT-OBSERVED for every declared entity
202
+ * rather than an empty result, and a 404 is a real absence the thin read
203
+ * already reports.
205
204
  */
206
205
  export async function observeResourcesDeepGcp(options: GcpDeepObserveOptions): Promise<DeepObservationResult> {
207
206
  const resources: Record<string, DeepResourceObservation> = {};
208
207
  const unobserved: Record<string, UnobservedEntity> = {};
209
208
 
210
209
  const endpoint = process.env.GCP_ENDPOINT_URL;
210
+ const manifestProjects = manifestProjectAnnotations(options.buildOutput);
211
211
 
212
212
  const reads = [...options.entities].map(async ([entityName, { entityType, props }]) => {
213
213
  const gvk = deriveGVK(entityType);
@@ -236,7 +236,7 @@ export async function observeResourcesDeepGcp(options: GcpDeepObserveOptions): P
236
236
  let client: GcpReadClientOptions;
237
237
  try {
238
238
  client = {
239
- project: resolveGcpProject({ kind: gvk.kind, metadata }),
239
+ project: resolveReadProject(gvk.kind, name, metadata, manifestProjects),
240
240
  ...(endpoint ? { endpoint } : {}),
241
241
  };
242
242
  } catch (err) {
@@ -267,8 +267,9 @@ export async function observeResourcesDeepGcp(options: GcpDeepObserveOptions): P
267
267
 
268
268
  resources[entityName] = {
269
269
  type: entityType,
270
- physicalId: (obj.id as string | undefined) ?? (obj.selfLink as string | undefined),
271
- properties: normalizeDeepProperties(restToCnrmShape(propertiesTreeOf(obj)), {
270
+ physicalId:
271
+ (obj.id as string | undefined) ?? (obj.selfLink as string | undefined) ?? (obj.name as string | undefined),
272
+ properties: normalizeDeepProperties(toCnrmTree(gvk.kind, obj, { project: client.project }), {
272
273
  entityType,
273
274
  side: "live",
274
275
  // The static table is the whole prune now — there is no per-resource
@@ -23,7 +23,7 @@ const bucket = (name: string) => ({
23
23
  props: { metadata: { name }, spec: { location: "US" } },
24
24
  });
25
25
 
26
- async function read(entities: ReturnType<typeof makeEntities>, opts: { owned?: boolean } = {}) {
26
+ async function read(entities: ReturnType<typeof makeEntities>, opts: { owned?: boolean; buildOutput?: string } = {}) {
27
27
  return describeResources({
28
28
  environment: "local",
29
29
  buildOutput: "",
@@ -92,6 +92,51 @@ describe("gcp describeResources — direct REST (#1209)", () => {
92
92
  expect(fetchMock).not.toHaveBeenCalled();
93
93
  });
94
94
 
95
+ test("kinds resolve through the serializer's GVK map, not naive recasing", async () => {
96
+ // The real entity type is `GCP::Pubsub::Topic` (the generated barrel's
97
+ // casing); a naive `${service}${shortKind}` derives `PubsubTopic`, which
98
+ // matches no mapper — 4 of the 6 appliable kinds were invisible this way.
99
+ fetchMock.mockResolvedValue(reply(200, { name: "projects/my-project/topics/t" }));
100
+ const out = await read(
101
+ makeEntities([{ name: "t", entityType: "GCP::Pubsub::Topic", props: { metadata: { name: "t" } } }]),
102
+ );
103
+ expect(out.unobserved?.t).toBeUndefined();
104
+ expect(out.resources.t).toBeDefined();
105
+ expect(fetchMock.mock.calls[0][0]).toBe("http://localhost:4588/v1/projects/my-project/topics/t");
106
+ });
107
+
108
+ test("the project falls back to the built manifest's merged annotation", async () => {
109
+ // `defaultAnnotations` is a separate declarable the serializer merges at
110
+ // synthesis — the entity's own props never carry it.
111
+ delete process.env.GOOGLE_CLOUD_PROJECT;
112
+ fetchMock.mockResolvedValue(reply(200, { id: "b/b" }));
113
+ const buildOutput = [
114
+ "apiVersion: storage.cnrm.cloud.google.com/v1beta1",
115
+ "kind: StorageBucket",
116
+ "metadata:",
117
+ " name: b",
118
+ " annotations:",
119
+ " cnrm.cloud.google.com/project-id: manifest-project",
120
+ "spec:",
121
+ " location: US",
122
+ ].join("\n");
123
+ const out = await read(
124
+ makeEntities([{ name: "b", entityType: "GCP::Storage::Bucket", props: { metadata: { name: "b" } } }]),
125
+ { buildOutput },
126
+ );
127
+ expect(out.unobserved?.b).toBeUndefined();
128
+ expect(out.resources.b).toBeDefined();
129
+ });
130
+
131
+ test("no project from any source is a no-binding hole, never a guess", async () => {
132
+ delete process.env.GOOGLE_CLOUD_PROJECT;
133
+ const out = await read(
134
+ makeEntities([{ name: "b", entityType: "GCP::Storage::Bucket", props: { metadata: { name: "b" } } }]),
135
+ );
136
+ expect(out.unobserved?.b?.reason).toBe("no-binding");
137
+ expect(fetchMock).not.toHaveBeenCalled();
138
+ });
139
+
95
140
  test("reads concurrently, where the kubectl path was one spawn after another", async () => {
96
141
  fetchMock.mockResolvedValue(reply(200, {}));
97
142
  const entities = makeEntities([
@@ -40,7 +40,8 @@ import type { ObservationResult, ResourceMetadata, UnobservedEntity } from "@int
40
40
  import { observation } from "@intentius/chant/observation";
41
41
  import { hasOwnershipMarker, classifyOwnership, type ChannelKeys } from "@intentius/chant/ownership";
42
42
  import { getResource, mapperForKind, GcpReadError, isNotFound, type GcpReadClientOptions } from "./api/read-client";
43
- import { resolveGcpProject } from "./op/activities/gcp-apply";
43
+ import { resolveGcpProject, parseManifest } from "./op/activities/gcp-apply";
44
+ import { resolveGVK } from "./serializer";
44
45
 
45
46
  /**
46
47
  * chant's ownership marker as GCP labels.
@@ -75,19 +76,67 @@ interface GcpRestResponse {
75
76
  }
76
77
 
77
78
  /**
78
- * Mirror of `lexicons/gcp/src/serializer.ts:deriveGVKFromType` — keeping the
79
- * derivation logic local so describeResources can compute the kubectl resource
80
- * name without importing serializer internals.
79
+ * The CNRM group/kind for an entity type, resolved through the serializer's
80
+ * own GVK map so the reader and the manifest agree on the kind's casing —
81
+ * `GCP::Pubsub::Topic` is `PubSubTopic` in CNRM and in the applier's mapper
82
+ * table, while a naive `${service}${shortKind}` concatenation would produce
83
+ * `PubsubTopic` and silently miss the mapper for 4 of the 6 appliable kinds.
81
84
  */
82
85
  export function deriveGVK(entityType: string): { group: string; kind: string } | null {
83
- const parts = entityType.split("::");
84
- if (parts.length !== 3 || parts[0] !== "GCP") return null;
85
- const service = parts[1].toLowerCase();
86
- const shortKind = parts[2];
87
- return {
88
- group: `${service}.cnrm.cloud.google.com`,
89
- kind: `${parts[1]}${shortKind}`,
90
- };
86
+ const resolved = resolveGVK(entityType);
87
+ if (!resolved) return null;
88
+ return { group: resolved.apiVersion.split("/")[0], kind: resolved.kind };
89
+ }
90
+
91
+ /**
92
+ * The `cnrm.cloud.google.com/project-id` annotations in the built manifest,
93
+ * keyed `kind/name`.
94
+ *
95
+ * The declared entities the observe paths receive are discovery output, and a
96
+ * project-wide `defaultAnnotations({"cnrm.cloud.google.com/project-id": …})`
97
+ * is a separate declarable the serializer merges into each document at
98
+ * synthesis — the entity's own props never see it. The applier resolves its
99
+ * project from the manifest for exactly that reason, so the readers do too:
100
+ * without this, every entity relying on the default annotation reports
101
+ * `no-binding` unless the shell happens to export GOOGLE_CLOUD_PROJECT.
102
+ */
103
+ export function manifestProjectAnnotations(buildOutput: string | undefined): Map<string, string> {
104
+ const out = new Map<string, string>();
105
+ if (!buildOutput) return out;
106
+ try {
107
+ for (const doc of parseManifest(buildOutput, "<build output>")) {
108
+ const project = doc.metadata?.annotations?.["cnrm.cloud.google.com/project-id"];
109
+ if (doc.kind && doc.metadata?.name && typeof project === "string") {
110
+ out.set(`${doc.kind}/${doc.metadata.name}`, project);
111
+ }
112
+ }
113
+ } catch {
114
+ // An unparsable build output resolves nothing — per-entity annotations and
115
+ // GOOGLE_CLOUD_PROJECT still apply, and a truly unresolvable project is
116
+ // still reported as `no-binding` per entity.
117
+ }
118
+ return out;
119
+ }
120
+
121
+ /**
122
+ * The project a read should target: `GOOGLE_CLOUD_PROJECT` / the entity's own
123
+ * annotation (via `resolveGcpProject`, the applier's rule), then the built
124
+ * manifest's merged annotation. Throws the applier's own error when nothing
125
+ * resolves, so the `no-binding` detail names both knobs.
126
+ */
127
+ export function resolveReadProject(
128
+ kind: string,
129
+ name: string,
130
+ metadata: { annotations?: Record<string, string> } | undefined,
131
+ manifestProjects: Map<string, string>,
132
+ ): string {
133
+ try {
134
+ return resolveGcpProject({ kind, metadata });
135
+ } catch (err) {
136
+ const fromManifest = manifestProjects.get(`${kind}/${name}`);
137
+ if (fromManifest) return fromManifest;
138
+ throw err;
139
+ }
91
140
  }
92
141
 
93
142
  function pruneUndefined<T extends Record<string, unknown>>(obj: T): Record<string, unknown> {
@@ -144,6 +193,8 @@ export async function describeResources(options: {
144
193
  // `describe-stack-resources` returns no tags.
145
194
  let warnedOwnership = false;
146
195
 
196
+ const manifestProjects = manifestProjectAnnotations(options.buildOutput);
197
+
147
198
  const reads = [...options.entities].map(async ([entityName, { entityType, props }]) => {
148
199
  const gvk = deriveGVK(entityType);
149
200
  if (!gvk) {
@@ -179,7 +230,7 @@ export async function describeResources(options: {
179
230
  let client: GcpReadClientOptions;
180
231
  try {
181
232
  client = {
182
- project: resolveGcpProject({ kind: gvk.kind, metadata }),
233
+ project: resolveReadProject(gvk.kind, name, metadata, manifestProjects),
183
234
  ...(endpoint ? { endpoint } : {}),
184
235
  };
185
236
  } catch (err) {
@@ -0,0 +1,59 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { landingZoneConfig, FOUNDATION_FOLDERS } from "./governance";
3
+
4
+ describe("landingZoneConfig (#791)", () => {
5
+ test("the default is the recommended foundation", () => {
6
+ const cfg = landingZoneConfig();
7
+ expect(Object.keys(cfg.folders)).toEqual(["Security", "Infrastructure", "Sandbox", "Workloads"]);
8
+ expect(cfg.organization.orgPolicies).toEqual(["disable-sa-key-creation", "skip-default-network"]);
9
+ expect(Object.keys(cfg.orgPolicies).sort()).toEqual(["disable-sa-key-creation", "skip-default-network"]);
10
+ expect(cfg.orgPolicies["disable-sa-key-creation"].constraint).toBe("iam.disableServiceAccountKeyCreation");
11
+ expect(cfg.auditSinks).toBeUndefined();
12
+ });
13
+
14
+ test("custom folders and projects merge over the foundation (brownfield: partial trees work)", () => {
15
+ const cfg = landingZoneConfig({
16
+ folders: {
17
+ Workloads: {
18
+ children: { Prod: { projects: [{ name: "checkout" }] } },
19
+ },
20
+ },
21
+ });
22
+ // Same-name key wins over the foundation's Workloads…
23
+ expect(cfg.folders.Workloads.children?.Prod.projects?.[0].name).toBe("checkout");
24
+ // …while the rest of the foundation persists.
25
+ expect(cfg.folders.Security).toEqual(FOUNDATION_FOLDERS.Security);
26
+
27
+ const partial = landingZoneConfig({ foundation: false, folders: { Legacy: {} }, rootOrgPolicies: [] });
28
+ expect(Object.keys(partial.folders)).toEqual(["Legacy"]);
29
+ expect(partial.organization.orgPolicies).toBeUndefined();
30
+ expect(partial.orgPolicies).toEqual({});
31
+ });
32
+
33
+ test("allowedLocations adds a root resource-location org policy", () => {
34
+ const cfg = landingZoneConfig({ allowedLocations: ["in:eu-locations", "europe-west1"] });
35
+ expect(cfg.organization.orgPolicies).toContain("resource-location-restriction");
36
+ const policy = cfg.orgPolicies["resource-location-restriction"];
37
+ expect(policy.constraint).toBe("gcp.resourceLocations");
38
+ expect(JSON.stringify(policy.rules)).toContain("europe-west1");
39
+ });
40
+
41
+ test("auditAllServices declares the audit sink", () => {
42
+ const cfg = landingZoneConfig({ auditAllServices: true });
43
+ expect(cfg.auditSinks?.auditConfig).toEqual({
44
+ service: "allServices",
45
+ logTypes: ["ADMIN_READ", "DATA_READ", "DATA_WRITE"],
46
+ });
47
+ });
48
+
49
+ test("only attached org policies are emitted; attaching an undefined policy throws", () => {
50
+ const cfg = landingZoneConfig({
51
+ orgPolicies: { unused: { constraint: "compute.disableSerialPortAccess", rules: [{ enforce: "TRUE" }] } },
52
+ });
53
+ expect(cfg.orgPolicies.unused).toBeUndefined();
54
+
55
+ expect(() => landingZoneConfig({ folders: { Security: { orgPolicies: ["nope"] } } })).toThrowError(
56
+ 'org policy "nope" is attached but not defined',
57
+ );
58
+ });
59
+ });