@intentius/chant-lexicon-gcp 0.124.32 → 0.124.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codegen/generate.js +7 -3
- package/dist/composites/catalog.d.ts.map +1 -1
- package/dist/composites/catalog.js +7 -1
- package/dist/composites/cloud-run-service.d.ts +7 -3
- package/dist/composites/cloud-run-service.d.ts.map +1 -1
- package/dist/composites/cloud-run-service.js +8 -4
- package/dist/deep-observe.js +1 -1
- package/dist/describe-resources.d.ts +4 -3
- package/dist/describe-resources.d.ts.map +1 -1
- package/dist/describe-resources.js +8 -7
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +487 -487
- package/dist/health.d.ts +42 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +87 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/integrity.json +4 -4
- package/dist/manifest.json +1 -1
- package/dist/meta.json +1848 -481
- package/dist/okf/types/API.md +2 -0
- package/dist/okf/types/APIConfig.md +3 -0
- package/dist/okf/types/APIQuotaAdjusterSettings.md +2 -0
- package/dist/okf/types/APIQuotaPreference.md +2 -0
- package/dist/okf/types/AccessBoundaryPolicy.md +2 -0
- package/dist/okf/types/AccessLevel.md +2 -0
- package/dist/okf/types/AccessLevelCondition.md +1 -0
- package/dist/okf/types/AccessPolicy.md +4 -0
- package/dist/okf/types/AddonsConfig.md +1 -0
- package/dist/okf/types/AgentPool.md +2 -0
- package/dist/okf/types/AiplatformModel.md +2 -0
- package/dist/okf/types/AistreamsCluster.md +2 -0
- package/dist/okf/types/AlertPolicy.md +2 -0
- package/dist/okf/types/AlloydbBackup.md +9 -0
- package/dist/okf/types/AlloydbCluster.md +5 -0
- package/dist/okf/types/AlloydbInstance.md +10 -0
- package/dist/okf/types/AnalyticsAccount.md +2 -0
- package/dist/okf/types/AndroidApp.md +4 -0
- package/dist/okf/types/AnywhereCache.md +2 -0
- package/dist/okf/types/ApigatewayGateway.md +3 -0
- package/dist/okf/types/ApigeeEnvironment.md +5 -0
- package/dist/okf/types/ApigeeInstance.md +2 -0
- package/dist/okf/types/ApihubDeployment.md +2 -0
- package/dist/okf/types/ApikeysKey.md +2 -0
- package/dist/okf/types/AppConnection.md +1 -0
- package/dist/okf/types/AppConnector.md +2 -0
- package/dist/okf/types/AppGateway.md +3 -0
- package/dist/okf/types/AppProfile.md +3 -0
- package/dist/okf/types/Application.md +2 -0
- package/dist/okf/types/ArtifactRegistryRepository.md +4 -0
- package/dist/okf/types/Assignment.md +2 -0
- package/dist/okf/types/Attestor.md +2 -0
- package/dist/okf/types/AuthorizationPolicy.md +4 -0
- package/dist/okf/types/AuthorizedView.md +2 -0
- package/dist/okf/types/AutokeyConfig.md +2 -0
- package/dist/okf/types/Automation.md +2 -0
- package/dist/okf/types/Autoscaler.md +3 -0
- package/dist/okf/types/AutoscalingPolicy.md +2 -0
- package/dist/okf/types/BQJob.md +3 -0
- package/dist/okf/types/BackendBucket.md +3 -0
- package/dist/okf/types/BackendBucketSignedURLKey.md +1 -0
- package/dist/okf/types/BackendService.md +5 -0
- package/dist/okf/types/BackendServiceSignedURLKey.md +1 -0
- package/dist/okf/types/BackupPlanAssociation.md +2 -0
- package/dist/okf/types/BackupPolicy.md +2 -0
- package/dist/okf/types/BackupdrBackupPlan.md +2 -0
- package/dist/okf/types/BackupdrBackupVault.md +2 -0
- package/dist/okf/types/Batch.md +2 -0
- package/dist/okf/types/BatchJob.md +2 -0
- package/dist/okf/types/BatchTask.md +3 -0
- package/dist/okf/types/BigLakeCatalog.md +2 -0
- package/dist/okf/types/BigLakeDatabase.md +2 -0
- package/dist/okf/types/BigLakeTable.md +2 -0
- package/dist/okf/types/BigQueryDataPolicy.md +2 -0
- package/dist/okf/types/BigQueryDataset.md +6 -0
- package/dist/okf/types/BigQueryExport.md +2 -0
- package/dist/okf/types/BigQueryTable.md +11 -0
- package/dist/okf/types/BigqueryconnectionConnection.md +2 -0
- package/dist/okf/types/BigquerydatatransferConfig.md +2 -0
- package/dist/okf/types/BigqueryreservationReservation.md +2 -0
- package/dist/okf/types/BigtableInstance.md +1 -0
- package/dist/okf/types/BigtableTable.md +2 -0
- package/dist/okf/types/BillingAccount.md +2 -0
- package/dist/okf/types/BinaryauthorizationPolicy.md +3 -0
- package/dist/okf/types/Brand.md +2 -0
- package/dist/okf/types/BtBackup.md +2 -0
- package/dist/okf/types/BtCluster.md +2 -0
- package/dist/okf/types/Bucket.md +2 -0
- package/dist/okf/types/BucketAccessControl.md +3 -0
- package/dist/okf/types/Budget.md +2 -0
- package/dist/okf/types/CAPool.md +1 -0
- package/dist/okf/types/CapacityCommitment.md +5 -0
- package/dist/okf/types/CertificateAuthority.md +7 -0
- package/dist/okf/types/CertificateIssuanceConfig.md +2 -0
- package/dist/okf/types/CertificateMap.md +3 -0
- package/dist/okf/types/CertificateMapEntry.md +4 -0
- package/dist/okf/types/CertificateTemplate.md +3 -0
- package/dist/okf/types/CertificatemanagerCertificate.md +1 -0
- package/dist/okf/types/ClientConnectorService.md +2 -0
- package/dist/okf/types/ClientTLSPolicy.md +3 -0
- package/dist/okf/types/CloudBatchResourceAllowance.md +2 -0
- package/dist/okf/types/CloudFunction.md +4 -0
- package/dist/okf/types/CloudRunJob.md +13 -0
- package/dist/okf/types/CloudRunService.md +13 -0
- package/dist/okf/types/CloudbuildTrigger.md +4 -0
- package/dist/okf/types/ClouddmsPrivateConnection.md +2 -0
- package/dist/okf/types/CloudidentityGroup.md +5 -0
- package/dist/okf/types/CloudidentityMembership.md +6 -0
- package/dist/okf/types/CloudidsEndpoint.md +1 -0
- package/dist/okf/types/CloudschedulerJob.md +5 -0
- package/dist/okf/types/ComposerEnvironment.md +2 -0
- package/dist/okf/types/ComputeAddress.md +4 -0
- package/dist/okf/types/ComputeDisk.md +9 -0
- package/dist/okf/types/ComputeFirewallPolicy.md +7 -0
- package/dist/okf/types/ComputeHealthCheck.md +4 -0
- package/dist/okf/types/ComputeInstance.md +8 -0
- package/dist/okf/types/ComputeNetworkPeering.md +3 -0
- package/dist/okf/types/ComputeNodeGroup.md +3 -0
- package/dist/okf/types/ComputeReservation.md +6 -0
- package/dist/okf/types/ComputeRoute.md +3 -0
- package/dist/okf/types/ComputeSnapshot.md +7 -0
- package/dist/okf/types/ConfigcontrollerInstance.md +3 -0
- package/dist/okf/types/ConnectionProfile.md +2 -0
- package/dist/okf/types/ConnectivityTest.md +2 -0
- package/dist/okf/types/Connector.md +3 -0
- package/dist/okf/types/ConsentStore.md +1 -0
- package/dist/okf/types/ConsumerGroup.md +2 -0
- package/dist/okf/types/ConsumerQuotaOverride.md +2 -0
- package/dist/okf/types/Contact.md +2 -0
- package/dist/okf/types/ContainerattachedCluster.md +8 -0
- package/dist/okf/types/ConversionWorkspace.md +2 -0
- package/dist/okf/types/CryptoKeyVersion.md +5 -0
- package/dist/okf/types/CustomClass.md +2 -0
- package/dist/okf/types/CustomConstraint.md +2 -0
- package/dist/okf/types/CustomRole.md +3 -0
- package/dist/okf/types/CustomTargetType.md +2 -0
- package/dist/okf/types/DICOMStore.md +2 -0
- package/dist/okf/types/DNSAuthorization.md +2 -0
- package/dist/okf/types/DNSManagedZone.md +3 -0
- package/dist/okf/types/DNSRecordSet.md +1 -0
- package/dist/okf/types/Dashboard.md +2 -0
- package/dist/okf/types/DataExchange.md +2 -0
- package/dist/okf/types/DataLabelingJob.md +2 -0
- package/dist/okf/types/DataPolicy.md +2 -0
- package/dist/okf/types/DataStore.md +2 -0
- package/dist/okf/types/DataStoreTargetSite.md +2 -0
- package/dist/okf/types/Database.md +2 -0
- package/dist/okf/types/DatacatalogEntryGroup.md +2 -0
- package/dist/okf/types/DataflowJob.md +4 -0
- package/dist/okf/types/DataformRepository.md +2 -0
- package/dist/okf/types/DatafusionInstance.md +10 -0
- package/dist/okf/types/DataplexEntryGroup.md +2 -0
- package/dist/okf/types/DataplexTask.md +2 -0
- package/dist/okf/types/DataprocCluster.md +2 -0
- package/dist/okf/types/DataprocJob.md +2 -0
- package/dist/okf/types/DataprocNodeGroup.md +2 -0
- package/dist/okf/types/DataprocSession.md +2 -0
- package/dist/okf/types/DatasetAccess.md +2 -0
- package/dist/okf/types/DatastoreIndex.md +2 -0
- package/dist/okf/types/DatastreamPrivateConnection.md +2 -0
- package/dist/okf/types/DatastreamRoute.md +2 -0
- package/dist/okf/types/DefaultObjectAccessControl.md +5 -0
- package/dist/okf/types/DefaultSupportedIDPConfig.md +2 -0
- package/dist/okf/types/DeidentifyTemplate.md +4 -0
- package/dist/okf/types/DeliveryPipeline.md +2 -0
- package/dist/okf/types/DenyPolicy.md +2 -0
- package/dist/okf/types/DeployPolicy.md +2 -0
- package/dist/okf/types/DeploymentResourcePool.md +2 -0
- package/dist/okf/types/DeploymentmanagerDeployment.md +4 -0
- package/dist/okf/types/Device.md +8 -0
- package/dist/okf/types/DeviceRegistry.md +1 -0
- package/dist/okf/types/DevicestreamingSession.md +2 -0
- package/dist/okf/types/DialogflowAgent.md +2 -0
- package/dist/okf/types/DialogflowEntityType.md +2 -0
- package/dist/okf/types/DialogflowIntent.md +3 -0
- package/dist/okf/types/DialogflowcxAgent.md +3 -0
- package/dist/okf/types/DialogflowcxEntityType.md +2 -0
- package/dist/okf/types/DialogflowcxIntent.md +2 -0
- package/dist/okf/types/DiscoveredService.md +2 -0
- package/dist/okf/types/DiscoveredWorkload.md +2 -0
- package/dist/okf/types/DiskResourcePolicyAttachment.md +1 -0
- package/dist/okf/types/DnsPolicy.md +1 -0
- package/dist/okf/types/Document.md +2 -0
- package/dist/okf/types/DomainMapping.md +2 -0
- package/dist/okf/types/EdgeCacheKeyset.md +1 -0
- package/dist/okf/types/EdgeCacheOrigin.md +1 -0
- package/dist/okf/types/EdgeCacheService.md +1 -0
- package/dist/okf/types/EdgecontainerCluster.md +9 -0
- package/dist/okf/types/EdgecontainerNodePool.md +4 -0
- package/dist/okf/types/EdgenetworkNetwork.md +4 -0
- package/dist/okf/types/EndpointAttachment.md +2 -0
- package/dist/okf/types/EndpointPolicy.md +3 -0
- package/dist/okf/types/Engine.md +2 -0
- package/dist/okf/types/Enrollment.md +2 -0
- package/dist/okf/types/Entitlement.md +2 -0
- package/dist/okf/types/Entry.md +2 -0
- package/dist/okf/types/EntryType.md +2 -0
- package/dist/okf/types/Envgroup.md +2 -0
- package/dist/okf/types/EnvgroupAttachment.md +2 -0
- package/dist/okf/types/EventarcChannel.md +2 -0
- package/dist/okf/types/EventarcTrigger.md +5 -0
- package/dist/okf/types/ExampleStore.md +2 -0
- package/dist/okf/types/ExternalAccessRule.md +2 -0
- package/dist/okf/types/ExternalAddress.md +2 -0
- package/dist/okf/types/ExternalVPNGateway.md +3 -0
- package/dist/okf/types/FHIRStore.md +2 -0
- package/dist/okf/types/Feature.md +4 -0
- package/dist/okf/types/FeatureMembership.md +1 -0
- package/dist/okf/types/Featurestore.md +2 -0
- package/dist/okf/types/FeaturestoreEntityType.md +5 -0
- package/dist/okf/types/FeaturestoreEntityTypeFeature.md +5 -0
- package/dist/okf/types/Federation.md +2 -0
- package/dist/okf/types/Feed.md +2 -0
- package/dist/okf/types/Field.md +2 -0
- package/dist/okf/types/FilestoreBackup.md +7 -0
- package/dist/okf/types/FilestoreInstance.md +5 -0
- package/dist/okf/types/FilestoreSnapshot.md +4 -0
- package/dist/okf/types/FirebaseProject.md +3 -0
- package/dist/okf/types/FirebasedatabaseInstance.md +4 -0
- package/dist/okf/types/FirebasehostingChannel.md +2 -0
- package/dist/okf/types/FirestoreBackupSchedule.md +2 -0
- package/dist/okf/types/FirestoreIndex.md +2 -0
- package/dist/okf/types/Firewall.md +3 -0
- package/dist/okf/types/FirewallPolicyAssociation.md +2 -0
- package/dist/okf/types/FirewallPolicyRule.md +4 -0
- package/dist/okf/types/FirewallRule.md +1 -0
- package/dist/okf/types/FlexTemplateJob.md +4 -0
- package/dist/okf/types/FlexibleAppVersion.md +2 -0
- package/dist/okf/types/Flow.md +2 -0
- package/dist/okf/types/FolderFeed.md +3 -0
- package/dist/okf/types/ForwardingRule.md +10 -0
- package/dist/okf/types/Fulfillment.md +2 -0
- package/dist/okf/types/Function.md +5 -0
- package/dist/okf/types/FutureReservation.md +2 -0
- package/dist/okf/types/GCPServiceAccount.md +5 -0
- package/dist/okf/types/GCPUserAccessBinding.md +2 -0
- package/dist/okf/types/GCPolicy.md +1 -0
- package/dist/okf/types/GKECluster.md +8 -0
- package/dist/okf/types/GRPCRoute.md +4 -0
- package/dist/okf/types/GcsFolder.md +2 -0
- package/dist/okf/types/GkebackupBackup.md +2 -0
- package/dist/okf/types/GkebackupBackupPlan.md +2 -0
- package/dist/okf/types/GkehubMembership.md +6 -0
- package/dist/okf/types/GkehubNamespace.md +2 -0
- package/dist/okf/types/GlobalNetworkEndpoint.md +1 -0
- package/dist/okf/types/GlobalNetworkEndpointGroup.md +2 -0
- package/dist/okf/types/GoogleChannelConfig.md +2 -0
- package/dist/okf/types/GuestPolicy.md +4 -0
- package/dist/okf/types/HL7V2Store.md +2 -0
- package/dist/okf/types/HMACKey.md +5 -0
- package/dist/okf/types/HTTPHealthCheck.md +3 -0
- package/dist/okf/types/HTTPRoute.md +4 -0
- package/dist/okf/types/HTTPSHealthCheck.md +3 -0
- package/dist/okf/types/HealthcareDataset.md +2 -0
- package/dist/okf/types/Hub.md +5 -0
- package/dist/okf/types/IAMAuditConfig.md +1 -0
- package/dist/okf/types/IAMPolicy.md +1 -0
- package/dist/okf/types/IAMPolicyMember.md +1 -0
- package/dist/okf/types/IdentityAwareProxyClient.md +2 -0
- package/dist/okf/types/IdentityplatformConfig.md +2 -0
- package/dist/okf/types/Image.md +5 -0
- package/dist/okf/types/ImportJob.md +2 -0
- package/dist/okf/types/InboundSAMLConfig.md +1 -0
- package/dist/okf/types/IndexEndpoint.md +6 -0
- package/dist/okf/types/InspectTemplate.md +4 -0
- package/dist/okf/types/InstanceAttachment.md +2 -0
- package/dist/okf/types/InstanceConfig.md +2 -0
- package/dist/okf/types/InstanceEndpoint.md +1 -0
- package/dist/okf/types/InstanceGroup.md +3 -0
- package/dist/okf/types/InstanceGroupManager.md +8 -0
- package/dist/okf/types/InstanceGroupNamedPort.md +1 -0
- package/dist/okf/types/InstanceTemplate.md +5 -0
- package/dist/okf/types/InterceptDeployment.md +2 -0
- package/dist/okf/types/InterceptEndpointGroup.md +2 -0
- package/dist/okf/types/Interconnect.md +2 -0
- package/dist/okf/types/InterconnectAttachment.md +9 -0
- package/dist/okf/types/InternalRange.md +2 -0
- package/dist/okf/types/JobTrigger.md +5 -0
- package/dist/okf/types/KMSCryptoKey.md +2 -0
- package/dist/okf/types/KMSKeyRing.md +2 -0
- package/dist/okf/types/KeyHandle.md +2 -0
- package/dist/okf/types/KeyRingImportJob.md +4 -0
- package/dist/okf/types/LBRouteExtension.md +2 -0
- package/dist/okf/types/Lake.md +2 -0
- package/dist/okf/types/Lien.md +3 -0
- package/dist/okf/types/Link.md +2 -0
- package/dist/okf/types/Listing.md +2 -0
- package/dist/okf/types/LocationTagBinding.md +3 -0
- package/dist/okf/types/LogBucket.md +4 -0
- package/dist/okf/types/LogExclusion.md +3 -0
- package/dist/okf/types/LogMetric.md +3 -0
- package/dist/okf/types/LogSink.md +2 -0
- package/dist/okf/types/LogView.md +3 -0
- package/dist/okf/types/LogicalView.md +3 -0
- package/dist/okf/types/Machine.md +2 -0
- package/dist/okf/types/MachineImage.md +2 -0
- package/dist/okf/types/ManagedFolder.md +2 -0
- package/dist/okf/types/ManagedSSLCertificate.md +1 -0
- package/dist/okf/types/ManagedkafkaCluster.md +2 -0
- package/dist/okf/types/ManagedkafkaTopic.md +2 -0
- package/dist/okf/types/ManagementServer.md +2 -0
- package/dist/okf/types/MaterializedView.md +3 -0
- package/dist/okf/types/MembershipBinding.md +2 -0
- package/dist/okf/types/MemcacheInstance.md +4 -0
- package/dist/okf/types/MemorystoreInstance.md +2 -0
- package/dist/okf/types/Mesh.md +4 -0
- package/dist/okf/types/MetadataStore.md +2 -0
- package/dist/okf/types/MetastoreBackup.md +2 -0
- package/dist/okf/types/MetastoreService.md +2 -0
- package/dist/okf/types/MetricDescriptor.md +2 -0
- package/dist/okf/types/MigrationJob.md +2 -0
- package/dist/okf/types/MlengineModel.md +1 -0
- package/dist/okf/types/MonGroup.md +1 -0
- package/dist/okf/types/MonService.md +1 -0
- package/dist/okf/types/MonitoredProject.md +2 -0
- package/dist/okf/types/MuteConfig.md +2 -0
- package/dist/okf/types/NATAddress.md +3 -0
- package/dist/okf/types/NetappBackupVault.md +2 -0
- package/dist/okf/types/NetworkAttachment.md +2 -0
- package/dist/okf/types/NetworkEdgeSecurityService.md +2 -0
- package/dist/okf/types/NetworkEndpoint.md +1 -0
- package/dist/okf/types/NetworkEndpointGroup.md +3 -0
- package/dist/okf/types/NetworkFirewallPolicy.md +7 -0
- package/dist/okf/types/NetworkFirewallPolicyAssociation.md +2 -0
- package/dist/okf/types/NetworkFirewallPolicyRule.md +3 -0
- package/dist/okf/types/NetworkPeeringRoutesConfig.md +1 -0
- package/dist/okf/types/NetworkPolicy.md +2 -0
- package/dist/okf/types/NetworkservicesGateway.md +4 -0
- package/dist/okf/types/Node.md +2 -0
- package/dist/okf/types/NodePool.md +2 -0
- package/dist/okf/types/NodeTemplate.md +4 -0
- package/dist/okf/types/Note.md +3 -0
- package/dist/okf/types/NotebookInstance.md +2 -0
- package/dist/okf/types/NotebooksEnvironment.md +2 -0
- package/dist/okf/types/Notification.md +3 -0
- package/dist/okf/types/NotificationChannel.md +3 -0
- package/dist/okf/types/NotificationConfig.md +3 -0
- package/dist/okf/types/OAuthIDPConfig.md +1 -0
- package/dist/okf/types/OSPolicyAssignment.md +9 -0
- package/dist/okf/types/Occurrence.md +5 -0
- package/dist/okf/types/Organization.md +10 -0
- package/dist/okf/types/OrganizationFeed.md +2 -0
- package/dist/okf/types/OrganizationSecurityPolicy.md +3 -0
- package/dist/okf/types/OrganizationSecurityPolicyAssociation.md +2 -0
- package/dist/okf/types/OrganizationSecurityPolicyRule.md +1 -0
- package/dist/okf/types/OrgpolicyPolicy.md +2 -0
- package/dist/okf/types/PacketMirroring.md +4 -0
- package/dist/okf/types/Page.md +2 -0
- package/dist/okf/types/Parameter.md +2 -0
- package/dist/okf/types/ParameterVersion.md +2 -0
- package/dist/okf/types/PartialPolicy.md +1 -0
- package/dist/okf/types/PatchDeployment.md +5 -0
- package/dist/okf/types/PeeredDNSDomain.md +2 -0
- package/dist/okf/types/PerInstanceConfig.md +1 -0
- package/dist/okf/types/PhraseSet.md +2 -0
- package/dist/okf/types/PlatformPolicy.md +2 -0
- package/dist/okf/types/PolicyTag.md +3 -0
- package/dist/okf/types/PrivateCloud.md +2 -0
- package/dist/okf/types/PrivatecaCertificate.md +5 -0
- package/dist/okf/types/Processor.md +2 -0
- package/dist/okf/types/ProcessorDefaultVersion.md +1 -0
- package/dist/okf/types/ProcessorVersion.md +2 -0
- package/dist/okf/types/ProjectDefaultConfig.md +2 -0
- package/dist/okf/types/ProjectFeed.md +2 -0
- package/dist/okf/types/ProjectMetadata.md +1 -0
- package/dist/okf/types/PubSubSnapshot.md +2 -0
- package/dist/okf/types/PubSubSubscription.md +1 -0
- package/dist/okf/types/PubSubTopic.md +1 -0
- package/dist/okf/types/PubsubliteReservation.md +1 -0
- package/dist/okf/types/PubsubliteTopic.md +1 -0
- package/dist/okf/types/RecaptchaenterpriseFirewallPolicy.md +2 -0
- package/dist/okf/types/RecaptchaenterpriseKey.md +2 -0
- package/dist/okf/types/Recognizer.md +2 -0
- package/dist/okf/types/RedisCluster.md +2 -0
- package/dist/okf/types/RedisInstance.md +8 -0
- package/dist/okf/types/RegionAutoscaler.md +3 -0
- package/dist/okf/types/RegionDiskResourcePolicyAttachment.md +1 -0
- package/dist/okf/types/RegionNetworkEndpointGroup.md +2 -0
- package/dist/okf/types/RegionPerInstanceConfig.md +1 -0
- package/dist/okf/types/RegionSSLPolicy.md +4 -0
- package/dist/okf/types/RegionalEndpoint.md +2 -0
- package/dist/okf/types/ResourceBundle.md +2 -0
- package/dist/okf/types/ResourcePolicy.md +3 -0
- package/dist/okf/types/ResourcemanagerFolder.md +5 -0
- package/dist/okf/types/ResourcemanagerPolicy.md +3 -0
- package/dist/okf/types/ResourcemanagerProject.md +2 -0
- package/dist/okf/types/ResponsePolicy.md +1 -0
- package/dist/okf/types/ResponsePolicyRule.md +1 -0
- package/dist/okf/types/Restore.md +2 -0
- package/dist/okf/types/RestorePlan.md +2 -0
- package/dist/okf/types/Router.md +3 -0
- package/dist/okf/types/RouterInterface.md +1 -0
- package/dist/okf/types/RouterNAT.md +1 -0
- package/dist/okf/types/RouterPeer.md +2 -0
- package/dist/okf/types/Routine.md +3 -0
- package/dist/okf/types/Runtime.md +2 -0
- package/dist/okf/types/RuntimeTemplate.md +2 -0
- package/dist/okf/types/SQLDatabase.md +2 -0
- package/dist/okf/types/SQLInstance.md +10 -0
- package/dist/okf/types/SQLUser.md +1 -0
- package/dist/okf/types/SSHPublicKey.md +2 -0
- package/dist/okf/types/SSLCert.md +8 -0
- package/dist/okf/types/SSLCertificate.md +5 -0
- package/dist/okf/types/SSLPolicy.md +4 -0
- package/dist/okf/types/SavedQuery.md +2 -0
- package/dist/okf/types/Schema.md +1 -0
- package/dist/okf/types/Scope.md +5 -0
- package/dist/okf/types/ScopeRBACRoleBinding.md +2 -0
- package/dist/okf/types/SecretCiphertext.md +2 -0
- package/dist/okf/types/SecretManagerSecret.md +3 -0
- package/dist/okf/types/SecretManagerSecretVersion.md +6 -0
- package/dist/okf/types/SecuresourcemanagerInstance.md +2 -0
- package/dist/okf/types/SecuresourcemanagerRepository.md +2 -0
- package/dist/okf/types/SecurityPolicy.md +3 -0
- package/dist/okf/types/ServerTLSPolicy.md +3 -0
- package/dist/okf/types/ServiceAccountKey.md +6 -0
- package/dist/okf/types/ServiceAttachment.md +5 -0
- package/dist/okf/types/ServiceBinding.md +2 -0
- package/dist/okf/types/ServiceConnectionPolicy.md +2 -0
- package/dist/okf/types/ServiceIdentity.md +2 -0
- package/dist/okf/types/ServiceLevelObjective.md +4 -0
- package/dist/okf/types/ServicePerimeter.md +4 -0
- package/dist/okf/types/ServicePerimeterResource.md +1 -0
- package/dist/okf/types/ServiceProjectAttachment.md +2 -0
- package/dist/okf/types/ServiceSplitTraffic.md +1 -0
- package/dist/okf/types/ServicedirectoryEndpoint.md +2 -0
- package/dist/okf/types/ServicedirectoryNamespace.md +2 -0
- package/dist/okf/types/ServicedirectoryService.md +2 -0
- package/dist/okf/types/ServicenetworkingConnection.md +2 -0
- package/dist/okf/types/ServiceusageService.md +1 -0
- package/dist/okf/types/Settings.md +2 -0
- package/dist/okf/types/SharedVPCHostProject.md +1 -0
- package/dist/okf/types/SharedVPCServiceProject.md +1 -0
- package/dist/okf/types/Site.md +3 -0
- package/dist/okf/types/Source.md +2 -0
- package/dist/okf/types/SourcerepoRepository.md +3 -0
- package/dist/okf/types/SpannerBackupSchedule.md +2 -0
- package/dist/okf/types/SpannerDatabase.md +2 -0
- package/dist/okf/types/SpannerInstance.md +3 -0
- package/dist/okf/types/Spoke.md +5 -0
- package/dist/okf/types/StandardAppVersion.md +2 -0
- package/dist/okf/types/StorageBucket.md +3 -0
- package/dist/okf/types/StoragetransferJob.md +5 -0
- package/dist/okf/types/StoredInfoType.md +1 -0
- package/dist/okf/types/Stream.md +3 -0
- package/dist/okf/types/Subnet.md +5 -0
- package/dist/okf/types/Subnetwork.md +8 -0
- package/dist/okf/types/Subscription.md +1 -0
- package/dist/okf/types/SyncAuthorization.md +2 -0
- package/dist/okf/types/TCPRoute.md +4 -0
- package/dist/okf/types/TLSRoute.md +4 -0
- package/dist/okf/types/Tag.md +2 -0
- package/dist/okf/types/TagBinding.md +3 -0
- package/dist/okf/types/TagKey.md +6 -0
- package/dist/okf/types/TagTemplate.md +2 -0
- package/dist/okf/types/TagValue.md +6 -0
- package/dist/okf/types/Target.md +2 -0
- package/dist/okf/types/TargetGRPCProxy.md +5 -0
- package/dist/okf/types/TargetHTTPProxy.md +4 -0
- package/dist/okf/types/TargetHTTPSProxy.md +5 -0
- package/dist/okf/types/TargetInstance.md +3 -0
- package/dist/okf/types/TargetPool.md +2 -0
- package/dist/okf/types/TargetSSLProxy.md +4 -0
- package/dist/okf/types/TargetTCPProxy.md +5 -0
- package/dist/okf/types/TargetVPNGateway.md +4 -0
- package/dist/okf/types/TasksQueue.md +2 -0
- package/dist/okf/types/Taxonomy.md +3 -0
- package/dist/okf/types/Tenant.md +1 -0
- package/dist/okf/types/TenantDefaultSupportedIDPConfig.md +2 -0
- package/dist/okf/types/TenantInboundSAMLConfig.md +1 -0
- package/dist/okf/types/TenantOAuthIDPConfig.md +1 -0
- package/dist/okf/types/Tensorboard.md +6 -0
- package/dist/okf/types/URLMap.md +5 -0
- package/dist/okf/types/UptimeCheckConfig.md +1 -0
- package/dist/okf/types/User.md +2 -0
- package/dist/okf/types/VPCNetwork.md +3 -0
- package/dist/okf/types/VPNGateway.md +2 -0
- package/dist/okf/types/VPNTunnel.md +7 -0
- package/dist/okf/types/VertexaiDataset.md +1 -0
- package/dist/okf/types/VertexaiEndpoint.md +1 -0
- package/dist/okf/types/VertexaiIndex.md +1 -0
- package/dist/okf/types/VirtualMachine.md +2 -0
- package/dist/okf/types/VmwareengineNetwork.md +2 -0
- package/dist/okf/types/VmwareengineNetworkPeering.md +2 -0
- package/dist/okf/types/VpnConnection.md +3 -0
- package/dist/okf/types/WasmPlugin.md +2 -0
- package/dist/okf/types/WebApp.md +3 -0
- package/dist/okf/types/Webhook.md +3 -0
- package/dist/okf/types/WorkerPool.md +2 -0
- package/dist/okf/types/Workflow.md +2 -0
- package/dist/okf/types/WorkflowTemplate.md +4 -0
- package/dist/okf/types/WorkflowsExecution.md +2 -0
- package/dist/okf/types/WorkforcePool.md +3 -0
- package/dist/okf/types/WorkforcePoolProvider.md +2 -0
- package/dist/okf/types/Workload.md +2 -0
- package/dist/okf/types/WorkloadIdentityPool.md +2 -0
- package/dist/okf/types/WorkloadIdentityPoolProvider.md +2 -0
- package/dist/okf/types/Workstation.md +2 -0
- package/dist/okf/types/WorkstationCluster.md +2 -0
- package/dist/okf/types/WorkstationConfig.md +2 -0
- package/dist/okf/types/Zone.md +2 -0
- package/dist/op/activities/gcp-apply.d.ts +7 -0
- package/dist/op/activities/gcp-apply.d.ts.map +1 -1
- package/dist/op/activities/gcp-apply.js +25 -2
- package/dist/op/activities/index.d.ts +1 -1
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +6 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +52 -3
- package/dist/spec/parse.d.ts +1 -1
- package/dist/spec/parse.js +17 -1
- package/dist/types/index.d.ts +1367 -0
- package/package.json +2 -2
- package/src/attributes.test.ts +16 -0
- package/src/codegen/generate.ts +8 -3
- package/src/composites/catalog.ts +7 -1
- package/src/composites/cloud-run-service.ts +12 -5
- package/src/composites/composites.test.ts +17 -0
- package/src/deep-observe.ts +1 -1
- package/src/describe-resources.ts +8 -6
- package/src/generated/index.d.ts +1367 -0
- package/src/generated/index.ts +487 -487
- package/src/generated/lexicon-gcp.json +1848 -481
- package/src/health.test.ts +59 -0
- package/src/health.ts +123 -0
- package/src/index.ts +3 -0
- package/src/op/activities/gcp-apply.test.ts +16 -0
- package/src/op/activities/gcp-apply.ts +25 -2
- package/src/op/activities/index.ts +1 -0
- package/src/plugin.ts +8 -0
- package/src/project-resolution.test.ts +41 -0
- package/src/serializer-outputs.test.ts +26 -0
- package/src/serializer-pseudo.test.ts +38 -0
- package/src/serializer.ts +62 -5
- package/src/spec/parse.test.ts +42 -2
- package/src/spec/parse.ts +17 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
2
|
+
import { cloudRunEntry, observeHealthGcp } from "./health";
|
|
3
|
+
import type { GcpReadHttp } from "./api/read-client";
|
|
4
|
+
|
|
5
|
+
const AT = "2026-10-20T21:00:00.000Z";
|
|
6
|
+
const now = () => new Date(AT);
|
|
7
|
+
const entities = new Map([
|
|
8
|
+
[
|
|
9
|
+
"api",
|
|
10
|
+
{
|
|
11
|
+
entityType: "GCP::Run::Service",
|
|
12
|
+
props: { metadata: { name: "api", annotations: { "cnrm.cloud.google.com/project-id": "demo" } }, spec: { location: "us-central1" } },
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
describe("gcp health (#4177)", () => {
|
|
18
|
+
let saved: string | undefined;
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
saved = process.env.GCP_ENDPOINT_URL;
|
|
21
|
+
process.env.GCP_ENDPOINT_URL = "http://localhost:4588";
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
if (saved === undefined) delete process.env.GCP_ENDPOINT_URL;
|
|
25
|
+
else process.env.GCP_ENDPOINT_URL = saved;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("reads the v2 terminalCondition and the v1 status conditions", () => {
|
|
29
|
+
expect(
|
|
30
|
+
cloudRunEntry({ terminalCondition: { type: "Ready", state: "CONDITION_SUCCEEDED", lastTransitionTime: "2026-10-20T20:00:00Z" }, latestReadyRevision: "projects/demo/locations/us-central1/services/api/revisions/api-00002" }, AT),
|
|
31
|
+
).toMatchObject({ state: "healthy", detail: "Ready CONDITION_SUCCEEDED, latest ready api-00002", checkedAt: "2026-10-20T20:00:00Z" });
|
|
32
|
+
expect(cloudRunEntry({ terminalCondition: { type: "Ready", state: "CONDITION_FAILED", message: "image not found" } }, AT)).toMatchObject({
|
|
33
|
+
state: "unhealthy",
|
|
34
|
+
detail: "Ready CONDITION_FAILED: image not found",
|
|
35
|
+
});
|
|
36
|
+
expect(cloudRunEntry({ terminalCondition: { type: "Ready", state: "CONDITION_RECONCILING" } }, AT).state).toBe("unknown");
|
|
37
|
+
expect(cloudRunEntry({ status: { conditions: [{ type: "Ready", status: "False", reason: "RevisionFailed" }] } }, AT).state).toBe("unhealthy");
|
|
38
|
+
expect(cloudRunEntry({}, AT).state).toBe("unknown");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("reads at the endpoint override in the declared project and location", async () => {
|
|
42
|
+
const urls: string[] = [];
|
|
43
|
+
const http: GcpReadHttp = async (_m, url) => {
|
|
44
|
+
urls.push(url);
|
|
45
|
+
return { status: 200, text: JSON.stringify({ terminalCondition: { type: "Ready", state: "CONDITION_SUCCEEDED" } }) };
|
|
46
|
+
};
|
|
47
|
+
const r = await observeHealthGcp({ environment: "dev", buildOutput: "", entities, http, now });
|
|
48
|
+
expect(r.entities.api).toMatchObject({ state: "healthy", observedAt: AT });
|
|
49
|
+
expect(urls).toEqual(["http://localhost:4588/v2/projects/demo/locations/us-central1/services/api"]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("a 404 is absent; a 403 is a no-credentials hole", async () => {
|
|
53
|
+
const notFound: GcpReadHttp = async () => ({ status: 404, text: "" });
|
|
54
|
+
expect((await observeHealthGcp({ environment: "dev", buildOutput: "", entities, http: notFound })).absent).toEqual(["api"]);
|
|
55
|
+
const denied: GcpReadHttp = async () => ({ status: 403, text: "denied" });
|
|
56
|
+
const r = await observeHealthGcp({ environment: "dev", buildOutput: "", entities, http: denied });
|
|
57
|
+
expect(r.unobserved.api?.reason).toBe("no-credentials");
|
|
58
|
+
});
|
|
59
|
+
});
|
package/src/health.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime health for GCP (#4177): Cloud Run services.
|
|
3
|
+
*
|
|
4
|
+
* A Cloud Run v2 service carries its `Ready` condition as `terminalCondition`
|
|
5
|
+
* (`CONDITION_SUCCEEDED`, `CONDITION_FAILED`, pending or reconciling). The v1
|
|
6
|
+
* and Config Connector shape carries it in `status.conditions` with
|
|
7
|
+
* `status: "True" | "False" | "Unknown"`; both are read. Same transport,
|
|
8
|
+
* project resolution and endpoint rule as `describe-resources.ts`, so
|
|
9
|
+
* `GCP_ENDPOINT_URL` (floci-gcp) answers.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { HealthEntry, HealthReadOptions, HealthReadResult, UnobservedEntity } from "@intentius/chant/lexicon";
|
|
13
|
+
import { getResource, GcpReadError, isNotFound, type GcpReadHttp } from "./api/read-client";
|
|
14
|
+
import { deriveGVK, manifestProjectAnnotations, resolveReadProject } from "./describe-resources";
|
|
15
|
+
|
|
16
|
+
export const GCP_HEALTH_TYPES = ["GCP::Run::Service"] as const;
|
|
17
|
+
|
|
18
|
+
export interface GcpHealthOptions extends HealthReadOptions {
|
|
19
|
+
http?: GcpReadHttp;
|
|
20
|
+
now?: () => Date;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface Condition {
|
|
24
|
+
type?: string;
|
|
25
|
+
state?: string;
|
|
26
|
+
status?: string;
|
|
27
|
+
reason?: string;
|
|
28
|
+
message?: string;
|
|
29
|
+
lastTransitionTime?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The parts of a Cloud Run service body that decide health. */
|
|
33
|
+
export interface CloudRunServiceState {
|
|
34
|
+
terminalCondition?: Condition;
|
|
35
|
+
conditions?: Condition[];
|
|
36
|
+
reconciling?: boolean;
|
|
37
|
+
latestReadyRevision?: string;
|
|
38
|
+
uri?: string;
|
|
39
|
+
status?: { conditions?: Condition[]; url?: string };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function readyCondition(body: CloudRunServiceState): Condition | undefined {
|
|
43
|
+
if (body.terminalCondition && (body.terminalCondition.type ?? "Ready") === "Ready") return body.terminalCondition;
|
|
44
|
+
return body.conditions?.find((c) => c.type === "Ready") ?? body.status?.conditions?.find((c) => c.type === "Ready");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The `Ready` condition's verdict. No condition at all is `unknown`. */
|
|
48
|
+
export function cloudRunEntry(body: CloudRunServiceState, observedAt: string): HealthEntry {
|
|
49
|
+
const type = "GCP::Run::Service";
|
|
50
|
+
const ready = readyCondition(body);
|
|
51
|
+
if (!ready) return { type, state: "unknown", detail: "no Ready condition", observedAt };
|
|
52
|
+
const value = (ready.state ?? ready.status ?? "").toUpperCase();
|
|
53
|
+
const state =
|
|
54
|
+
value === "CONDITION_SUCCEEDED" || value === "TRUE"
|
|
55
|
+
? "healthy"
|
|
56
|
+
: value === "CONDITION_FAILED" || value === "FALSE"
|
|
57
|
+
? "unhealthy"
|
|
58
|
+
: "unknown";
|
|
59
|
+
const why = ready.message || ready.reason;
|
|
60
|
+
const revision = body.latestReadyRevision ? `, latest ready ${body.latestReadyRevision.split("/").pop()}` : "";
|
|
61
|
+
const reconciling = body.reconciling ? ", reconciling" : "";
|
|
62
|
+
return {
|
|
63
|
+
type,
|
|
64
|
+
state,
|
|
65
|
+
detail: `Ready ${ready.state ?? ready.status ?? "unset"}${why ? `: ${why}` : ""}${revision}${reconciling}`,
|
|
66
|
+
observedAt,
|
|
67
|
+
...(ready.lastTransitionTime ? { checkedAt: ready.lastTransitionTime } : {}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function observeHealthGcp(options: GcpHealthOptions): Promise<HealthReadResult> {
|
|
72
|
+
const observedAt = (options.now?.() ?? new Date()).toISOString();
|
|
73
|
+
const endpoint = process.env.GCP_ENDPOINT_URL;
|
|
74
|
+
const manifestProjects = manifestProjectAnnotations(options.buildOutput);
|
|
75
|
+
const entities: Record<string, HealthEntry> = {};
|
|
76
|
+
const unobserved: Record<string, UnobservedEntity> = {};
|
|
77
|
+
const absent: string[] = [];
|
|
78
|
+
|
|
79
|
+
await Promise.all(
|
|
80
|
+
[...options.entities].map(async ([entityName, { entityType, props }]) => {
|
|
81
|
+
const gvk = deriveGVK(entityType);
|
|
82
|
+
const metadata = props.metadata as { name?: string; annotations?: Record<string, string> } | undefined;
|
|
83
|
+
const name = metadata?.name;
|
|
84
|
+
if (!gvk || !name) {
|
|
85
|
+
unobserved[entityName] = {
|
|
86
|
+
type: entityType,
|
|
87
|
+
reason: "read-failed",
|
|
88
|
+
detail: gvk ? "declared entity has no metadata.name to query by" : `cannot derive a GCP kind from ${entityType}`,
|
|
89
|
+
};
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
let project: string;
|
|
93
|
+
try {
|
|
94
|
+
project = resolveReadProject(gvk.kind, name, metadata, manifestProjects, props);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
unobserved[entityName] = { type: entityType, reason: "no-binding", detail: err instanceof Error ? err.message : String(err) };
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const body = await getResource(
|
|
101
|
+
{ project, ...(endpoint ? { endpoint } : {}), ...(options.http ? { http: options.http } : {}) },
|
|
102
|
+
gvk.kind,
|
|
103
|
+
name,
|
|
104
|
+
props,
|
|
105
|
+
);
|
|
106
|
+
entities[entityName] = cloudRunEntry(body as CloudRunServiceState, observedAt);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
if (isNotFound(err)) {
|
|
109
|
+
absent.push(entityName);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const status = err instanceof GcpReadError ? err.status : undefined;
|
|
113
|
+
unobserved[entityName] = {
|
|
114
|
+
type: entityType,
|
|
115
|
+
reason: status === 401 || status === 403 ? "no-credentials" : "read-failed",
|
|
116
|
+
detail: (err instanceof Error ? err.message : String(err)).slice(0, 200),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}),
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
return { entities, unobserved, absent };
|
|
123
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -21,6 +21,9 @@ export { GCP, ProjectId, Region, Zone } from "./pseudo";
|
|
|
21
21
|
// Variables / annotation constants
|
|
22
22
|
export { GcpAnnotations } from "./variables";
|
|
23
23
|
|
|
24
|
+
// Outputs (#4181): the build warns that Config Connector YAML can't carry them.
|
|
25
|
+
export { LexiconOutput, output, isLexiconOutput } from "@intentius/chant/lexicon-output";
|
|
26
|
+
|
|
24
27
|
// Generated entities — export everything from generated index
|
|
25
28
|
// After running `npm run generate`, this re-exports all Config Connector resource classes
|
|
26
29
|
export * from "./generated/index";
|
|
@@ -234,6 +234,22 @@ describe("resolveGcpProject (#711)", () => {
|
|
|
234
234
|
expect(() => resolveGcpProject({ metadata: { name: "b" } }, {} as NodeJS.ProcessEnv))
|
|
235
235
|
.toThrow(/no GCP project/);
|
|
236
236
|
});
|
|
237
|
+
|
|
238
|
+
test("spec.projectRef.external wins over env and the annotation (#4201)", () => {
|
|
239
|
+
const run = { ...BUCKET, spec: { projectRef: { external: "ref-project" } } };
|
|
240
|
+
expect(resolveGcpProject(run, { GOOGLE_CLOUD_PROJECT: "env-project" } as NodeJS.ProcessEnv)).toBe("ref-project");
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
test("projectRef.external may be projects/<id>", () => {
|
|
244
|
+
const run = { metadata: { name: "r" }, spec: { projectRef: { external: "projects/three-cloud" } } };
|
|
245
|
+
expect(resolveGcpProject(run, {} as NodeJS.ProcessEnv)).toBe("three-cloud");
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test("an unresolved GCP.ProjectId in projectRef reads GCP_PROJECT_ID, else falls through", () => {
|
|
249
|
+
const run = { ...BUCKET, spec: { projectRef: { external: { Ref: "GCP::ProjectId" } } } };
|
|
250
|
+
expect(resolveGcpProject(run, { GCP_PROJECT_ID: "pseudo-project" } as NodeJS.ProcessEnv)).toBe("pseudo-project");
|
|
251
|
+
expect(resolveGcpProject(run, {} as NodeJS.ProcessEnv)).toBe("annotated-project");
|
|
252
|
+
});
|
|
237
253
|
});
|
|
238
254
|
|
|
239
255
|
describe("resolveGcpEndpoint (#1449)", () => {
|
|
@@ -443,11 +443,34 @@ export function resolveGcpEndpoint(
|
|
|
443
443
|
}
|
|
444
444
|
|
|
445
445
|
/** Resolve the project: `GOOGLE_CLOUD_PROJECT` env, else the CNRM project-id annotation. Pure. */
|
|
446
|
+
/**
|
|
447
|
+
* The project a resource names in `spec.projectRef.external` (#4201): a
|
|
448
|
+
* project id or `projects/<id>`. A `GCP.ProjectId` pseudo-parameter there
|
|
449
|
+
* (`{ Ref: "GCP::ProjectId" }`, unresolved in discovery output) reads
|
|
450
|
+
* `GCP_PROJECT_ID`, as the serializer does.
|
|
451
|
+
*/
|
|
452
|
+
export function projectRefProject(spec: Record<string, unknown> | undefined, env: NodeJS.ProcessEnv = process.env): string | undefined {
|
|
453
|
+
const ref = spec?.projectRef;
|
|
454
|
+
if (ref === null || typeof ref !== "object") return undefined;
|
|
455
|
+
let external = (ref as Record<string, unknown>).external;
|
|
456
|
+
if (external !== null && typeof external === "object" && typeof (external as { toJSON?: unknown }).toJSON === "function") {
|
|
457
|
+
external = (external as { toJSON(): unknown }).toJSON();
|
|
458
|
+
}
|
|
459
|
+
if (external !== null && typeof external === "object" && (external as Record<string, unknown>).Ref === "GCP::ProjectId") {
|
|
460
|
+
return env.GCP_PROJECT_ID || undefined;
|
|
461
|
+
}
|
|
462
|
+
if (typeof external !== "string" || external === "") return undefined;
|
|
463
|
+
return external.startsWith("projects/") ? external.slice("projects/".length).split("/")[0] : external;
|
|
464
|
+
}
|
|
465
|
+
|
|
446
466
|
export function resolveGcpProject(resource: GcpResource, env: NodeJS.ProcessEnv = process.env): string {
|
|
447
|
-
const project =
|
|
467
|
+
const project =
|
|
468
|
+
projectRefProject(resource.spec, env) ||
|
|
469
|
+
env.GOOGLE_CLOUD_PROJECT ||
|
|
470
|
+
resource.metadata?.annotations?.[PROJECT_ID_ANNOTATION];
|
|
448
471
|
if (!project) {
|
|
449
472
|
throw new Error(
|
|
450
|
-
`no GCP project — set GOOGLE_CLOUD_PROJECT or the ${PROJECT_ID_ANNOTATION} annotation`,
|
|
473
|
+
`no GCP project — set spec.projectRef.external, GOOGLE_CLOUD_PROJECT or the ${PROJECT_ID_ANNOTATION} annotation`,
|
|
451
474
|
);
|
|
452
475
|
}
|
|
453
476
|
return project;
|
package/src/plugin.ts
CHANGED
|
@@ -410,4 +410,12 @@ export const bucket = new StorageBucket({
|
|
|
410
410
|
},
|
|
411
411
|
|
|
412
412
|
deepNormalizationHooks: gcpDeepNormalizationHooks,
|
|
413
|
+
|
|
414
|
+
/** Runtime health (#4177): Cloud Run services. Implementation in ./health.ts. */
|
|
415
|
+
healthTypes: ["GCP::Run::Service"],
|
|
416
|
+
|
|
417
|
+
async observeHealth(options) {
|
|
418
|
+
const { observeHealthGcp } = await import("./health");
|
|
419
|
+
return observeHealthGcp(options);
|
|
420
|
+
},
|
|
413
421
|
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live readers take a resource's project from `projectRef.external`
|
|
3
|
+
* (#4201), the way `CloudRunServiceComposite` declares it, before
|
|
4
|
+
* GOOGLE_CLOUD_PROJECT and the annotations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { afterEach, describe, expect, test } from "vitest";
|
|
8
|
+
import { manifestProjectAnnotations, resolveReadProject } from "./describe-resources";
|
|
9
|
+
|
|
10
|
+
const saved = process.env.GOOGLE_CLOUD_PROJECT;
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
if (saved === undefined) delete process.env.GOOGLE_CLOUD_PROJECT;
|
|
13
|
+
else process.env.GOOGLE_CLOUD_PROJECT = saved;
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe("resolveReadProject", () => {
|
|
17
|
+
test("reads the entity's projectRef.external with no env or annotation", () => {
|
|
18
|
+
delete process.env.GOOGLE_CLOUD_PROJECT;
|
|
19
|
+
const props = { projectRef: { external: "three-cloud" }, location: "asia-northeast1" };
|
|
20
|
+
expect(resolveReadProject("RunService", "web", { annotations: {} }, new Map(), props)).toBe("three-cloud");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("still names every knob when nothing resolves", () => {
|
|
24
|
+
delete process.env.GOOGLE_CLOUD_PROJECT;
|
|
25
|
+
expect(() => resolveReadProject("RunService", "web", undefined, new Map(), {})).toThrow(/projectRef\.external/);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe("manifestProjectAnnotations", () => {
|
|
30
|
+
test("takes a document's spec.projectRef.external", () => {
|
|
31
|
+
const yaml = `apiVersion: run.cnrm.cloud.google.com/v1beta1
|
|
32
|
+
kind: RunService
|
|
33
|
+
metadata:
|
|
34
|
+
name: web
|
|
35
|
+
spec:
|
|
36
|
+
projectRef:
|
|
37
|
+
external: projects/three-cloud
|
|
38
|
+
`;
|
|
39
|
+
expect(manifestProjectAnnotations(yaml).get("RunService/web")).toBe("three-cloud");
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Connector YAML has no outputs, so an output of a gcp resource is
|
|
3
|
+
* named in a warning instead of vanishing (#4181).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { output, CloudRunService } from "./index";
|
|
8
|
+
import { gcpSerializer } from "./serializer";
|
|
9
|
+
|
|
10
|
+
describe("gcp outputs", () => {
|
|
11
|
+
it("warns that an output of a gcp resource can't be written", () => {
|
|
12
|
+
const svc = new CloudRunService({ location: "us-central1", projectRef: { external: "p" }, template: {} }) as any;
|
|
13
|
+
const out = output(svc.status_uri, "WebUri");
|
|
14
|
+
out._setSourceEntity("web");
|
|
15
|
+
const result = gcpSerializer.serialize(new Map([["web", svc]]), [out]);
|
|
16
|
+
expect(typeof result).toBe("object");
|
|
17
|
+
const warnings = (result as { warnings?: string[] }).warnings ?? [];
|
|
18
|
+
expect(warnings).toHaveLength(1);
|
|
19
|
+
expect(warnings[0]).toContain('output "WebUri" (web.status.uri)');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("says nothing about an output with no source lexicon", () => {
|
|
23
|
+
const result = gcpSerializer.serialize(new Map(), [output("eastus", "Region")]);
|
|
24
|
+
expect(typeof result).toBe("string");
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GCP pseudo-parameters in spec values are resolved at build, and a build
|
|
3
|
+
* that can't resolve one refuses with the variable named (#4200).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { afterEach, describe, expect, test } from "vitest";
|
|
7
|
+
import { CloudRunServiceComposite } from "./composites/cloud-run-service";
|
|
8
|
+
import { gcpSerializer } from "./serializer";
|
|
9
|
+
|
|
10
|
+
const saved = { project: process.env.GCP_PROJECT_ID, region: process.env.GCP_REGION };
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
for (const [k, v] of [["GCP_PROJECT_ID", saved.project], ["GCP_REGION", saved.region]] as const) {
|
|
13
|
+
if (v === undefined) delete process.env[k];
|
|
14
|
+
else process.env[k] = v;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
function build(): string {
|
|
19
|
+
const { service } = CloudRunServiceComposite({ name: "web", image: "traefik/whoami:v1.10", port: 80 });
|
|
20
|
+
return gcpSerializer.serialize(new Map([["web", service]])) as string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe("gcp pseudo-parameters in spec values", () => {
|
|
24
|
+
test("resolve from GCP_PROJECT_ID and GCP_REGION", () => {
|
|
25
|
+
process.env.GCP_PROJECT_ID = "three-cloud";
|
|
26
|
+
process.env.GCP_REGION = "asia-northeast1";
|
|
27
|
+
const yaml = build();
|
|
28
|
+
expect(yaml).toContain("location: asia-northeast1");
|
|
29
|
+
expect(yaml).toContain("external: three-cloud");
|
|
30
|
+
expect(yaml).not.toMatch(/Ref: GCP::/);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("refuse the build, naming each unset variable", () => {
|
|
34
|
+
delete process.env.GCP_PROJECT_ID;
|
|
35
|
+
delete process.env.GCP_REGION;
|
|
36
|
+
expect(build).toThrow(/GCP_REGION, GCP_PROJECT_ID are not set[\s\S]*web: GCP::Region needs GCP_REGION[\s\S]*web: GCP::ProjectId needs GCP_PROJECT_ID/);
|
|
37
|
+
});
|
|
38
|
+
});
|
package/src/serializer.ts
CHANGED
|
@@ -116,6 +116,21 @@ function toYAMLValue(value: unknown, entityNames: Map<Declarable, string>): unkn
|
|
|
116
116
|
return walkValue(value, entityNames, gcpVisitor(entityNames));
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
/**
|
|
120
|
+
* A warning for each output of a gcp resource (#4181). Config Connector YAML
|
|
121
|
+
* has no outputs section, and a field such as `status.uri` exists only once
|
|
122
|
+
* the resource is applied, so the build cannot write the value anywhere. An
|
|
123
|
+
* output with no source lexicon (a literal or an intrinsic) is passed to
|
|
124
|
+
* every lexicon and is left to one that writes outputs.
|
|
125
|
+
*/
|
|
126
|
+
function unwritableOutputWarnings(outputs: LexiconOutput[] | undefined): string[] {
|
|
127
|
+
return (outputs ?? [])
|
|
128
|
+
.filter((o) => o.sourceLexicon === "gcp")
|
|
129
|
+
.map((o) =>
|
|
130
|
+
`gcp: output "${o.outputName}" (${o.sourceEntity || "?"}.${o.sourceAttribute}) is not written: Config Connector YAML has no outputs, so the value exists only after apply. Read it from the live resource instead.`,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
119
134
|
/**
|
|
120
135
|
* GCP Config Connector YAML serializer implementation.
|
|
121
136
|
*/
|
|
@@ -123,7 +138,7 @@ export const gcpSerializer: Serializer = {
|
|
|
123
138
|
name: "gcp",
|
|
124
139
|
rulePrefix: "WGC",
|
|
125
140
|
|
|
126
|
-
serialize(entities: Map<string, Declarable>,
|
|
141
|
+
serialize(entities: Map<string, Declarable>, outputs?: LexiconOutput[], context?: SerializeContext): string | SerializerResult {
|
|
127
142
|
// Build reverse map: entity → name
|
|
128
143
|
const entityNames = new Map<Declarable, string>();
|
|
129
144
|
for (const [name, entity] of entities) {
|
|
@@ -147,6 +162,7 @@ export const gcpSerializer: Serializer = {
|
|
|
147
162
|
}
|
|
148
163
|
|
|
149
164
|
const documents: string[] = [];
|
|
165
|
+
const unresolved: UnresolvedPseudo[] = [];
|
|
150
166
|
|
|
151
167
|
for (const [name, entity] of entities) {
|
|
152
168
|
if (isPropertyDeclarable(entity)) continue;
|
|
@@ -156,9 +172,10 @@ export const gcpSerializer: Serializer = {
|
|
|
156
172
|
const gvk = resolveGVK(entityType);
|
|
157
173
|
if (!gvk) continue;
|
|
158
174
|
|
|
159
|
-
const props =
|
|
160
|
-
isResourceDeclarable(entity) ? entity.props : undefined,
|
|
161
|
-
|
|
175
|
+
const props = resolvePseudoParameters(
|
|
176
|
+
toYAMLValue(isResourceDeclarable(entity) ? entity.props : undefined, entityNames),
|
|
177
|
+
name,
|
|
178
|
+
unresolved,
|
|
162
179
|
) as Record<string, unknown> | undefined;
|
|
163
180
|
|
|
164
181
|
if (!props) continue;
|
|
@@ -208,7 +225,11 @@ export const gcpSerializer: Serializer = {
|
|
|
208
225
|
documents.push(yamlDoc);
|
|
209
226
|
}
|
|
210
227
|
|
|
211
|
-
|
|
228
|
+
if (unresolved.length > 0) throw new Error(unresolvedMessage(unresolved));
|
|
229
|
+
|
|
230
|
+
const primary = documents.join("\n---\n");
|
|
231
|
+
const warnings = unwritableOutputWarnings(outputs);
|
|
232
|
+
return warnings.length > 0 ? { primary, warnings } : primary;
|
|
212
233
|
},
|
|
213
234
|
};
|
|
214
235
|
|
|
@@ -223,6 +244,42 @@ const PSEUDO_ENV_MAP: Record<string, { envVar: string; fallback: string }> = {
|
|
|
223
244
|
"GCP::Zone": { envVar: "GCP_ZONE", fallback: "us-central1-a" },
|
|
224
245
|
};
|
|
225
246
|
|
|
247
|
+
interface UnresolvedPseudo {
|
|
248
|
+
entity: string;
|
|
249
|
+
ref: string;
|
|
250
|
+
envVar: string;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Replace each GCP pseudo-parameter (`{ Ref: "GCP::Region" }`) in a
|
|
255
|
+
* serialized resource with its environment variable's value (#4200).
|
|
256
|
+
* Config Connector has no parameters, so a `Ref` left in the YAML reaches
|
|
257
|
+
* the API as an object. A variable that isn't set is recorded, and the
|
|
258
|
+
* build refuses with every one named.
|
|
259
|
+
*/
|
|
260
|
+
function resolvePseudoParameters(value: unknown, entity: string, unresolved: UnresolvedPseudo[]): unknown {
|
|
261
|
+
if (Array.isArray(value)) return value.map((v) => resolvePseudoParameters(v, entity, unresolved));
|
|
262
|
+
if (value === null || typeof value !== "object") return value;
|
|
263
|
+
const obj = value as Record<string, unknown>;
|
|
264
|
+
const keys = Object.keys(obj);
|
|
265
|
+
if (keys.length === 1 && keys[0] === "Ref" && typeof obj.Ref === "string" && obj.Ref in PSEUDO_ENV_MAP) {
|
|
266
|
+
const { envVar } = PSEUDO_ENV_MAP[obj.Ref];
|
|
267
|
+
const resolved = process.env[envVar];
|
|
268
|
+
if (resolved) return resolved;
|
|
269
|
+
unresolved.push({ entity, ref: obj.Ref, envVar });
|
|
270
|
+
return value;
|
|
271
|
+
}
|
|
272
|
+
const out: Record<string, unknown> = {};
|
|
273
|
+
for (const [k, v] of Object.entries(obj)) out[k] = resolvePseudoParameters(v, entity, unresolved);
|
|
274
|
+
return out;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function unresolvedMessage(unresolved: UnresolvedPseudo[]): string {
|
|
278
|
+
const vars = [...new Set(unresolved.map((u) => u.envVar))];
|
|
279
|
+
const lines = unresolved.map((u) => ` ${u.entity}: ${u.ref} needs ${u.envVar}`);
|
|
280
|
+
return `gcp: ${vars.join(", ")} ${vars.length === 1 ? "is" : "are"} not set, and Config Connector YAML can't carry a pseudo-parameter. Set ${vars.length === 1 ? "it" : "them"} at build, or pass the value explicitly:\n${lines.join("\n")}`;
|
|
281
|
+
}
|
|
282
|
+
|
|
226
283
|
/**
|
|
227
284
|
* Resolve an annotation value to a plain string.
|
|
228
285
|
* PseudoParameter intrinsics are resolved from environment variables;
|
package/src/spec/parse.test.ts
CHANGED
|
@@ -50,6 +50,47 @@ describe("gcpShortName", () => {
|
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
describe("parseGcpCRD", () => {
|
|
53
|
+
test("turns the scalar fields of status into attributes (#4179)", () => {
|
|
54
|
+
const crd = `apiVersion: apiextensions.k8s.io/v1
|
|
55
|
+
kind: CustomResourceDefinition
|
|
56
|
+
metadata:
|
|
57
|
+
name: runservices.run.cnrm.cloud.google.com
|
|
58
|
+
spec:
|
|
59
|
+
group: run.cnrm.cloud.google.com
|
|
60
|
+
names:
|
|
61
|
+
kind: RunService
|
|
62
|
+
versions:
|
|
63
|
+
- name: v1beta1
|
|
64
|
+
served: true
|
|
65
|
+
storage: true
|
|
66
|
+
schema:
|
|
67
|
+
openAPIV3Schema:
|
|
68
|
+
properties:
|
|
69
|
+
spec:
|
|
70
|
+
type: object
|
|
71
|
+
properties:
|
|
72
|
+
location:
|
|
73
|
+
type: string
|
|
74
|
+
status:
|
|
75
|
+
type: object
|
|
76
|
+
properties:
|
|
77
|
+
uri:
|
|
78
|
+
type: string
|
|
79
|
+
observedGeneration:
|
|
80
|
+
type: integer
|
|
81
|
+
conditions:
|
|
82
|
+
type: array
|
|
83
|
+
items:
|
|
84
|
+
type: object
|
|
85
|
+
`;
|
|
86
|
+
const [result] = parseGcpCRD(crd);
|
|
87
|
+
const attrs = Object.fromEntries(result.resource.attributes.map((a) => [a.name, a.tsType]));
|
|
88
|
+
expect(attrs["status.uri"]).toBe("string");
|
|
89
|
+
expect(attrs["status.observedGeneration"]).toBe("number");
|
|
90
|
+
expect(attrs["status.conditions"]).toBeUndefined();
|
|
91
|
+
expect(attrs.name).toBe("string");
|
|
92
|
+
});
|
|
93
|
+
|
|
53
94
|
test("parses ComputeInstance CRD", () => {
|
|
54
95
|
const content = readFileSync(join(testdata, "compute-instance.yaml"), "utf-8");
|
|
55
96
|
const results = parseGcpCRD(content);
|
|
@@ -80,8 +121,7 @@ describe("parseGcpCRD", () => {
|
|
|
80
121
|
expect(netRef!.isResourceRef).toBe(true);
|
|
81
122
|
|
|
82
123
|
// Check attributes
|
|
83
|
-
expect(result.resource.attributes).
|
|
84
|
-
expect(result.resource.attributes[0].name).toBe("name");
|
|
124
|
+
expect(result.resource.attributes.map((a) => a.name)).toEqual(["name", "namespace", "uid", "status.instanceId", "status.selfLink"]);
|
|
85
125
|
});
|
|
86
126
|
|
|
87
127
|
test("parses StorageBucket CRD", () => {
|
package/src/spec/parse.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Adapts the K8s CRD parser pattern for GCP-specific concerns:
|
|
5
5
|
* - Type naming: GCP::{Service}::{Kind}
|
|
6
6
|
* - resourceRef detection
|
|
7
|
-
* - Status
|
|
7
|
+
* - Status fields skipped as props; scalar ones become attributes
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import yaml from "js-yaml";
|
|
@@ -212,6 +212,7 @@ function parseCRDSpec(spec: CRDSpec): GcpParseResult[] {
|
|
|
212
212
|
{ name: "name", tsType: "string" },
|
|
213
213
|
{ name: "namespace", tsType: "string" },
|
|
214
214
|
{ name: "uid", tsType: "string" },
|
|
215
|
+
...statusAttributes(schema?.properties?.status),
|
|
215
216
|
],
|
|
216
217
|
deprecatedProperties: [],
|
|
217
218
|
},
|
|
@@ -223,6 +224,21 @@ function parseCRDSpec(spec: CRDSpec): GcpParseResult[] {
|
|
|
223
224
|
return results;
|
|
224
225
|
}
|
|
225
226
|
|
|
227
|
+
/**
|
|
228
|
+
* The scalar top-level fields of a CRD's `status`, such as RunService's
|
|
229
|
+
* `status.uri` (#4179), as dotted attribute names. Config Connector fills them
|
|
230
|
+
* once the resource is ready, so they can't appear in the resource's own
|
|
231
|
+
* YAML, but another lexicon or an output can reference them.
|
|
232
|
+
*/
|
|
233
|
+
function statusAttributes(statusSchema: OpenAPISchema | undefined): ParsedAttribute[] {
|
|
234
|
+
const out: ParsedAttribute[] = [];
|
|
235
|
+
for (const [name, prop] of Object.entries(statusSchema?.properties ?? {})) {
|
|
236
|
+
if (prop.type !== "string" && prop.type !== "integer" && prop.type !== "number" && prop.type !== "boolean") continue;
|
|
237
|
+
out.push({ name: `status.${name}`, tsType: resolveSchemaType(prop) });
|
|
238
|
+
}
|
|
239
|
+
return out;
|
|
240
|
+
}
|
|
241
|
+
|
|
226
242
|
// ── Property extraction ─────────────────────────────────────────────
|
|
227
243
|
|
|
228
244
|
/**
|