enhance metrics part for resources - #3
Merged
Conversation
6 tasks
thzgajendra
added a commit
to thzgajendra/cloudemu
that referenced
this pull request
Jul 29, 2026
…nforcement Addresses the remaining LOW review items: - Read-side slice aliasing (LOW stackshy#1): Describe paths now copy their slice/map fields so a returned value never aliases the store — DescribeDBProxies (Targets/Auth/subnets/SGs), DescribeGlobalClusters (Members), DescribeDBClusterEndpoints (Static/Excluded), DescribeEventSubscriptions (SourceIDs/EventCategories), DescribeOptionGroups (Options), and the parameter-group Parameters maps. Adds a generic cloneSlice helper; consistent with the tags copy-on-read. - Parameter/option-group in-use enforcement (LOW stackshy#2): instances now carry DBParameterGroupName/OptionGroupName and clusters DBClusterParameterGroupName (parsed from the wire). Delete{,Cluster}ParameterGroup and DeleteOptionGroup refuse an in-use group (FailedPrecondition) and refuse the reserved default.* / default:* names. Not changed: conformance guards for ClusterEndpoints/ClusterFailover/ GlobalClusters/Metadata/Tagging already exist (var _ blocks in aurora.go / metadata.go) — the review's stackshy#3 was a false alarm. Remaining LOW fidelity nits (proxy RoleArn/Auth validation, global secondary attach, metric backfill, etc.) stay as documented follow-ups. New tests: parameter/option-group delete guards (in-use + default), copy-on-read regression. build/vet/gofmt/full test + -race green; golangci-lint clean.
thzgajendra
added a commit
that referenced
this pull request
Jul 29, 2026
* feat(rds): DB and DB cluster parameter groups Add parameter-group support to the RDS emulation as an optional ParameterGroups capability (mirroring the SubnetGroups pattern): create, describe, modify, delete, describe-parameters, reset, and copy — for both DB parameter groups and DB cluster parameter groups (14 actions). Only user-set parameters are modeled; the emulator does not fabricate the hundreds of engine defaults real AWS returns. Real AWS reuses the DBParameterGroup fault codes for the cluster variants, so error mapping is shared via a 'parameter group' message keyword. Covered by provider unit tests and aws-sdk-go-v2 SDK round-trip tests. * feat(rds): option groups Add option-group support as an optional OptionGroups capability: create, describe (with engine-name filter), modify (include/remove options), delete, copy, and describe-option-group-options (6 actions). DescribeOptionGroupOptions returns a small, representative per-engine catalog of well-known option names rather than fabricating AWS's exhaustive version-specific list. Covered by provider unit tests and SDK round-trip tests. * feat(rds): read replicas Add CreateDBInstanceReadReplica and PromoteReadReplica as an optional ReadReplicas capability. A replica inherits its source's engine, version and storage; the source tracks its replica identifiers and the replica records its source. Promotion detaches the replica (clears its source, removes it from the source's list). Instance XML now carries ReadReplicaSourceDBInstanceIdentifier and ReadReplicaDBInstanceIdentifiers. Covered by provider unit tests and SDK round-trip tests. * feat(rds): copy snapshot and point-in-time restore Add an optional AdvancedRestore capability: CopyDBSnapshot, CopyDBClusterSnapshot, RestoreDBInstanceToPointInTime, and RestoreDBClusterToPointInTime (4 actions). Copies clone the source snapshot's engine/version/storage under a new identifier; PITR clones the source instance/cluster's current spec into a new resource. The emulator has no historical timeline, so a point-in-time restore reflects the source as it is now; RestoreTime/UseLatestRestorableTime are accepted but not replayed. Covered by provider unit tests and SDK round-trip tests. * feat(rds): RDS Proxy Add RDS Proxy as an optional DBProxies capability: create, describe, modify, delete proxies; register/deregister targets; describe targets and target groups (8 actions). A proxy has a single implicit 'default' target group; targets may be RDS instances (RDS_INSTANCE) or clusters (TRACKED_CLUSTER), validated against existing resources on registration. Covered by provider unit tests and SDK round-trip tests. * feat(rds): event subscriptions, events, event categories Add an optional EventSubscriptions capability: create/describe/modify/delete event subscriptions, DescribeEvents, and DescribeEventCategories (6 actions). Enabled defaults to true on create (matching AWS). DescribeEventCategories returns AWS's published per-source-type categories. DescribeEvents returns an empty list by design: the emulator retains no event timeline, so there are truthfully no events for any window. Covered by provider unit tests and SDK round-trip tests. * feat(rds): Aurora custom endpoints, failover, and global clusters Add three optional Aurora capabilities (10 actions): - ClusterEndpoints: create/describe/modify/delete custom cluster endpoints. - ClusterFailover: FailoverDBCluster promotes the target member to writer (or rotates the first reader when no target is given). - GlobalClusters: create (optionally adopting a source cluster as writer), describe, modify (rename / engine version), delete, and remove-from. Covered by provider unit tests and SDK round-trip tests. * feat(rds): engine-version/orderable-option metadata and resource tagging Add two optional capabilities (5 actions): - Metadata: DescribeDBEngineVersions and DescribeOrderableDBInstanceOptions, backed by representative per-engine version and instance-class catalogs. - Tagging: AddTagsToResource, RemoveTagsFromResource, ListTagsForResource, addressed by resource ARN over the tag-bearing stores (instances, clusters, and instance/cluster snapshots). Covered by provider unit tests and SDK round-trip tests. * feat(discovery): surface RDS/Aurora in Resource Explorer (AWS) Issue #295 workstream A: RDS instances, Aurora clusters, and snapshots are emulated but were never enumerable via Resource Explorer. Add a RelationalDatabases discovery capability + neutral DiscoveredDatabase projection, a walkRelationalDB walker, and an rdsDiscovery adapter in the AWS provider (mirroring the Kubernetes eksDiscovery pattern, keeping services/ free of provider imports). Map rds<->relationaldb in the Resource Explorer 2 filter/handler so 'service:rds' narrows to these resources and their ResourceType/Service render correctly. Covered by an SDK indexing round-trip test. GCP Cloud SQL / Azure SQL discovery are deliberately out of scope here. * feat(rds): cost-tracker rates and enriched CloudWatch metrics Add relationaldb operation rates to the cost Tracker's rate catalog (instances and read replicas per instance-hour, RDS Proxy per hour; snapshots and Aurora cluster grouping free), consistent with how the other services populate the catalog. Enrich instance metric emission with FreeStorageSpace, ReadLatency, WriteLatency, and Network{Receive,Transmit}Throughput alongside the existing CPU/connections/memory/IOPS series; latency and throughput read zero when the instance is stopped. Covered by cost and metrics tests. * chore(rds): lint sweep + discovery cleanup Drop the write-only DiscoveredDatabase.Engine field; refactor the RDS error-code switches into ordered keyword->fault tables (keeps them under the gocyclo gate); wrap long signatures, fix cuddling/var-naming/receiver/goconst, and annotate the intentional per-resource duplication. Full build/vet/gofmt and the whole test suite pass; golangci-lint clean on the touched packages. * docs(rds): document new RDS capabilities and discovery surfacing Update services.md section 17 with the 11 new optional capability interfaces and their operations (parameter/option groups, read replicas, snapshot copy/PITR, RDS Proxy, event subscriptions, Aurora endpoints/failover/global clusters, metadata, tagging), refresh the totals, and note AWS RDS discovery through Resource Explorer 2 in section 19 (and features.md). * fix(rds): review — concurrency, delete guards, slice aliasing Address PR review (both HIGH + the MEDIUM aliasing set): HIGH - Concurrent-map-write panic on Tags/Parameters: copy-on-read in the Describe paths (instances/clusters/snapshots tags; parameter groups) and replace-on-write in the mutators (AddTags/RemoveTags build a fresh map; parameter Modify/Reset build a fresh map), mirroring ModifyInstance. Add a go test -race concurrency test (Describe + caller iteration vs tag/param writes). - DeleteInstance now refuses (FailedPrecondition) while the instance still has read replicas. MEDIUM - DeleteInstance strips a deleted replica from its source's target list; make removeString non-mutating so it never corrupts a slice a Describe handed out. - DeleteGlobalCluster refuses while members remain. - Fresh-slice rebuilds (no in-place [:0]/append into aliased backing arrays) in DeregisterDBProxyTargets, RegisterDBProxyTargets, RemoveFromGlobalCluster, ModifyOptionGroup. - DeleteDBSubnetGroup takes m.mu across the in-use scan + delete. - Preserve per-parameter ApplyMethod (store map[string]Parameter). LOW - Deterministic tag XML ordering; DescribeEventCategories/PITR return copied slices; PITR clears ClusterID; SubnetGroups conformance guard; subnet-group ARN via idgen. New tests: -race concurrency; delete-blocked-by-replica; delete-global-with- members; ApplyMethod round-trip. * fix(rds): review LOW — read-side slice copies + param/option in-use enforcement Addresses the remaining LOW review items: - Read-side slice aliasing (LOW #1): Describe paths now copy their slice/map fields so a returned value never aliases the store — DescribeDBProxies (Targets/Auth/subnets/SGs), DescribeGlobalClusters (Members), DescribeDBClusterEndpoints (Static/Excluded), DescribeEventSubscriptions (SourceIDs/EventCategories), DescribeOptionGroups (Options), and the parameter-group Parameters maps. Adds a generic cloneSlice helper; consistent with the tags copy-on-read. - Parameter/option-group in-use enforcement (LOW #2): instances now carry DBParameterGroupName/OptionGroupName and clusters DBClusterParameterGroupName (parsed from the wire). Delete{,Cluster}ParameterGroup and DeleteOptionGroup refuse an in-use group (FailedPrecondition) and refuse the reserved default.* / default:* names. Not changed: conformance guards for ClusterEndpoints/ClusterFailover/ GlobalClusters/Metadata/Tagging already exist (var _ blocks in aurora.go / metadata.go) — the review's #3 was a false alarm. Remaining LOW fidelity nits (proxy RoleArn/Auth validation, global secondary attach, metric backfill, etc.) stay as documented follow-ups. New tests: parameter/option-group delete guards (in-use + default), copy-on-read regression. build/vet/gofmt/full test + -race green; golangci-lint clean. * fix(rds): review — Modify can re-point/release param & option groups Addresses the re-review of the LOW-fix commit. MEDIUM — the new in-use enforcement could strand a group: a group attached at Create could only be released by deleting the instance/cluster. Add DBParameterGroupName/OptionGroupName (instance) and DBClusterParameterGroupName (cluster) to ModifyInstanceInput and wire the modify handlers, so re-pointing an instance/cluster to a new group releases the old one (which then deletes). LOW: - Finish read-side copies: DescribeInstances (VPCSecurityGroups, ReadReplicaTargets), DescribeClusters (Members, VPCSecurityGroups), and DescribeDBSubnetGroups (SubnetIDs) now return independent copies too, so the 'every Describe path copies its slice/map fields' contract actually holds. - Create{,Cluster}ParameterGroup / CreateOptionGroup reject the reserved default. / default: prefixes so a user can't self-inflict an undeletable group. - DescribeOptionGroups deep-copies Option.Settings (cloneSlice was shallow). Tests: Modify re-point/release for instance param, cluster param, and option groups; reserved-name rejection on create; copy-on-read across the list-all and named branches for proxies and instances.
Merged
4 tasks
thzgajendra
added a commit
to thzgajendra/cloudemu
that referenced
this pull request
Jul 29, 2026
Address review MEDIUM stackshy#2/stackshy#3/stackshy#4 (Azure update paths) and stackshy#7 (MI discovery): - PUT on an existing Azure SQL server / database / managed instance now applies the request body (upsert) instead of returning the stale record. - PATCH is a genuine merge — elastic pools, failover groups and managed instances gain Update* capability methods that overlay only the fields the request supplied, so a partial PATCH no longer wipes unspecified fields; MI PATCH now decodes and applies its body instead of being a no-op. - Managed instances are projected into cross-service discovery (microsoft.sql/managedinstances) via sqlDiscovery + the Resource Graph type map, so a created MI appears in inventory. Covered by SDK PATCH-merge round-trip tests (elastic pool keeps its SKU when only maxSizeBytes is patched; MI keeps administratorLogin when only vCores is patched) and a managed-instance type-map test.
This was referenced Jul 30, 2026
thzgajendra
added a commit
that referenced
this pull request
Jul 30, 2026
…xible Server, Cloud SQL) (#303) * feat(azure): full parity for Azure MySQL Flexible Server sub-resources Add databases, firewall rules and server configurations plus the server failover action to Azure Database for MySQL Flexible Server, bringing it to native parity with the ARM surface real armmysqlflexibleservers clients use. Introduce Databases, FirewallRules, Configurations and Failover as optional relationaldb driver capabilities (mirroring SubnetGroups), so the same interfaces are reusable by the other managed-SQL services. The mock stores each family per server and cascade-deletes children on server delete; the ARM handler routes databases/firewallRules/configurations, updateConfigurations (batch) and the failover action. Covered by real-SDK round-trip tests and mock-level error-path/cascade tests. * feat(azure): full parity for Azure PostgreSQL Flexible Server sub-resources Add databases, firewall rules and server configurations to Azure Database for PostgreSQL Flexible Server, reusing the Databases/FirewallRules/Configurations optional relationaldb capabilities introduced for MySQL Flex. Postgres Flex has no failover action and no batch-configuration endpoint, and its configuration resource accepts both PUT and PATCH; the handler and mock reflect that. The mock cascade-deletes children on server delete. Covered by real-SDK round-trip tests (the SDK has no ClientFactory, so each client is built from shared options) plus mock-level default/error/cascade tests. * feat(azure): full parity for Azure SQL server sub-resources Add firewall rules, virtual-network rules, elastic pools, failover groups and the Azure AD administrator to Azure SQL (Microsoft.Sql). Firewall rules reuse the shared FirewallRules capability; the other four are added as optional relationaldb capabilities (VNetRules, ElasticPools, FailoverGroups, AADAdmins) alongside the existing SubnetGroups pattern. Failover-group failover flips the local replication role between Primary and Secondary. The mock cascade-deletes all child resources on server delete and returns isolated copies of the slice-bearing failover-group state. Covered by real-SDK (armsql) round-trip tests across all five families plus mock-level error/cascade/aliasing tests. * feat(gcp): full parity for Cloud SQL databases, users, certs and instance ops Add databases (via the shared Databases capability), users and client SSL certs as instance child resources, plus the clone, failover, promote-replica and start/stop-replica instance actions to GCP Cloud SQL. Users and SSL certs are new optional relationaldb capabilities (Users, SslCerts); clone and replica promotion are Clonable and ReplicaPromotion; failover reuses the shared Failover capability. The REST path parser now recognizes the databases/users/sslCerts sub-collections, and the users route honors Cloud SQL's ?name= query quirk for delete and update. The mock cascade-deletes children on instance delete. Tiers and flags catalogs are intentionally out of scope (separate path shapes, static data). Covered by real sqladmin SDK round-trip tests plus mock-level clone/cascade/error tests. * feat(discovery): surface managed SQL servers in Resource Graph and Cloud Asset Add a RelationalDatabases discovery capability to the resource-discovery engine and a walkRelationalDB walker, mirroring the Kubernetes adapter pattern. Azure wires an adapter that projects Azure SQL logical servers plus MySQL/PostgreSQL Flexible Servers, and GCP projects Cloud SQL instances, so managed relational databases appear in cross-service inventory. Resource Graph maps the portable types to microsoft.sql/servers, microsoft.dbformysql/flexibleservers and microsoft.dbforpostgresql/flexibleservers; Cloud Asset maps Cloud SQL to sqladmin.googleapis.com/Instance. Both type-map switches become lookup tables to stay under the cyclomatic-complexity gate. Covered by walker and type-map tests. * feat(cost): add managed relational-database rates Add relationaldb:* entries to the cost rate catalog so provisioning a managed database server/instance (RDS, Azure SQL, Azure MySQL/PostgreSQL Flexible Server, Cloud SQL) is billed per instance-hour, clusters per cluster-hour, and restores reuse the instance-hour, while snapshots and lifecycle actions are free. The portable "relationaldb" service name means one catalog covers every cloud. Covered by a cost-tracker test. * docs: document full managed-SQL parity (sub-resources, discovery, cost) Document the native sub-resource capabilities added to Azure SQL, the Azure MySQL/PostgreSQL Flexible Servers and Cloud SQL — databases, users, firewall/ vnet rules, configurations, elastic pools, failover groups, AAD admins, SSL certs, clone/failover/replica actions — along with their discovery surfacing and cost rates. Refresh the relational-database operation totals and the discovery driver list. * feat(sql): Cloud SQL tiers/flags catalogs + elastic-pool metrics Close the remaining managed-SQL parity gaps: serve the Cloud SQL machine-tier catalog (GET /v1/projects/{p}/tiers) and the database-flag catalog (GET /v1/flags, which is project-less) as static reference data, and emit Microsoft.Sql/servers/elasticpools metrics (cpu/storage/workers percent) when an Azure SQL elastic pool is created. Also annotate the ModifyInstance/ModifyCluster methods across the four SQL mocks with the driver-interface hugeParam nolint now that the shared ModifyInstanceInput grew. Covered by SDK tiers/flags round-trip and an elastic-pool metric-emission test. * feat(azure): add SQL Managed Instance family to Azure SQL Add the Microsoft.Sql/managedInstances resource type and its managed databases as a ManagedInstances optional relationaldb capability: managed-instance CRUD + list + start/stop/failover actions, and managed-database CRUD + list. The handler now matches the managedInstances resource type alongside servers and routes both, and the mock cascade-deletes managed databases when their instance is removed. Covered by an armsql managed-instance/database SDK round-trip test (create → get → list → failover → cascade delete) and a mock-level lifecycle test. * docs: document managed instances, tiers/flags and elastic-pool metrics Update the relational-database section for the now-complete managed-SQL parity: add the ManagedInstances capability row, note Cloud SQL's tiers/flags reference catalogs and Azure SQL's Managed Instance family, and record the elastic-pool metric namespace. Refresh the optional-operation totals (25 capability interfaces, +109 relational / +118 grand-total optional). * fix(sql): clone ManagedInstance tags on read; deterministic list ordering Address review MEDIUM #1 and the list-ordering LOW: GetManagedInstance / ListManagedInstances now clone the stored Tags map so a caller mutating the returned map can't corrupt the store (the copy-on-read hole flagged as the concurrent-map panic class), and every List* mock method iterates memstore.SortedValues() instead of All() for deterministic SDK list ordering, matching the documented convention. Large-value list loops use index iteration to avoid per-element copies. * fix(azure): real update semantics + discoverable managed instances Address review MEDIUM #2/#3/#4 (Azure update paths) and #7 (MI discovery): - PUT on an existing Azure SQL server / database / managed instance now applies the request body (upsert) instead of returning the stale record. - PATCH is a genuine merge — elastic pools, failover groups and managed instances gain Update* capability methods that overlay only the fields the request supplied, so a partial PATCH no longer wipes unspecified fields; MI PATCH now decodes and applies its body instead of being a no-op. - Managed instances are projected into cross-service discovery (microsoft.sql/managedinstances) via sqlDiscovery + the Resource Graph type map, so a created MI appears in inventory. Covered by SDK PATCH-merge round-trip tests (elastic pool keeps its SKU when only maxSizeBytes is patched; MI keeps administratorLogin when only vCores is patched) and a managed-instance type-map test. * fix(azure): model Azure SQL database elastic-pool membership Address review MEDIUM #5. Databases now carry an ElasticPoolID (added to the shared InstanceConfig/Instance/ModifyInstanceInput and surfaced as the elasticPoolId ARM database property), so an SDK client placing a database into a pool round-trips instead of silently dropping it. DeleteElasticPool now returns a precondition error while the pool still contains databases, matching real Azure's 409. Covered by a membership/delete-guard test. * fix(gcp): real Cloud SQL read-replica and failover semantics Address review MEDIUM #6. A Cloud SQL insert with masterInstanceName now creates an actual read replica: the replica records its master (ReadReplicaSource) and the primary lists it (replicaNames), both surfaced in the instance body. Replica lifecycle is faithful — start/stopReplica require the target to be a replica and leave it RUNNABLE (no SUSPENDED state change); promoteReplica detaches it from the primary (and rejects a non-replica); failover is a primary-only operation and rejects a replica. Covered by SDK and mock replica-lifecycle tests. * fix(sql): review LOW items — determinism, validation, replica fidelity tests - Cloud SQL backup-run IDs are generated by the mock from the clock + a monotonic counter (was time.Now().UnixNano(), violating the Clock determinism rule and collision-prone); CloneInstance now clones the source's databases and resets replica linkage; UpdateUser doc corrected. - Firewall rules validate IPv4 start/end (Azure SQL + both Flexible Servers); Azure SQL Managed Instance requires subnetId, as real Azure does. - Added a real-SDK Resource Graph indexing test that drives sqlDiscovery end-to-end (logical server + managed instance appear and filter), and a -race concurrency test that mutates a returned managed-instance Tags map to pin the copy-on-read fix. * fix(sql): address second review — MI lifecycle, in-place restore, validation - Cloud SQL DeleteInstance now unlinks replica<->master before cascading children, so no dangling ReadReplicaSource/ReadReplicaTargets remain. - Managed Instance lifecycle gains a state guard (transitionManagedInstance): Start/Stop respect current state, Failover requires Ready; MI create emits representative metrics and clones returned Tags; adds CreateManagedInstance cost rate. - Cloud SQL RestoreBackup restores in place onto the existing instance via a new optional BackupRestorer capability (was create-new -> 409). - Failover-group failover requires a partner server; firewall rules validate Start <= End; Azure Flex SetConfiguration rejects unknown params and empty values; ARM parser captures the action verb so forced vs planned failover and unknown POST verbs are distinguished; Cloud SQL selfLink/targetLink use the served /v1 prefix. - Broaden new-package test coverage (sub-resource CRUD, MI lifecycle, Users update, backup get, error paths, server PATCH, raw MI start/stop). * fix(sql): address third review — output aliasing, config catalog, validation - Deep-copy Tags/slice fields on every Instance/Cluster/Snapshot return path in azuresql and cloudsql (Describe/Create/Modify/Restore/Clone), so a returned value never aliases the memstore — fixes a potential concurrent-map crash and matches the managedinstance/FailoverGroup discipline. - Azure Flex GetConfiguration/ListConfigurations return catalog defaults for a known-but-unset parameter (real Azure behavior) instead of NotFound/empty; the catalog now maps names to defaults. - MySQL Flex batch config update is atomic: all entries are validated before any is applied, via a new optional BatchConfigurations capability. - Azure SQL database create/modify validates the referenced elastic pool exists (symmetry with the pool-delete member guard). - Cloud SQL rejects child (database/user) names containing '/' that would orphan a row; get-paths add length guards on single-ID Describe lookups. - Flex firewall create validates start <= end (parity with Azure SQL). - Tests: aliasing, config defaults, batch atomicity, elastic-pool validation, child-name rejection, FG update/list, managed-database delete, and Azure wire-level error-mapping (404/400) across all three Azure SQL services.
NitinKumar004
added a commit
that referenced
this pull request
Jul 30, 2026
…ocs) From thzgajendra's review of PR #299: - Lint (#1): replace the version-sensitive //nolint:prealloc directives with real preallocation (coreResources/appsResources/registryAPIResources, openapi kinds, endpoint-address slice), so golangci-lint is clean regardless of prealloc's version-dependent placement — no dangling directives. - Docs (#2): drop the 'pagination' claim from the k8s data-plane sentence in sdk-server.md; data-plane lists are unpaginated, matching services.md. - Watch load-shedding (#3): a slow watcher that overflows its buffer now receives a 410 Gone (ERROR) event and the stream ends, so client-go relists instead of running with a permanently-divergent cache. Regression test added. - GC comment (#4): correct the 'never mutate while ranging' wording — deleting the current key mid-range is legal; the BFS is what makes the cascade order-independent. - Provider package headers (#8): describe the now-wired data plane instead of 'out of scope / Wave 2'. Deferred as documented follow-ups (all Low): clamp/silent-signal, Job shrink reconcile, committed kubectl smoke test, provider CA-vs-sentinel misconfig window.
NitinKumar004
added a commit
that referenced
this pull request
Jul 30, 2026
…upport (#299) * feat(k8s): connect parity across EKS/AKS/GKE via a shared CA (Phase A) The data-plane serving cert and every provider's advertised CA must be the same authority or client-go's TLS handshake fails. Extract the CA into a new internal/k8spki package used by both the serving TLS config and all three control planes: - EKS: tls.go now delegates to k8spki (serve + EKS call sites unchanged). - GKE: advertise the real CA in masterAuth.clusterCaCertificate; drop the unparseable dummy blob that broke the handshake outright. - AKS: embed the real CA in the rendered kubeconfig and drop insecure-skip-tls-verify — parity with EKS/GKE. Tests: AKS data-plane test now serves with the k8spki cert and validates end-to-end (no skip-verify); new GKE real-TLS connect-parity test proves the advertised CA certifies the endpoint (create cluster -> validate CA -> client-go ConfigMap round-trip). RenderKubeconfig test updated to the real-CA behavior. First phase of the k8s runtime/parity work; registry refactor + reconcile engine + workload kinds follow on this branch. * feat(k8s): parse resource subresources in the router (Phase B foundation) Add Route.Subresource and parse the /{name}/{subresource} tail for both cluster-scoped (/api/v1/nodes/n/status) and namespaced (/apis/apps/v1/namespaces/ns/deployments/d/scale) shapes. ServeHTTP routes subresource requests to a dedicated dispatcher (stubbed to 404 until the reconcile phase wires /status and /scale) so a subresource path is never mis-parsed as a write against the parent object. Updated the parseRoute unit test to the new (correct) cluster-subresource semantics. * feat(k8s): generic resource registry + reconcile engine (Phases B+C) Turn the k8s data plane from a CRUD store into a minikube-like runtime. Registry (registry.go, registry_ops.go, registry_defs.go): a generic unstructured-backed store + one handler serving CRUD, list (label & field selectors), watch, patch, delete (ownerReference garbage collection), and the /status + /scale subresources for any registered kind. New kinds are a registration + optional reconcile hook. Registers apps/v1 ReplicaSet, StatefulSet, DaemonSet and core/v1 PersistentVolumeClaim; discovery is derived from the registry so it can't drift. Reconcile engine (reconcile.go), run synchronously on every write (no controller goroutines, so it stays deterministic): - Pods are driven Running with a synthetic Pod IP and ready containers. - Deployment materializes its Pods and reports real status; ReplicaSet and DaemonSet do likewise; StatefulSet creates stable-ordinal Pods (name-0..N-1) plus a Bound PVC per volumeClaimTemplate. - The endpoints controller fills a Service's Endpoints from the Running Pods matching its selector, and drains them when Pods are deleted/GC'd. - Deleting a controller cascades to its Pods; scaling (spec.replicas or the /scale subresource) adjusts the Pod count. Typed handlers: Deployment now reconciles + serves /scale and /status; direct Pod creates come up Running; Pod list honors label/field selectors; Service create populates endpoints. Tests: new client-go WorkloadRuntime E2E (Deployment+Service -> Running pods + endpoints -> scale to 4 -> StatefulSet with 3 stable pods + 3 Bound PVCs -> DaemonSet -> cascade teardown). Existing pod/cascade/provider tests updated to the new Running/materialized behavior. Deployment /scale + /status advertised in discovery. Deferred to later phases: the intermediate ReplicaSet object for Deployments (pods are owned by the Deployment directly); Job/CronJob, Ingress, RBAC, HPA, Node, Event, NetworkPolicy, EndpointSlice; strategic-merge / server-side-apply. * k8s: register batch/networking/rbac/storage/autoscaling/discovery + core supporting kinds; registry-driven discovery Adds registry entries for Job/CronJob, Ingress/IngressClass/NetworkPolicy, RBAC (Role/RoleBinding/ClusterRole/ClusterRoleBinding), StorageClass, HorizontalPodAutoscaler, EndpointSlice, and core PVC/PV/Node/Event/ ResourceQuota/LimitRange. Reconcile hooks drive Job pods to Succeeded, Ingress to a load-balancer IP, and PV to Available/Bound. serveDiscovery now derives the /apis group list and every /apis/<group>/<version> resource list from registeredResources() (seeded with the typed apps/policy groups) instead of a hardcoded switch, so new groups and their subresources are discoverable by kubectl and client-go without drifting from what the server serves. * test(k8s): e2e coverage for supporting kinds via client-go Drives Jobs (complete to Succeeded with materialized pods), Ingresses (get a load-balancer IP), PVCs (bind), StorageClass/RBAC/HPA/Node round-trips, and asserts the new API groups are discoverable — the negotiation kubectl and client-go do before any typed request. * k8s: rolling updates replace Pods on pod-template change; advertise endpoints - Controllers stamp a pod-template-hash label on Pods; reconcile treats a changed template hash as a rolling update and replaces stale-hash Pods (Deployment/ReplicaSet via syncScaledPods, StatefulSet via syncStablePods). Convergence is instant — no surge/unavailable pacing. - buildControllerPod now copies the template label map before stamping, so it can't mutate the controller's shared template. - Discovery advertises core/v1 endpoints (get/list/watch only, matching the read-only handler) so kubectl/client-go can resolve them. E2E: runtime test now exercises a rolling update (image change replaces all Pods, endpoints re-point); supporting-kinds test asserts endpoints discovery. * docs(k8s): document the minikube-like data plane and its non-goals Update services.md §18, sdk-server.md, and the package doc to reflect the reconcile engine (Running Pods, Endpoints, binding PVCs, completing Jobs), validated TLS via the shared CA, the full multi-group resource surface with /scale and /status subresources, rolling updates, and the deliberate emulation boundaries (no exec/logs/portforward, no scheduling, no quota/RBAC/policy enforcement, no HPA/CronJob actuation). * fix(k8s): merge-patch to /scale no longer silently scales to zero applyUnstructuredPatch decoded the merged JSON with plain json.Unmarshal into map[string]any, which turns whole-number JSON into float64. unstructured.NestedInt64 accepts only int64, so spec.replicas read back as 0 — a 'kubectl scale --replicas=N' (a merge-patch to the /scale subresource, or any merge-patch touching replicas) silently scaled the workload to zero. Decode via unstructured.Unstructured.UnmarshalJSON instead, which preserves integers as int64. This fixes every merge-patch path (object and /scale) at the root. Regression test drives a merge-patch scale-up and asserts both the returned Scale and the stored object carry replicas=4. * fix(k8s): address review findings across reconcile, GC, endpoints, PKI - Endpoints: only bump ResourceVersion / publish MODIFIED when the address set actually changes. resyncEndpointsForNamespaceLocked runs for every Service on any Pod change, so an unchanged Service was emitting a spurious watch event (with a climbing RV) on unrelated Pod churn. Regression test added. - Pod field selector: support spec.nodeName. Every materialized Pod is scheduled to the synthetic node, so 'kubectl get pods --field-selector spec.nodeName=...' (node-drain/kubelet tooling) previously returned an empty list. E2E covers it. - Garbage collection: walk the owned set breadth-first and collect UIDs before deleting, instead of mutating each store's map while ranging it and recursing. Pods owned by an intermediate controller (not just the root) are now reaped. - Scale subresource: only bump generation when spec.replicas actually changes, matching registryUpdate/registryPatch (no spurious generation != observed). - Job: ignore a non-positive spec.completions (default to 1) so a Job can't report Complete having run zero Pods. - StatefulSet PVCs: deep-copy the volumeClaimTemplate spec per ordinal instead of aliasing one map across every PVC. - PKI: give each serving leaf a random 128-bit serial (was fixed '2') and assert BasicConstraintsValid (cA=FALSE) so strict non-Go verifiers accept the leaf. - docs: correct the data-plane list to say it is unpaginated (limit/continue are not honored) and scope field-selector support accurately. * k8s: real-user kubectl parity — protobuf writes, OpenAPI v2/v3, strategic & JSON patch Driving a running cloudemu server with real kubectl (cluster created via the EKS/GKE/AKS SDK, then kubectl against the advertised endpoint) surfaced gaps the JSON-forcing client-go tests masked. kubectl now works end-to-end. - Protobuf request bodies: kubectl sends built-in kinds as protobuf on writes and does NOT retry as JSON on 415, so every 'kubectl create/apply/scale' write failed. Decode protobuf via the client-go scheme's recognizing deserializer (typed handlers decode in place; registry handlers convert to unstructured). Responses stay JSON — clients' Accept allows it. - OpenAPI: serve a v3 discovery root + per-group docs that carry each served GVK (with a permissive schema) so kubectl resolves the kind and stays on the JSON v3 path; and serve the legacy v2 doc as protobuf bytes (mime-safe application/octet-stream content type) for the fallback. Without this 'kubectl apply' died at 'failed to download openapi'. Served cluster-independently in APIServer.ServeHTTP so the prefix-less v3 serverRelativeURL follow-ups resolve. - Patch types: typed handlers now accept strategic-merge-patch (kubectl's default for set/edit/label — real strategic merge, so the container list merges by name) and JSONPatch (RFC 6902), in addition to merge-patch; registry handlers gain JSONPatch too. - Discovery: advertise kubectl short names (pvc, hpa, sts, ds, rs, ing, sc, …) for registry kinds so 'kubectl get pvc' resolves. Verified with real kubectl v1.36 against a standalone server: full lifecycle (apply → scale → rolling update → statefulset/PVCs → daemonset → job → cronjob → ingress → hpa → pv/pvc/storageclass → rbac → networkpolicy → node → all three patch types → cascade teardown) across EKS, GKE, and AKS connect paths. * docs(k8s): note full kubectl parity (protobuf, OpenAPI, all patch types) * k8s: drop len()+1 map capacity hint (clears CodeQL allocation-overflow alert) * k8s: filter watch streams by label/field selector (review blocker) Watch streams ignored labelSelector/fieldSelector: typed watches (watchPods, watchDeployments, …) filtered neither initial nor streamed events, and the registry watch filtered only the initial snapshot. A selective watch ('kubectl get pods -l app=x -w', or any informer/controller-runtime cache built with a selector) therefore received non-matching objects — polluting reflector caches and firing spurious reconciles, which the reconcile engine amplifies (one Deployment emits many Pod events). streamWatch now takes a keep(T) predicate applied to both the initial snapshot and every streamed event; each watch handler builds it from the request's selectors (parseListSelectors + metaFieldsMatch/podMatchesFields/matchesFields). Also extracts field-selector-name constants (fixes goconst) and indexes filterPods to avoid per-item Pod copies. * k8s: cap materialized pods, bootstrap Node, mirror EndpointSlices, resync endpoints on pod update/patch Correctness gaps from the PR review: - Unbounded replicas/completions: the reconciler runs synchronously under the cluster lock, so a huge spec value would allocate/hang the whole API. Clamp the materialized Pod count to maxReconciledPods (500) for Deployment, ReplicaSet/StatefulSet (via replicasOf), and Job. reconcileJob's top-up is also made O(n) instead of O(n²). - Synthetic Node: bootstrap cloudemu-node-0 (Ready, InternalIP) in newClusterState so 'kubectl get nodes' is non-empty and the node every Pod is scheduled onto actually exists. - EndpointSlices: mirror each Service's endpoints into a discovery.k8s.io EndpointSlice (labelled kubernetes.io/service-name) so EndpointSlice-mode consumers (kube-proxy, Gateway API) see the same backends as Endpoints. - Pod update/patch now resync endpoints (a label change matching a Service selector was invisible until unrelated churn) and re-drive a spec-only PUT back to Running so it isn't dropped out of the endpoint set. reconcileServiceEndpointsLocked is split into matchingEndpointAddressesLocked / writeEndpointsLocked / syncEndpointSliceLocked (also lowers its complexity). E2E asserts the synthetic Node and populated EndpointSlices; a new watch test asserts label-selector stream filtering. * k8s: dedup watch handlers + resolve golangci-lint to zero (review blocker) - All 8 typed watch handlers now share a generic serveWatch[T] helper (removes the dupl the near-identical subscribe/snapshot/stream blocks triggered, and addresses the reuse the review flagged). - golangci-lint (repo .golangci.yml, v2.11.4) is clean on the new non-test files: extracted goconst constants (api/apis path segments, status/scale subresources, group names), named crypto/mnd magic numbers in k8spki, gave parseListSelectors named results, indexed the container-status range, lowered ServeHTTP/serveRegistry complexity via dispatchResource / serveRegistryItem, fixed the govet shadow, and added reasoned //nolint for the legitimately-global lookup tables and hugeParam k8s structs. No behavior change; build, vet, tests, and -race remain green. * k8s: bump Deployment generation on spec change; unify /scale patch types - Typed Deployment now sets metadata.generation=1 on create and advances it only on a spec change (update/patch), matching apiserver semantics and the registry path so observedGeneration comparisons are meaningful. - deploymentScale PATCH routes through the shared applyPatchBytes dispatcher, so the typed /scale honors merge / strategic-merge / JSONPatch like the registry /scale (the two paths no longer diverge). - Tidy a stale AKS kubeconfig comment (Phase 3 -> the normal path). * docs(k8s): note watch selector filtering, synthetic node, EndpointSlice mirroring * k8s: address second-review findings (lint robustness, watch relist, docs) From thzgajendra's review of PR #299: - Lint (#1): replace the version-sensitive //nolint:prealloc directives with real preallocation (coreResources/appsResources/registryAPIResources, openapi kinds, endpoint-address slice), so golangci-lint is clean regardless of prealloc's version-dependent placement — no dangling directives. - Docs (#2): drop the 'pagination' claim from the k8s data-plane sentence in sdk-server.md; data-plane lists are unpaginated, matching services.md. - Watch load-shedding (#3): a slow watcher that overflows its buffer now receives a 410 Gone (ERROR) event and the stream ends, so client-go relists instead of running with a permanently-divergent cache. Regression test added. - GC comment (#4): correct the 'never mutate while ranging' wording — deleting the current key mid-range is legal; the BFS is what makes the cascade order-independent. - Provider package headers (#8): describe the now-wired data plane instead of 'out of scope / Wave 2'. Deferred as documented follow-ups (all Low): clamp/silent-signal, Job shrink reconcile, committed kubectl smoke test, provider CA-vs-sentinel misconfig window.
thzgajendra
added a commit
that referenced
this pull request
Jul 31, 2026
* feat(azure): full parity for Azure MySQL Flexible Server sub-resources
Add databases, firewall rules and server configurations plus the server
failover action to Azure Database for MySQL Flexible Server, bringing it to
native parity with the ARM surface real armmysqlflexibleservers clients use.
Introduce Databases, FirewallRules, Configurations and Failover as optional
relationaldb driver capabilities (mirroring SubnetGroups), so the same
interfaces are reusable by the other managed-SQL services. The mock stores each
family per server and cascade-deletes children on server delete; the ARM handler
routes databases/firewallRules/configurations, updateConfigurations (batch) and
the failover action. Covered by real-SDK round-trip tests and mock-level
error-path/cascade tests.
* feat(azure): full parity for Azure PostgreSQL Flexible Server sub-resources
Add databases, firewall rules and server configurations to Azure Database for
PostgreSQL Flexible Server, reusing the Databases/FirewallRules/Configurations
optional relationaldb capabilities introduced for MySQL Flex. Postgres Flex has
no failover action and no batch-configuration endpoint, and its configuration
resource accepts both PUT and PATCH; the handler and mock reflect that. The mock
cascade-deletes children on server delete. Covered by real-SDK round-trip tests
(the SDK has no ClientFactory, so each client is built from shared options) plus
mock-level default/error/cascade tests.
* feat(azure): full parity for Azure SQL server sub-resources
Add firewall rules, virtual-network rules, elastic pools, failover groups and
the Azure AD administrator to Azure SQL (Microsoft.Sql). Firewall rules reuse
the shared FirewallRules capability; the other four are added as optional
relationaldb capabilities (VNetRules, ElasticPools, FailoverGroups, AADAdmins)
alongside the existing SubnetGroups pattern. Failover-group failover flips the
local replication role between Primary and Secondary. The mock cascade-deletes
all child resources on server delete and returns isolated copies of the
slice-bearing failover-group state. Covered by real-SDK (armsql) round-trip
tests across all five families plus mock-level error/cascade/aliasing tests.
* feat(gcp): full parity for Cloud SQL databases, users, certs and instance ops
Add databases (via the shared Databases capability), users and client SSL certs
as instance child resources, plus the clone, failover, promote-replica and
start/stop-replica instance actions to GCP Cloud SQL. Users and SSL certs are
new optional relationaldb capabilities (Users, SslCerts); clone and replica
promotion are Clonable and ReplicaPromotion; failover reuses the shared Failover
capability. The REST path parser now recognizes the databases/users/sslCerts
sub-collections, and the users route honors Cloud SQL's ?name= query quirk for
delete and update. The mock cascade-deletes children on instance delete. Tiers
and flags catalogs are intentionally out of scope (separate path shapes, static
data). Covered by real sqladmin SDK round-trip tests plus mock-level
clone/cascade/error tests.
* feat(discovery): surface managed SQL servers in Resource Graph and Cloud Asset
Add a RelationalDatabases discovery capability to the resource-discovery engine
and a walkRelationalDB walker, mirroring the Kubernetes adapter pattern. Azure
wires an adapter that projects Azure SQL logical servers plus MySQL/PostgreSQL
Flexible Servers, and GCP projects Cloud SQL instances, so managed relational
databases appear in cross-service inventory. Resource Graph maps the portable
types to microsoft.sql/servers, microsoft.dbformysql/flexibleservers and
microsoft.dbforpostgresql/flexibleservers; Cloud Asset maps Cloud SQL to
sqladmin.googleapis.com/Instance. Both type-map switches become lookup tables to
stay under the cyclomatic-complexity gate. Covered by walker and type-map tests.
* feat(cost): add managed relational-database rates
Add relationaldb:* entries to the cost rate catalog so provisioning a managed
database server/instance (RDS, Azure SQL, Azure MySQL/PostgreSQL Flexible
Server, Cloud SQL) is billed per instance-hour, clusters per cluster-hour, and
restores reuse the instance-hour, while snapshots and lifecycle actions are
free. The portable "relationaldb" service name means one catalog covers every
cloud. Covered by a cost-tracker test.
* docs: document full managed-SQL parity (sub-resources, discovery, cost)
Document the native sub-resource capabilities added to Azure SQL, the Azure
MySQL/PostgreSQL Flexible Servers and Cloud SQL — databases, users, firewall/
vnet rules, configurations, elastic pools, failover groups, AAD admins, SSL
certs, clone/failover/replica actions — along with their discovery surfacing and
cost rates. Refresh the relational-database operation totals and the discovery
driver list.
* feat(sql): Cloud SQL tiers/flags catalogs + elastic-pool metrics
Close the remaining managed-SQL parity gaps: serve the Cloud SQL machine-tier
catalog (GET /v1/projects/{p}/tiers) and the database-flag catalog
(GET /v1/flags, which is project-less) as static reference data, and emit
Microsoft.Sql/servers/elasticpools metrics (cpu/storage/workers percent) when an
Azure SQL elastic pool is created. Also annotate the ModifyInstance/ModifyCluster
methods across the four SQL mocks with the driver-interface hugeParam nolint now
that the shared ModifyInstanceInput grew. Covered by SDK tiers/flags round-trip
and an elastic-pool metric-emission test.
* feat(azure): add SQL Managed Instance family to Azure SQL
Add the Microsoft.Sql/managedInstances resource type and its managed databases
as a ManagedInstances optional relationaldb capability: managed-instance CRUD +
list + start/stop/failover actions, and managed-database CRUD + list. The
handler now matches the managedInstances resource type alongside servers and
routes both, and the mock cascade-deletes managed databases when their instance
is removed. Covered by an armsql managed-instance/database SDK round-trip test
(create → get → list → failover → cascade delete) and a mock-level lifecycle
test.
* docs: document managed instances, tiers/flags and elastic-pool metrics
Update the relational-database section for the now-complete managed-SQL parity:
add the ManagedInstances capability row, note Cloud SQL's tiers/flags reference
catalogs and Azure SQL's Managed Instance family, and record the elastic-pool
metric namespace. Refresh the optional-operation totals (25 capability
interfaces, +109 relational / +118 grand-total optional).
* fix(sql): clone ManagedInstance tags on read; deterministic list ordering
Address review MEDIUM #1 and the list-ordering LOW: GetManagedInstance /
ListManagedInstances now clone the stored Tags map so a caller mutating the
returned map can't corrupt the store (the copy-on-read hole flagged as the
concurrent-map panic class), and every List* mock method iterates
memstore.SortedValues() instead of All() for deterministic SDK list ordering,
matching the documented convention. Large-value list loops use index iteration
to avoid per-element copies.
* fix(azure): real update semantics + discoverable managed instances
Address review MEDIUM #2/#3/#4 (Azure update paths) and #7 (MI discovery):
- PUT on an existing Azure SQL server / database / managed instance now applies
the request body (upsert) instead of returning the stale record.
- PATCH is a genuine merge — elastic pools, failover groups and managed
instances gain Update* capability methods that overlay only the fields the
request supplied, so a partial PATCH no longer wipes unspecified fields; MI
PATCH now decodes and applies its body instead of being a no-op.
- Managed instances are projected into cross-service discovery
(microsoft.sql/managedinstances) via sqlDiscovery + the Resource Graph type
map, so a created MI appears in inventory.
Covered by SDK PATCH-merge round-trip tests (elastic pool keeps its SKU when
only maxSizeBytes is patched; MI keeps administratorLogin when only vCores is
patched) and a managed-instance type-map test.
* fix(azure): model Azure SQL database elastic-pool membership
Address review MEDIUM #5. Databases now carry an ElasticPoolID (added to the
shared InstanceConfig/Instance/ModifyInstanceInput and surfaced as the
elasticPoolId ARM database property), so an SDK client placing a database into a
pool round-trips instead of silently dropping it. DeleteElasticPool now returns
a precondition error while the pool still contains databases, matching real
Azure's 409. Covered by a membership/delete-guard test.
* fix(gcp): real Cloud SQL read-replica and failover semantics
Address review MEDIUM #6. A Cloud SQL insert with masterInstanceName now creates
an actual read replica: the replica records its master (ReadReplicaSource) and
the primary lists it (replicaNames), both surfaced in the instance body. Replica
lifecycle is faithful — start/stopReplica require the target to be a replica and
leave it RUNNABLE (no SUSPENDED state change); promoteReplica detaches it from
the primary (and rejects a non-replica); failover is a primary-only operation
and rejects a replica. Covered by SDK and mock replica-lifecycle tests.
* fix(sql): review LOW items — determinism, validation, replica fidelity tests
- Cloud SQL backup-run IDs are generated by the mock from the clock + a
monotonic counter (was time.Now().UnixNano(), violating the Clock determinism
rule and collision-prone); CloneInstance now clones the source's databases and
resets replica linkage; UpdateUser doc corrected.
- Firewall rules validate IPv4 start/end (Azure SQL + both Flexible Servers);
Azure SQL Managed Instance requires subnetId, as real Azure does.
- Added a real-SDK Resource Graph indexing test that drives sqlDiscovery
end-to-end (logical server + managed instance appear and filter), and a
-race concurrency test that mutates a returned managed-instance Tags map to
pin the copy-on-read fix.
* fix(sql): address second review — MI lifecycle, in-place restore, validation
- Cloud SQL DeleteInstance now unlinks replica<->master before cascading
children, so no dangling ReadReplicaSource/ReadReplicaTargets remain.
- Managed Instance lifecycle gains a state guard (transitionManagedInstance):
Start/Stop respect current state, Failover requires Ready; MI create emits
representative metrics and clones returned Tags; adds CreateManagedInstance
cost rate.
- Cloud SQL RestoreBackup restores in place onto the existing instance via a
new optional BackupRestorer capability (was create-new -> 409).
- Failover-group failover requires a partner server; firewall rules validate
Start <= End; Azure Flex SetConfiguration rejects unknown params and empty
values; ARM parser captures the action verb so forced vs planned failover
and unknown POST verbs are distinguished; Cloud SQL selfLink/targetLink use
the served /v1 prefix.
- Broaden new-package test coverage (sub-resource CRUD, MI lifecycle, Users
update, backup get, error paths, server PATCH, raw MI start/stop).
* fix(sql): address third review — output aliasing, config catalog, validation
- Deep-copy Tags/slice fields on every Instance/Cluster/Snapshot return path in
azuresql and cloudsql (Describe/Create/Modify/Restore/Clone), so a returned
value never aliases the memstore — fixes a potential concurrent-map crash and
matches the managedinstance/FailoverGroup discipline.
- Azure Flex GetConfiguration/ListConfigurations return catalog defaults for a
known-but-unset parameter (real Azure behavior) instead of NotFound/empty; the
catalog now maps names to defaults.
- MySQL Flex batch config update is atomic: all entries are validated before any
is applied, via a new optional BatchConfigurations capability.
- Azure SQL database create/modify validates the referenced elastic pool exists
(symmetry with the pool-delete member guard).
- Cloud SQL rejects child (database/user) names containing '/' that would orphan
a row; get-paths add length guards on single-ID Describe lookups.
- Flex firewall create validates start <= end (parity with Azure SQL).
- Tests: aliasing, config defaults, batch atomicity, elastic-pool validation,
child-name rejection, FG update/list, managed-database delete, and Azure
wire-level error-mapping (404/400) across all three Azure SQL services.
* feat(gcp): add AlloyDB full-parity support
Adds GCP AlloyDB as a first-class managed database server, reusing the
relationaldb driver.
- Provider providers/gcp/alloydb: implements RelationalDB (clusters,
instances, cluster backups→ClusterSnapshot, restore) + Users + Databases,
plus a new optional rdsdriver.AlloyDB capability for AlloyDB-specific
behavior — rich cluster/instance create, cross-region secondary + promote,
instance failover/restart, continuous/automated-backup + maintenance config,
and *Info accessors. Cloud Monitoring metrics on instance create.
Copy-on-read (clone Tags/slices), '/'-name and instance-type validation,
cascade delete, and lifecycle state guards throughout.
- Server server/gcp/alloydb: alloydb.googleapis.com/v1 REST handler
(clusters[/instances|/users], backups, LRO operations, custom methods
:promote/:createsecondary/:restore/:failover/:restart) using the SDK types
for wire fidelity; SDK round-trip + wire-error (404/409/400) tests.
- Wiring: providers/gcp/gcp.go (field, monitoring, combined CloudSQL+AlloyDB
relational discovery adapter, TypeAlloyDBCluster); server/gcp Drivers gains
an opt-in AlloyDB field (left nil in DriversFrom — its paths collide with
GKE's, so the two are mutually exclusive on one server).
- Dedicated AlloyDB cost rates; docs/services.md updated (capabilities, GCP
column, operation counts).
* fix(gcp): address AlloyDB review comments
- One PRIMARY per cluster enforced (base + native create); SECONDARY instance
requires a SECONDARY cluster; READ_POOL requires nodeCount > 0.
- Detach dangling SECONDARY links when their PRIMARY cluster is deleted (the
replica-linkage class from #303).
- FailoverInstance requires a PRIMARY target; RestartInstance stays valid on
any type.
- UpdateUser is now reachable via Users.Patch (was 405).
- Custom methods (:promote / :failover / :restart) are POST-only and unknown
verbs 404 instead of misrouting to CRUD; GET on :promote no longer promotes.
- Deterministic list order: DescribeClusters/DescribeInstances use SortedValues.
- patchCluster/patchInstance handle the capability assertion; toWireUser returns
the full resource path; removed banner comments.
- Wiring: guard New against AlloyDB+GKE both enabled (they share paths) and add
DriversFromWithAlloyDB helper (enables AlloyDB in place of GKE).
- Tests for every guard + user PATCH + GET-:promote rejection + 400 wire error +
instance output aliasing.
4 tasks
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.