diff --git a/changes/unreleased/Fixed-20260906-140000.yaml b/changes/unreleased/Fixed-20260906-140000.yaml new file mode 100644 index 00000000..c9d4e78c --- /dev/null +++ b/changes/unreleased/Fixed-20260906-140000.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: 'Eight query-protocol providers no longer fabricate a success. `rds`, `neptune`, `docdb`, `redshift`, `elasticache`, `autoscaling`, `cloudformation` and `elasticloadbalancingv2` answered any operation they do not implement with HTTP 200 and an empty ``, so a caller was told an operation succeeded when nothing ran. The body also had no `` wrapper, so botocore raised `KeyError` rather than returning a value — `neptune.describe_db_cluster_endpoints()` crashed the SDK. They now hand the operation to the generic CRUD engine, which serves the 223 CRUD-shaped ones from the real store and refuses the rest with a clean `InvalidAction`' +time: 2026-09-06T14:00:00.000000+09:00 +custom: + Issue: "145" diff --git a/docs/coverage.md b/docs/coverage.md index 4cb5df58..d6754e9e 100644 --- a/docs/coverage.md +++ b/docs/coverage.md @@ -23,8 +23,8 @@ Per operation, from the [fidelity manifest](fidelity-manifest.md): | Tier | Operations | |---|---| | `hand-verified` | 4,496 | -| `auto-crud` | 4,970 | -| `unimplemented` | 2,941 | +| `auto-crud` | 5,193 | +| `unimplemented` | 2,718 | | **total known** | **12,407** | ## Why a registered service can serve nothing diff --git a/internal/generated/compat/services.json b/internal/generated/compat/services.json index 8c92af42..37427412 100644 --- a/internal/generated/compat/services.json +++ b/internal/generated/compat/services.json @@ -695,18 +695,32 @@ "DeleteAutoScalingGroup", "DeleteLaunchConfiguration", "DeleteLifecycleHook", + "DeleteNotificationConfiguration", "DeletePolicy", "DeleteScheduledAction", "DeleteTags", + "DeleteWarmPool", "DescribeAccountLimits", + "DescribeAdjustmentTypes", "DescribeAutoScalingGroups", "DescribeAutoScalingInstances", + "DescribeAutoScalingNotificationTypes", "DescribeInstanceRefreshes", "DescribeLaunchConfigurations", + "DescribeLifecycleHookTypes", "DescribeLifecycleHooks", + "DescribeLoadBalancerTargetGroups", + "DescribeLoadBalancers", + "DescribeMetricCollectionTypes", + "DescribeNotificationConfigurations", "DescribePolicies", + "DescribeScalingActivities", + "DescribeScalingProcessTypes", "DescribeScheduledActions", "DescribeTags", + "DescribeTerminationPolicyTypes", + "DescribeTrafficSources", + "DescribeWarmPool", "DetachInstances", "DetachLoadBalancerTargetGroups", "DetachLoadBalancers", @@ -716,9 +730,12 @@ "EnterStandby", "ExecutePolicy", "ExitStandby", + "GetPredictiveScalingForecast", "PutLifecycleHook", + "PutNotificationConfiguration", "PutScalingPolicy", "PutScheduledUpdateGroupAction", + "PutWarmPool", "RecordLifecycleActionHeartbeat", "ResumeProcesses", "RollbackInstanceRefresh", @@ -1419,21 +1436,30 @@ "BatchDescribeTypeConfigurations", "ContinueUpdateRollback", "CreateChangeSet", + "CreateGeneratedTemplate", "CreateStack", "CreateStackInstances", + "CreateStackRefactor", "CreateStackSet", "DeactivateType", "DeleteChangeSet", + "DeleteGeneratedTemplate", "DeleteStack", "DeleteStackInstances", "DeleteStackSet", "DeregisterType", "DescribeAccountLimits", "DescribeChangeSet", + "DescribeChangeSetHooks", + "DescribeEvents", + "DescribeGeneratedTemplate", + "DescribeOrganizationsAccess", "DescribePublisher", + "DescribeResourceScan", "DescribeStackDriftDetectionStatus", "DescribeStackEvents", "DescribeStackInstance", + "DescribeStackRefactor", "DescribeStackResource", "DescribeStackResourceDrifts", "DescribeStackResources", @@ -1445,15 +1471,26 @@ "DetectStackDrift", "DetectStackResourceDrift", "ExecuteChangeSet", + "GetGeneratedTemplate", + "GetHookResult", "GetStackPolicy", "GetTemplate", "GetTemplateSummary", "ImportStacksToStackSet", "ListChangeSets", "ListExports", + "ListGeneratedTemplates", + "ListHookResults", "ListImports", + "ListResourceScanRelatedResources", + "ListResourceScanResources", + "ListResourceScans", + "ListStackInstanceResourceDrifts", "ListStackInstances", + "ListStackRefactorActions", + "ListStackRefactors", "ListStackResources", + "ListStackSetAutoDeploymentTargets", "ListStackSetOperationResults", "ListStackSetOperations", "ListStackSets", @@ -1471,6 +1508,7 @@ "SignalResource", "StopStackSetOperation", "TestType", + "UpdateGeneratedTemplate", "UpdateStack", "UpdateStackInstances", "UpdateStackSet", @@ -3724,8 +3762,10 @@ "CreateCacheParameterGroup", "CreateCacheSecurityGroup", "CreateCacheSubnetGroup", + "CreateGlobalReplicationGroup", "CreateReplicationGroup", "CreateServerlessCache", + "CreateServerlessCacheSnapshot", "CreateSnapshot", "CreateUser", "CreateUserGroup", @@ -3734,27 +3774,39 @@ "DeleteCacheParameterGroup", "DeleteCacheSecurityGroup", "DeleteCacheSubnetGroup", + "DeleteGlobalReplicationGroup", "DeleteReplicationGroup", "DeleteServerlessCache", + "DeleteServerlessCacheSnapshot", "DeleteSnapshot", "DeleteUser", "DeleteUserGroup", "DescribeCacheClusters", + "DescribeCacheEngineVersions", "DescribeCacheParameterGroups", "DescribeCacheParameters", "DescribeCacheSecurityGroups", "DescribeCacheSubnetGroups", "DescribeEngineDefaultParameters", + "DescribeEvents", + "DescribeGlobalReplicationGroups", "DescribeReplicationGroups", + "DescribeReservedCacheNodes", + "DescribeReservedCacheNodesOfferings", + "DescribeServerlessCacheSnapshots", "DescribeServerlessCaches", + "DescribeServiceUpdates", "DescribeSnapshots", + "DescribeUpdateActions", "DescribeUserGroups", "DescribeUsers", "IncreaseReplicaCount", + "ListAllowedNodeTypeModifications", "ListTagsForResource", "ModifyCacheCluster", "ModifyCacheParameterGroup", "ModifyCacheSubnetGroup", + "ModifyGlobalReplicationGroup", "ModifyReplicationGroup", "ModifyReplicationGroupShardConfiguration", "ModifyServerlessCache", @@ -3851,12 +3903,17 @@ "CreateLoadBalancer", "CreateRule", "CreateTargetGroup", + "CreateTrustStore", "DeleteListener", "DeleteLoadBalancer", "DeleteRule", + "DeleteSharedTrustStoreAssociation", "DeleteTargetGroup", + "DeleteTrustStore", "DeregisterTargets", "DescribeAccountLimits", + "DescribeCapacityReservation", + "DescribeListenerAttributes", "DescribeListenerCertificates", "DescribeListeners", "DescribeLoadBalancerAttributes", @@ -3867,11 +3924,21 @@ "DescribeTargetGroupAttributes", "DescribeTargetGroups", "DescribeTargetHealth", + "DescribeTrustStoreAssociations", + "DescribeTrustStoreRevocations", + "DescribeTrustStores", + "GetResourcePolicy", + "GetTrustStoreCaCertificatesBundle", + "GetTrustStoreRevocationContent", + "ModifyCapacityReservation", + "ModifyIpPools", "ModifyListener", + "ModifyListenerAttributes", "ModifyLoadBalancerAttributes", "ModifyRule", "ModifyTargetGroup", "ModifyTargetGroupAttributes", + "ModifyTrustStore", "RegisterTargets", "RemoveListenerCertificates", "RemoveTags", @@ -7665,53 +7732,122 @@ "CopyDBParameterGroup", "CopyDBSnapshot", "CopyOptionGroup", + "CreateBlueGreenDeployment", + "CreateCustomDBEngineVersion", "CreateDBCluster", + "CreateDBClusterEndpoint", "CreateDBClusterParameterGroup", "CreateDBClusterSnapshot", "CreateDBInstance", + "CreateDBInstanceReadReplica", "CreateDBParameterGroup", + "CreateDBProxy", + "CreateDBProxyEndpoint", + "CreateDBSecurityGroup", + "CreateDBShardGroup", "CreateDBSnapshot", "CreateDBSubnetGroup", + "CreateEventSubscription", + "CreateGlobalCluster", + "CreateIntegration", "CreateOptionGroup", + "CreateTenantDatabase", + "DeleteBlueGreenDeployment", + "DeleteCustomDBEngineVersion", "DeleteDBCluster", + "DeleteDBClusterAutomatedBackup", + "DeleteDBClusterEndpoint", "DeleteDBClusterParameterGroup", "DeleteDBClusterSnapshot", "DeleteDBInstance", + "DeleteDBInstanceAutomatedBackup", "DeleteDBParameterGroup", + "DeleteDBProxy", + "DeleteDBProxyEndpoint", + "DeleteDBSecurityGroup", + "DeleteDBShardGroup", "DeleteDBSnapshot", "DeleteDBSubnetGroup", + "DeleteEventSubscription", + "DeleteGlobalCluster", + "DeleteIntegration", "DeleteOptionGroup", + "DeleteTenantDatabase", + "DeregisterDBProxyTargets", "DescribeAccountAttributes", + "DescribeBlueGreenDeployments", "DescribeCertificates", + "DescribeDBClusterAutomatedBackups", + "DescribeDBClusterBacktracks", + "DescribeDBClusterEndpoints", "DescribeDBClusterParameterGroups", "DescribeDBClusterParameters", + "DescribeDBClusterSnapshotAttributes", "DescribeDBClusterSnapshots", "DescribeDBClusters", "DescribeDBEngineVersions", + "DescribeDBInstanceAutomatedBackups", "DescribeDBInstances", + "DescribeDBLogFiles", + "DescribeDBMajorEngineVersions", "DescribeDBParameterGroups", "DescribeDBParameters", + "DescribeDBProxies", + "DescribeDBProxyEndpoints", + "DescribeDBProxyTargetGroups", + "DescribeDBProxyTargets", + "DescribeDBRecommendations", + "DescribeDBSecurityGroups", + "DescribeDBShardGroups", + "DescribeDBSnapshotAttributes", + "DescribeDBSnapshotTenantDatabases", "DescribeDBSnapshots", "DescribeDBSubnetGroups", "DescribeEngineDefaultClusterParameters", "DescribeEngineDefaultParameters", "DescribeEventCategories", + "DescribeEventSubscriptions", "DescribeEvents", + "DescribeExportTasks", + "DescribeGlobalClusters", + "DescribeIntegrations", "DescribeOptionGroupOptions", "DescribeOptionGroups", "DescribeOrderableDBInstanceOptions", "DescribePendingMaintenanceActions", + "DescribeReservedDBInstances", + "DescribeReservedDBInstancesOfferings", "DescribeSourceRegions", + "DescribeTenantDatabases", + "DescribeValidDBInstanceModifications", "FailoverDBCluster", "ListTagsForResource", + "ModifyActivityStream", + "ModifyCertificates", + "ModifyCurrentDBClusterCapacity", + "ModifyCustomDBEngineVersion", "ModifyDBCluster", + "ModifyDBClusterEndpoint", "ModifyDBClusterParameterGroup", + "ModifyDBClusterSnapshotAttribute", "ModifyDBInstance", "ModifyDBParameterGroup", + "ModifyDBProxy", + "ModifyDBProxyEndpoint", + "ModifyDBProxyTargetGroup", + "ModifyDBRecommendation", + "ModifyDBShardGroup", + "ModifyDBSnapshot", + "ModifyDBSnapshotAttribute", "ModifyDBSubnetGroup", + "ModifyEventSubscription", + "ModifyGlobalCluster", + "ModifyIntegration", "ModifyOptionGroup", + "ModifyTenantDatabase", "RebootDBCluster", "RebootDBInstance", + "RegisterDBProxyTargets", "RemoveTagsFromResource", "ResetDBClusterParameterGroup", "ResetDBParameterGroup", @@ -7729,36 +7865,123 @@ "protocol": "query", "servedOps": [ "CopyClusterSnapshot", + "CreateAuthenticationProfile", "CreateCluster", "CreateClusterParameterGroup", + "CreateClusterSecurityGroup", "CreateClusterSnapshot", "CreateClusterSubnetGroup", + "CreateCustomDomainAssociation", + "CreateEndpointAccess", + "CreateEventSubscription", + "CreateHsmClientCertificate", + "CreateHsmConfiguration", + "CreateIntegration", + "CreateRedshiftIdcApplication", + "CreateScheduledAction", + "CreateSnapshotCopyGrant", + "CreateSnapshotSchedule", "CreateTags", + "CreateUsageLimit", + "DeleteAuthenticationProfile", "DeleteCluster", "DeleteClusterParameterGroup", + "DeleteClusterSecurityGroup", "DeleteClusterSnapshot", "DeleteClusterSubnetGroup", + "DeleteCustomDomainAssociation", + "DeleteEndpointAccess", + "DeleteEventSubscription", + "DeleteHsmClientCertificate", + "DeleteHsmConfiguration", + "DeleteIntegration", + "DeletePartner", + "DeleteRedshiftIdcApplication", + "DeleteResourcePolicy", + "DeleteScheduledAction", + "DeleteSnapshotCopyGrant", + "DeleteSnapshotSchedule", "DeleteTags", + "DeleteUsageLimit", + "DeregisterNamespace", + "DescribeAccountAttributes", + "DescribeAuthenticationProfiles", + "DescribeClusterDbRevisions", "DescribeClusterParameterGroups", "DescribeClusterParameters", + "DescribeClusterSecurityGroups", "DescribeClusterSnapshots", "DescribeClusterSubnetGroups", + "DescribeClusterTracks", + "DescribeClusterVersions", "DescribeClusters", + "DescribeCustomDomainAssociations", + "DescribeDataShares", + "DescribeDataSharesForConsumer", + "DescribeDataSharesForProducer", "DescribeDefaultClusterParameters", + "DescribeEndpointAccess", + "DescribeEndpointAuthorization", + "DescribeEventCategories", + "DescribeEventSubscriptions", + "DescribeEvents", + "DescribeHsmClientCertificates", + "DescribeHsmConfigurations", + "DescribeInboundIntegrations", + "DescribeIntegrations", "DescribeLoggingStatus", + "DescribeNodeConfigurationOptions", + "DescribeOrderableClusterOptions", + "DescribePartners", + "DescribeRedshiftIdcApplications", + "DescribeReservedNodeExchangeStatus", + "DescribeReservedNodeOfferings", + "DescribeReservedNodes", + "DescribeResize", + "DescribeScheduledActions", + "DescribeSnapshotCopyGrants", + "DescribeSnapshotSchedules", + "DescribeStorage", + "DescribeTableRestoreStatus", "DescribeTags", + "DescribeUsageLimits", "DisableLogging", "EnableLogging", "GetClusterCredentials", "GetClusterCredentialsWithIAM", + "GetIdentityCenterAuthToken", + "GetReservedNodeExchangeConfigurationOptions", + "GetReservedNodeExchangeOfferings", + "GetResourcePolicy", + "ListRecommendations", + "ModifyAquaConfiguration", + "ModifyAuthenticationProfile", "ModifyCluster", + "ModifyClusterDbRevision", + "ModifyClusterIamRoles", + "ModifyClusterMaintenance", "ModifyClusterParameterGroup", + "ModifyClusterSnapshot", + "ModifyClusterSnapshotSchedule", "ModifyClusterSubnetGroup", + "ModifyCustomDomainAssociation", + "ModifyEndpointAccess", + "ModifyEventSubscription", + "ModifyIntegration", + "ModifyLakehouseConfiguration", + "ModifyRedshiftIdcApplication", + "ModifyScheduledAction", + "ModifySnapshotCopyRetentionPeriod", + "ModifySnapshotSchedule", + "ModifyUsageLimit", "PauseCluster", + "PutResourcePolicy", "RebootCluster", + "RegisterNamespace", "ResetClusterParameterGroup", "RestoreFromClusterSnapshot", - "ResumeCluster" + "ResumeCluster", + "UpdatePartnerStatus" ] }, "redshiftdata": { diff --git a/internal/generated/fidelity/manifest_gen.go b/internal/generated/fidelity/manifest_gen.go index 2321eaf0..53a1edd1 100644 --- a/internal/generated/fidelity/manifest_gen.go +++ b/internal/generated/fidelity/manifest_gen.go @@ -745,7 +745,7 @@ var Services = map[string]Service{ "UpdatePreparedStatement": TierHandVerified, "UpdateWorkGroup": TierHandVerified, }}, - "autoscaling": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ + "autoscaling": {Protocol: "query", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AttachInstances": TierHandVerified, "AttachLoadBalancerTargetGroups": TierHandVerified, "AttachLoadBalancers": TierHandVerified, @@ -760,32 +760,32 @@ var Services = map[string]Service{ "DeleteAutoScalingGroup": TierHandVerified, "DeleteLaunchConfiguration": TierHandVerified, "DeleteLifecycleHook": TierHandVerified, - "DeleteNotificationConfiguration": TierUnimplemented, + "DeleteNotificationConfiguration": TierAutoCRUD, "DeletePolicy": TierHandVerified, "DeleteScheduledAction": TierHandVerified, "DeleteTags": TierHandVerified, - "DeleteWarmPool": TierUnimplemented, + "DeleteWarmPool": TierAutoCRUD, "DescribeAccountLimits": TierHandVerified, - "DescribeAdjustmentTypes": TierUnimplemented, + "DescribeAdjustmentTypes": TierAutoCRUD, "DescribeAutoScalingGroups": TierHandVerified, "DescribeAutoScalingInstances": TierHandVerified, - "DescribeAutoScalingNotificationTypes": TierUnimplemented, + "DescribeAutoScalingNotificationTypes": TierAutoCRUD, "DescribeInstanceRefreshes": TierHandVerified, "DescribeLaunchConfigurations": TierHandVerified, - "DescribeLifecycleHookTypes": TierUnimplemented, + "DescribeLifecycleHookTypes": TierAutoCRUD, "DescribeLifecycleHooks": TierHandVerified, - "DescribeLoadBalancerTargetGroups": TierUnimplemented, - "DescribeLoadBalancers": TierUnimplemented, - "DescribeMetricCollectionTypes": TierUnimplemented, - "DescribeNotificationConfigurations": TierUnimplemented, + "DescribeLoadBalancerTargetGroups": TierAutoCRUD, + "DescribeLoadBalancers": TierAutoCRUD, + "DescribeMetricCollectionTypes": TierAutoCRUD, + "DescribeNotificationConfigurations": TierAutoCRUD, "DescribePolicies": TierHandVerified, - "DescribeScalingActivities": TierUnimplemented, - "DescribeScalingProcessTypes": TierUnimplemented, + "DescribeScalingActivities": TierAutoCRUD, + "DescribeScalingProcessTypes": TierAutoCRUD, "DescribeScheduledActions": TierHandVerified, "DescribeTags": TierHandVerified, - "DescribeTerminationPolicyTypes": TierUnimplemented, - "DescribeTrafficSources": TierUnimplemented, - "DescribeWarmPool": TierUnimplemented, + "DescribeTerminationPolicyTypes": TierAutoCRUD, + "DescribeTrafficSources": TierAutoCRUD, + "DescribeWarmPool": TierAutoCRUD, "DetachInstances": TierHandVerified, "DetachLoadBalancerTargetGroups": TierHandVerified, "DetachLoadBalancers": TierHandVerified, @@ -795,13 +795,13 @@ var Services = map[string]Service{ "EnterStandby": TierHandVerified, "ExecutePolicy": TierHandVerified, "ExitStandby": TierHandVerified, - "GetPredictiveScalingForecast": TierUnimplemented, + "GetPredictiveScalingForecast": TierAutoCRUD, "LaunchInstances": TierUnimplemented, "PutLifecycleHook": TierHandVerified, - "PutNotificationConfiguration": TierUnimplemented, + "PutNotificationConfiguration": TierAutoCRUD, "PutScalingPolicy": TierHandVerified, "PutScheduledUpdateGroupAction": TierHandVerified, - "PutWarmPool": TierUnimplemented, + "PutWarmPool": TierAutoCRUD, "RecordLifecycleActionHeartbeat": TierHandVerified, "ResumeProcesses": TierHandVerified, "RollbackInstanceRefresh": TierHandVerified, @@ -1641,38 +1641,38 @@ var Services = map[string]Service{ "ValidateResource": TierHandVerified, "WaitForResource": TierHandVerified, }}, - "cloudformation": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ + "cloudformation": {Protocol: "query", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "ActivateOrganizationsAccess": TierUnimplemented, "ActivateType": TierHandVerified, "BatchDescribeTypeConfigurations": TierHandVerified, "CancelUpdateStack": TierUnimplemented, "ContinueUpdateRollback": TierHandVerified, "CreateChangeSet": TierHandVerified, - "CreateGeneratedTemplate": TierUnimplemented, + "CreateGeneratedTemplate": TierAutoCRUD, "CreateStack": TierHandVerified, "CreateStackInstances": TierHandVerified, - "CreateStackRefactor": TierUnimplemented, + "CreateStackRefactor": TierAutoCRUD, "CreateStackSet": TierHandVerified, "DeactivateOrganizationsAccess": TierUnimplemented, "DeactivateType": TierHandVerified, "DeleteChangeSet": TierHandVerified, - "DeleteGeneratedTemplate": TierUnimplemented, + "DeleteGeneratedTemplate": TierAutoCRUD, "DeleteStack": TierHandVerified, "DeleteStackInstances": TierHandVerified, "DeleteStackSet": TierHandVerified, "DeregisterType": TierHandVerified, "DescribeAccountLimits": TierHandVerified, "DescribeChangeSet": TierHandVerified, - "DescribeChangeSetHooks": TierUnimplemented, - "DescribeEvents": TierUnimplemented, - "DescribeGeneratedTemplate": TierUnimplemented, - "DescribeOrganizationsAccess": TierUnimplemented, + "DescribeChangeSetHooks": TierAutoCRUD, + "DescribeEvents": TierAutoCRUD, + "DescribeGeneratedTemplate": TierAutoCRUD, + "DescribeOrganizationsAccess": TierAutoCRUD, "DescribePublisher": TierHandVerified, - "DescribeResourceScan": TierUnimplemented, + "DescribeResourceScan": TierAutoCRUD, "DescribeStackDriftDetectionStatus": TierHandVerified, "DescribeStackEvents": TierHandVerified, "DescribeStackInstance": TierHandVerified, - "DescribeStackRefactor": TierUnimplemented, + "DescribeStackRefactor": TierAutoCRUD, "DescribeStackResource": TierHandVerified, "DescribeStackResourceDrifts": TierHandVerified, "DescribeStackResources": TierHandVerified, @@ -1687,26 +1687,26 @@ var Services = map[string]Service{ "EstimateTemplateCost": TierUnimplemented, "ExecuteChangeSet": TierHandVerified, "ExecuteStackRefactor": TierUnimplemented, - "GetGeneratedTemplate": TierUnimplemented, - "GetHookResult": TierUnimplemented, + "GetGeneratedTemplate": TierAutoCRUD, + "GetHookResult": TierAutoCRUD, "GetStackPolicy": TierHandVerified, "GetTemplate": TierHandVerified, "GetTemplateSummary": TierHandVerified, "ImportStacksToStackSet": TierHandVerified, "ListChangeSets": TierHandVerified, "ListExports": TierHandVerified, - "ListGeneratedTemplates": TierUnimplemented, - "ListHookResults": TierUnimplemented, + "ListGeneratedTemplates": TierAutoCRUD, + "ListHookResults": TierAutoCRUD, "ListImports": TierHandVerified, - "ListResourceScanRelatedResources": TierUnimplemented, - "ListResourceScanResources": TierUnimplemented, - "ListResourceScans": TierUnimplemented, - "ListStackInstanceResourceDrifts": TierUnimplemented, + "ListResourceScanRelatedResources": TierAutoCRUD, + "ListResourceScanResources": TierAutoCRUD, + "ListResourceScans": TierAutoCRUD, + "ListStackInstanceResourceDrifts": TierAutoCRUD, "ListStackInstances": TierHandVerified, - "ListStackRefactorActions": TierUnimplemented, - "ListStackRefactors": TierUnimplemented, + "ListStackRefactorActions": TierAutoCRUD, + "ListStackRefactors": TierAutoCRUD, "ListStackResources": TierHandVerified, - "ListStackSetAutoDeploymentTargets": TierUnimplemented, + "ListStackSetAutoDeploymentTargets": TierAutoCRUD, "ListStackSetOperationResults": TierHandVerified, "ListStackSetOperations": TierHandVerified, "ListStackSets": TierHandVerified, @@ -1726,7 +1726,7 @@ var Services = map[string]Service{ "StartResourceScan": TierUnimplemented, "StopStackSetOperation": TierHandVerified, "TestType": TierHandVerified, - "UpdateGeneratedTemplate": TierUnimplemented, + "UpdateGeneratedTemplate": TierAutoCRUD, "UpdateStack": TierHandVerified, "UpdateStackInstances": TierHandVerified, "UpdateStackSet": TierHandVerified, @@ -3825,7 +3825,7 @@ var Services = map[string]Service{ "StopReplicationTask": TierHandVerified, "TestConnection": TierHandVerified, }}, - "docdb": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ + "docdb": {Protocol: "query", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddSourceIdentifierToSubscription": TierHandVerified, "AddTagsToResource": TierHandVerified, "ApplyPendingMaintenanceAction": TierHandVerified, @@ -4998,7 +4998,7 @@ var Services = map[string]Service{ "UpdateNodegroupVersion": TierHandVerified, "UpdatePodIdentityAssociation": TierHandVerified, }}, - "elasticache": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ + "elasticache": {Protocol: "query", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddTagsToResource": TierHandVerified, "AuthorizeCacheSecurityGroupIngress": TierHandVerified, "BatchApplyUpdateAction": TierUnimplemented, @@ -5010,10 +5010,10 @@ var Services = map[string]Service{ "CreateCacheParameterGroup": TierHandVerified, "CreateCacheSecurityGroup": TierHandVerified, "CreateCacheSubnetGroup": TierHandVerified, - "CreateGlobalReplicationGroup": TierUnimplemented, + "CreateGlobalReplicationGroup": TierAutoCRUD, "CreateReplicationGroup": TierHandVerified, "CreateServerlessCache": TierHandVerified, - "CreateServerlessCacheSnapshot": TierUnimplemented, + "CreateServerlessCacheSnapshot": TierAutoCRUD, "CreateSnapshot": TierHandVerified, "CreateUser": TierHandVerified, "CreateUserGroup": TierHandVerified, @@ -5023,30 +5023,30 @@ var Services = map[string]Service{ "DeleteCacheParameterGroup": TierHandVerified, "DeleteCacheSecurityGroup": TierHandVerified, "DeleteCacheSubnetGroup": TierHandVerified, - "DeleteGlobalReplicationGroup": TierUnimplemented, + "DeleteGlobalReplicationGroup": TierAutoCRUD, "DeleteReplicationGroup": TierHandVerified, "DeleteServerlessCache": TierHandVerified, - "DeleteServerlessCacheSnapshot": TierUnimplemented, + "DeleteServerlessCacheSnapshot": TierAutoCRUD, "DeleteSnapshot": TierHandVerified, "DeleteUser": TierHandVerified, "DeleteUserGroup": TierHandVerified, "DescribeCacheClusters": TierHandVerified, - "DescribeCacheEngineVersions": TierUnimplemented, + "DescribeCacheEngineVersions": TierAutoCRUD, "DescribeCacheParameterGroups": TierHandVerified, "DescribeCacheParameters": TierHandVerified, "DescribeCacheSecurityGroups": TierHandVerified, "DescribeCacheSubnetGroups": TierHandVerified, "DescribeEngineDefaultParameters": TierHandVerified, - "DescribeEvents": TierUnimplemented, - "DescribeGlobalReplicationGroups": TierUnimplemented, + "DescribeEvents": TierAutoCRUD, + "DescribeGlobalReplicationGroups": TierAutoCRUD, "DescribeReplicationGroups": TierHandVerified, - "DescribeReservedCacheNodes": TierUnimplemented, - "DescribeReservedCacheNodesOfferings": TierUnimplemented, - "DescribeServerlessCacheSnapshots": TierUnimplemented, + "DescribeReservedCacheNodes": TierAutoCRUD, + "DescribeReservedCacheNodesOfferings": TierAutoCRUD, + "DescribeServerlessCacheSnapshots": TierAutoCRUD, "DescribeServerlessCaches": TierHandVerified, - "DescribeServiceUpdates": TierUnimplemented, + "DescribeServiceUpdates": TierAutoCRUD, "DescribeSnapshots": TierHandVerified, - "DescribeUpdateActions": TierUnimplemented, + "DescribeUpdateActions": TierAutoCRUD, "DescribeUserGroups": TierHandVerified, "DescribeUsers": TierHandVerified, "DisassociateGlobalReplicationGroup": TierUnimplemented, @@ -5054,12 +5054,12 @@ var Services = map[string]Service{ "FailoverGlobalReplicationGroup": TierUnimplemented, "IncreaseNodeGroupsInGlobalReplicationGroup": TierUnimplemented, "IncreaseReplicaCount": TierHandVerified, - "ListAllowedNodeTypeModifications": TierUnimplemented, + "ListAllowedNodeTypeModifications": TierAutoCRUD, "ListTagsForResource": TierHandVerified, "ModifyCacheCluster": TierHandVerified, "ModifyCacheParameterGroup": TierHandVerified, "ModifyCacheSubnetGroup": TierHandVerified, - "ModifyGlobalReplicationGroup": TierUnimplemented, + "ModifyGlobalReplicationGroup": TierAutoCRUD, "ModifyReplicationGroup": TierHandVerified, "ModifyReplicationGroupShardConfiguration": TierHandVerified, "ModifyServerlessCache": TierHandVerified, @@ -5155,7 +5155,7 @@ var Services = map[string]Service{ "SetLoadBalancerPoliciesForBackendServer": TierUnimplemented, "SetLoadBalancerPoliciesOfListener": TierUnimplemented, }}, - "elasticloadbalancingv2": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ + "elasticloadbalancingv2": {Protocol: "query", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddListenerCertificates": TierHandVerified, "AddTags": TierHandVerified, "AddTrustStoreRevocations": TierUnimplemented, @@ -5163,17 +5163,17 @@ var Services = map[string]Service{ "CreateLoadBalancer": TierHandVerified, "CreateRule": TierHandVerified, "CreateTargetGroup": TierHandVerified, - "CreateTrustStore": TierUnimplemented, + "CreateTrustStore": TierAutoCRUD, "DeleteListener": TierHandVerified, "DeleteLoadBalancer": TierHandVerified, "DeleteRule": TierHandVerified, - "DeleteSharedTrustStoreAssociation": TierUnimplemented, + "DeleteSharedTrustStoreAssociation": TierAutoCRUD, "DeleteTargetGroup": TierHandVerified, - "DeleteTrustStore": TierUnimplemented, + "DeleteTrustStore": TierAutoCRUD, "DeregisterTargets": TierHandVerified, "DescribeAccountLimits": TierHandVerified, - "DescribeCapacityReservation": TierUnimplemented, - "DescribeListenerAttributes": TierUnimplemented, + "DescribeCapacityReservation": TierAutoCRUD, + "DescribeListenerAttributes": TierAutoCRUD, "DescribeListenerCertificates": TierHandVerified, "DescribeListeners": TierHandVerified, "DescribeLoadBalancerAttributes": TierHandVerified, @@ -5184,21 +5184,21 @@ var Services = map[string]Service{ "DescribeTargetGroupAttributes": TierHandVerified, "DescribeTargetGroups": TierHandVerified, "DescribeTargetHealth": TierHandVerified, - "DescribeTrustStoreAssociations": TierUnimplemented, - "DescribeTrustStoreRevocations": TierUnimplemented, - "DescribeTrustStores": TierUnimplemented, - "GetResourcePolicy": TierUnimplemented, - "GetTrustStoreCaCertificatesBundle": TierUnimplemented, - "GetTrustStoreRevocationContent": TierUnimplemented, - "ModifyCapacityReservation": TierUnimplemented, - "ModifyIpPools": TierUnimplemented, + "DescribeTrustStoreAssociations": TierAutoCRUD, + "DescribeTrustStoreRevocations": TierAutoCRUD, + "DescribeTrustStores": TierAutoCRUD, + "GetResourcePolicy": TierAutoCRUD, + "GetTrustStoreCaCertificatesBundle": TierAutoCRUD, + "GetTrustStoreRevocationContent": TierAutoCRUD, + "ModifyCapacityReservation": TierAutoCRUD, + "ModifyIpPools": TierAutoCRUD, "ModifyListener": TierHandVerified, - "ModifyListenerAttributes": TierUnimplemented, + "ModifyListenerAttributes": TierAutoCRUD, "ModifyLoadBalancerAttributes": TierHandVerified, "ModifyRule": TierHandVerified, "ModifyTargetGroup": TierHandVerified, "ModifyTargetGroupAttributes": TierHandVerified, - "ModifyTrustStore": TierUnimplemented, + "ModifyTrustStore": TierAutoCRUD, "RegisterTargets": TierHandVerified, "RemoveListenerCertificates": TierHandVerified, "RemoveTags": TierHandVerified, @@ -8259,7 +8259,7 @@ var Services = map[string]Service{ "UpdateEnvironment": TierHandVerified, "UpdateVariables": TierHandVerified, }}, - "neptune": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ + "neptune": {Protocol: "query", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddRoleToDBCluster": TierHandVerified, "AddSourceIdentifierToSubscription": TierHandVerified, "AddTagsToResource": TierHandVerified, @@ -9591,7 +9591,7 @@ var Services = map[string]Service{ "UntagResource": TierHandVerified, "UpdateResourceShare": TierHandVerified, }}, - "rds": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ + "rds": {Protocol: "query", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddRoleToDBCluster": TierUnimplemented, "AddRoleToDBInstance": TierUnimplemented, "AddSourceIdentifierToSubscription": TierUnimplemented, @@ -9605,130 +9605,130 @@ var Services = map[string]Service{ "CopyDBParameterGroup": TierHandVerified, "CopyDBSnapshot": TierHandVerified, "CopyOptionGroup": TierHandVerified, - "CreateBlueGreenDeployment": TierUnimplemented, - "CreateCustomDBEngineVersion": TierUnimplemented, + "CreateBlueGreenDeployment": TierAutoCRUD, + "CreateCustomDBEngineVersion": TierAutoCRUD, "CreateDBCluster": TierHandVerified, - "CreateDBClusterEndpoint": TierUnimplemented, + "CreateDBClusterEndpoint": TierAutoCRUD, "CreateDBClusterParameterGroup": TierHandVerified, "CreateDBClusterSnapshot": TierHandVerified, "CreateDBInstance": TierHandVerified, - "CreateDBInstanceReadReplica": TierUnimplemented, + "CreateDBInstanceReadReplica": TierAutoCRUD, "CreateDBParameterGroup": TierHandVerified, - "CreateDBProxy": TierUnimplemented, - "CreateDBProxyEndpoint": TierUnimplemented, - "CreateDBSecurityGroup": TierUnimplemented, - "CreateDBShardGroup": TierUnimplemented, + "CreateDBProxy": TierAutoCRUD, + "CreateDBProxyEndpoint": TierAutoCRUD, + "CreateDBSecurityGroup": TierAutoCRUD, + "CreateDBShardGroup": TierAutoCRUD, "CreateDBSnapshot": TierHandVerified, "CreateDBSubnetGroup": TierHandVerified, - "CreateEventSubscription": TierUnimplemented, - "CreateGlobalCluster": TierUnimplemented, - "CreateIntegration": TierUnimplemented, + "CreateEventSubscription": TierAutoCRUD, + "CreateGlobalCluster": TierAutoCRUD, + "CreateIntegration": TierAutoCRUD, "CreateOptionGroup": TierHandVerified, - "CreateTenantDatabase": TierUnimplemented, - "DeleteBlueGreenDeployment": TierUnimplemented, - "DeleteCustomDBEngineVersion": TierUnimplemented, + "CreateTenantDatabase": TierAutoCRUD, + "DeleteBlueGreenDeployment": TierAutoCRUD, + "DeleteCustomDBEngineVersion": TierAutoCRUD, "DeleteDBCluster": TierHandVerified, - "DeleteDBClusterAutomatedBackup": TierUnimplemented, - "DeleteDBClusterEndpoint": TierUnimplemented, + "DeleteDBClusterAutomatedBackup": TierAutoCRUD, + "DeleteDBClusterEndpoint": TierAutoCRUD, "DeleteDBClusterParameterGroup": TierHandVerified, "DeleteDBClusterSnapshot": TierHandVerified, "DeleteDBInstance": TierHandVerified, - "DeleteDBInstanceAutomatedBackup": TierUnimplemented, + "DeleteDBInstanceAutomatedBackup": TierAutoCRUD, "DeleteDBParameterGroup": TierHandVerified, - "DeleteDBProxy": TierUnimplemented, - "DeleteDBProxyEndpoint": TierUnimplemented, - "DeleteDBSecurityGroup": TierUnimplemented, - "DeleteDBShardGroup": TierUnimplemented, + "DeleteDBProxy": TierAutoCRUD, + "DeleteDBProxyEndpoint": TierAutoCRUD, + "DeleteDBSecurityGroup": TierAutoCRUD, + "DeleteDBShardGroup": TierAutoCRUD, "DeleteDBSnapshot": TierHandVerified, "DeleteDBSubnetGroup": TierHandVerified, - "DeleteEventSubscription": TierUnimplemented, - "DeleteGlobalCluster": TierUnimplemented, - "DeleteIntegration": TierUnimplemented, + "DeleteEventSubscription": TierAutoCRUD, + "DeleteGlobalCluster": TierAutoCRUD, + "DeleteIntegration": TierAutoCRUD, "DeleteOptionGroup": TierHandVerified, - "DeleteTenantDatabase": TierUnimplemented, - "DeregisterDBProxyTargets": TierUnimplemented, + "DeleteTenantDatabase": TierAutoCRUD, + "DeregisterDBProxyTargets": TierAutoCRUD, "DescribeAccountAttributes": TierHandVerified, - "DescribeBlueGreenDeployments": TierUnimplemented, + "DescribeBlueGreenDeployments": TierAutoCRUD, "DescribeCertificates": TierHandVerified, - "DescribeDBClusterAutomatedBackups": TierUnimplemented, - "DescribeDBClusterBacktracks": TierUnimplemented, - "DescribeDBClusterEndpoints": TierUnimplemented, + "DescribeDBClusterAutomatedBackups": TierAutoCRUD, + "DescribeDBClusterBacktracks": TierAutoCRUD, + "DescribeDBClusterEndpoints": TierAutoCRUD, "DescribeDBClusterParameterGroups": TierHandVerified, "DescribeDBClusterParameters": TierHandVerified, - "DescribeDBClusterSnapshotAttributes": TierUnimplemented, + "DescribeDBClusterSnapshotAttributes": TierAutoCRUD, "DescribeDBClusterSnapshots": TierHandVerified, "DescribeDBClusters": TierHandVerified, "DescribeDBEngineVersions": TierHandVerified, - "DescribeDBInstanceAutomatedBackups": TierUnimplemented, + "DescribeDBInstanceAutomatedBackups": TierAutoCRUD, "DescribeDBInstances": TierHandVerified, - "DescribeDBLogFiles": TierUnimplemented, - "DescribeDBMajorEngineVersions": TierUnimplemented, + "DescribeDBLogFiles": TierAutoCRUD, + "DescribeDBMajorEngineVersions": TierAutoCRUD, "DescribeDBParameterGroups": TierHandVerified, "DescribeDBParameters": TierHandVerified, - "DescribeDBProxies": TierUnimplemented, - "DescribeDBProxyEndpoints": TierUnimplemented, - "DescribeDBProxyTargetGroups": TierUnimplemented, - "DescribeDBProxyTargets": TierUnimplemented, - "DescribeDBRecommendations": TierUnimplemented, - "DescribeDBSecurityGroups": TierUnimplemented, - "DescribeDBShardGroups": TierUnimplemented, - "DescribeDBSnapshotAttributes": TierUnimplemented, - "DescribeDBSnapshotTenantDatabases": TierUnimplemented, + "DescribeDBProxies": TierAutoCRUD, + "DescribeDBProxyEndpoints": TierAutoCRUD, + "DescribeDBProxyTargetGroups": TierAutoCRUD, + "DescribeDBProxyTargets": TierAutoCRUD, + "DescribeDBRecommendations": TierAutoCRUD, + "DescribeDBSecurityGroups": TierAutoCRUD, + "DescribeDBShardGroups": TierAutoCRUD, + "DescribeDBSnapshotAttributes": TierAutoCRUD, + "DescribeDBSnapshotTenantDatabases": TierAutoCRUD, "DescribeDBSnapshots": TierHandVerified, "DescribeDBSubnetGroups": TierHandVerified, "DescribeEngineDefaultClusterParameters": TierHandVerified, "DescribeEngineDefaultParameters": TierHandVerified, "DescribeEventCategories": TierHandVerified, - "DescribeEventSubscriptions": TierUnimplemented, + "DescribeEventSubscriptions": TierAutoCRUD, "DescribeEvents": TierHandVerified, - "DescribeExportTasks": TierUnimplemented, - "DescribeGlobalClusters": TierUnimplemented, - "DescribeIntegrations": TierUnimplemented, + "DescribeExportTasks": TierAutoCRUD, + "DescribeGlobalClusters": TierAutoCRUD, + "DescribeIntegrations": TierAutoCRUD, "DescribeOptionGroupOptions": TierHandVerified, "DescribeOptionGroups": TierHandVerified, "DescribeOrderableDBInstanceOptions": TierHandVerified, "DescribePendingMaintenanceActions": TierHandVerified, - "DescribeReservedDBInstances": TierUnimplemented, - "DescribeReservedDBInstancesOfferings": TierUnimplemented, + "DescribeReservedDBInstances": TierAutoCRUD, + "DescribeReservedDBInstancesOfferings": TierAutoCRUD, "DescribeSourceRegions": TierHandVerified, - "DescribeTenantDatabases": TierUnimplemented, - "DescribeValidDBInstanceModifications": TierUnimplemented, + "DescribeTenantDatabases": TierAutoCRUD, + "DescribeValidDBInstanceModifications": TierAutoCRUD, "DisableHttpEndpoint": TierUnimplemented, "DownloadDBLogFilePortion": TierUnimplemented, "EnableHttpEndpoint": TierUnimplemented, "FailoverDBCluster": TierHandVerified, "FailoverGlobalCluster": TierUnimplemented, "ListTagsForResource": TierHandVerified, - "ModifyActivityStream": TierUnimplemented, - "ModifyCertificates": TierUnimplemented, - "ModifyCurrentDBClusterCapacity": TierUnimplemented, - "ModifyCustomDBEngineVersion": TierUnimplemented, + "ModifyActivityStream": TierAutoCRUD, + "ModifyCertificates": TierAutoCRUD, + "ModifyCurrentDBClusterCapacity": TierAutoCRUD, + "ModifyCustomDBEngineVersion": TierAutoCRUD, "ModifyDBCluster": TierHandVerified, - "ModifyDBClusterEndpoint": TierUnimplemented, + "ModifyDBClusterEndpoint": TierAutoCRUD, "ModifyDBClusterParameterGroup": TierHandVerified, - "ModifyDBClusterSnapshotAttribute": TierUnimplemented, + "ModifyDBClusterSnapshotAttribute": TierAutoCRUD, "ModifyDBInstance": TierHandVerified, "ModifyDBParameterGroup": TierHandVerified, - "ModifyDBProxy": TierUnimplemented, - "ModifyDBProxyEndpoint": TierUnimplemented, - "ModifyDBProxyTargetGroup": TierUnimplemented, - "ModifyDBRecommendation": TierUnimplemented, - "ModifyDBShardGroup": TierUnimplemented, - "ModifyDBSnapshot": TierUnimplemented, - "ModifyDBSnapshotAttribute": TierUnimplemented, + "ModifyDBProxy": TierAutoCRUD, + "ModifyDBProxyEndpoint": TierAutoCRUD, + "ModifyDBProxyTargetGroup": TierAutoCRUD, + "ModifyDBRecommendation": TierAutoCRUD, + "ModifyDBShardGroup": TierAutoCRUD, + "ModifyDBSnapshot": TierAutoCRUD, + "ModifyDBSnapshotAttribute": TierAutoCRUD, "ModifyDBSubnetGroup": TierHandVerified, - "ModifyEventSubscription": TierUnimplemented, - "ModifyGlobalCluster": TierUnimplemented, - "ModifyIntegration": TierUnimplemented, + "ModifyEventSubscription": TierAutoCRUD, + "ModifyGlobalCluster": TierAutoCRUD, + "ModifyIntegration": TierAutoCRUD, "ModifyOptionGroup": TierHandVerified, - "ModifyTenantDatabase": TierUnimplemented, + "ModifyTenantDatabase": TierAutoCRUD, "PromoteReadReplica": TierUnimplemented, "PromoteReadReplicaDBCluster": TierUnimplemented, "PurchaseReservedDBInstancesOffering": TierUnimplemented, "RebootDBCluster": TierHandVerified, "RebootDBInstance": TierHandVerified, "RebootDBShardGroup": TierUnimplemented, - "RegisterDBProxyTargets": TierUnimplemented, + "RegisterDBProxyTargets": TierAutoCRUD, "RemoveFromGlobalCluster": TierUnimplemented, "RemoveRoleFromDBCluster": TierUnimplemented, "RemoveRoleFromDBInstance": TierUnimplemented, @@ -9764,7 +9764,7 @@ var Services = map[string]Service{ "ExecuteStatement": TierUnimplemented, "RollbackTransaction": TierUnimplemented, }}, - "redshift": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ + "redshift": {Protocol: "query", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AcceptReservedNodeExchange": TierUnimplemented, "AddPartner": TierUnimplemented, "AssociateDataShareConsumer": TierUnimplemented, @@ -9776,87 +9776,87 @@ var Services = map[string]Service{ "BatchModifyClusterSnapshots": TierUnimplemented, "CancelResize": TierUnimplemented, "CopyClusterSnapshot": TierHandVerified, - "CreateAuthenticationProfile": TierUnimplemented, + "CreateAuthenticationProfile": TierAutoCRUD, "CreateCluster": TierHandVerified, "CreateClusterParameterGroup": TierHandVerified, - "CreateClusterSecurityGroup": TierUnimplemented, + "CreateClusterSecurityGroup": TierAutoCRUD, "CreateClusterSnapshot": TierHandVerified, "CreateClusterSubnetGroup": TierHandVerified, - "CreateCustomDomainAssociation": TierUnimplemented, - "CreateEndpointAccess": TierUnimplemented, - "CreateEventSubscription": TierUnimplemented, - "CreateHsmClientCertificate": TierUnimplemented, - "CreateHsmConfiguration": TierUnimplemented, - "CreateIntegration": TierUnimplemented, - "CreateRedshiftIdcApplication": TierUnimplemented, - "CreateScheduledAction": TierUnimplemented, - "CreateSnapshotCopyGrant": TierUnimplemented, - "CreateSnapshotSchedule": TierUnimplemented, + "CreateCustomDomainAssociation": TierAutoCRUD, + "CreateEndpointAccess": TierAutoCRUD, + "CreateEventSubscription": TierAutoCRUD, + "CreateHsmClientCertificate": TierAutoCRUD, + "CreateHsmConfiguration": TierAutoCRUD, + "CreateIntegration": TierAutoCRUD, + "CreateRedshiftIdcApplication": TierAutoCRUD, + "CreateScheduledAction": TierAutoCRUD, + "CreateSnapshotCopyGrant": TierAutoCRUD, + "CreateSnapshotSchedule": TierAutoCRUD, "CreateTags": TierHandVerified, - "CreateUsageLimit": TierUnimplemented, + "CreateUsageLimit": TierAutoCRUD, "DeauthorizeDataShare": TierUnimplemented, - "DeleteAuthenticationProfile": TierUnimplemented, + "DeleteAuthenticationProfile": TierAutoCRUD, "DeleteCluster": TierHandVerified, "DeleteClusterParameterGroup": TierHandVerified, - "DeleteClusterSecurityGroup": TierUnimplemented, + "DeleteClusterSecurityGroup": TierAutoCRUD, "DeleteClusterSnapshot": TierHandVerified, "DeleteClusterSubnetGroup": TierHandVerified, - "DeleteCustomDomainAssociation": TierUnimplemented, - "DeleteEndpointAccess": TierUnimplemented, - "DeleteEventSubscription": TierUnimplemented, - "DeleteHsmClientCertificate": TierUnimplemented, - "DeleteHsmConfiguration": TierUnimplemented, - "DeleteIntegration": TierUnimplemented, - "DeletePartner": TierUnimplemented, - "DeleteRedshiftIdcApplication": TierUnimplemented, - "DeleteResourcePolicy": TierUnimplemented, - "DeleteScheduledAction": TierUnimplemented, - "DeleteSnapshotCopyGrant": TierUnimplemented, - "DeleteSnapshotSchedule": TierUnimplemented, + "DeleteCustomDomainAssociation": TierAutoCRUD, + "DeleteEndpointAccess": TierAutoCRUD, + "DeleteEventSubscription": TierAutoCRUD, + "DeleteHsmClientCertificate": TierAutoCRUD, + "DeleteHsmConfiguration": TierAutoCRUD, + "DeleteIntegration": TierAutoCRUD, + "DeletePartner": TierAutoCRUD, + "DeleteRedshiftIdcApplication": TierAutoCRUD, + "DeleteResourcePolicy": TierAutoCRUD, + "DeleteScheduledAction": TierAutoCRUD, + "DeleteSnapshotCopyGrant": TierAutoCRUD, + "DeleteSnapshotSchedule": TierAutoCRUD, "DeleteTags": TierHandVerified, - "DeleteUsageLimit": TierUnimplemented, - "DeregisterNamespace": TierUnimplemented, - "DescribeAccountAttributes": TierUnimplemented, - "DescribeAuthenticationProfiles": TierUnimplemented, - "DescribeClusterDbRevisions": TierUnimplemented, + "DeleteUsageLimit": TierAutoCRUD, + "DeregisterNamespace": TierAutoCRUD, + "DescribeAccountAttributes": TierAutoCRUD, + "DescribeAuthenticationProfiles": TierAutoCRUD, + "DescribeClusterDbRevisions": TierAutoCRUD, "DescribeClusterParameterGroups": TierHandVerified, "DescribeClusterParameters": TierHandVerified, - "DescribeClusterSecurityGroups": TierUnimplemented, + "DescribeClusterSecurityGroups": TierAutoCRUD, "DescribeClusterSnapshots": TierHandVerified, "DescribeClusterSubnetGroups": TierHandVerified, - "DescribeClusterTracks": TierUnimplemented, - "DescribeClusterVersions": TierUnimplemented, + "DescribeClusterTracks": TierAutoCRUD, + "DescribeClusterVersions": TierAutoCRUD, "DescribeClusters": TierHandVerified, - "DescribeCustomDomainAssociations": TierUnimplemented, - "DescribeDataShares": TierUnimplemented, - "DescribeDataSharesForConsumer": TierUnimplemented, - "DescribeDataSharesForProducer": TierUnimplemented, + "DescribeCustomDomainAssociations": TierAutoCRUD, + "DescribeDataShares": TierAutoCRUD, + "DescribeDataSharesForConsumer": TierAutoCRUD, + "DescribeDataSharesForProducer": TierAutoCRUD, "DescribeDefaultClusterParameters": TierHandVerified, - "DescribeEndpointAccess": TierUnimplemented, - "DescribeEndpointAuthorization": TierUnimplemented, - "DescribeEventCategories": TierUnimplemented, - "DescribeEventSubscriptions": TierUnimplemented, - "DescribeEvents": TierUnimplemented, - "DescribeHsmClientCertificates": TierUnimplemented, - "DescribeHsmConfigurations": TierUnimplemented, - "DescribeInboundIntegrations": TierUnimplemented, - "DescribeIntegrations": TierUnimplemented, + "DescribeEndpointAccess": TierAutoCRUD, + "DescribeEndpointAuthorization": TierAutoCRUD, + "DescribeEventCategories": TierAutoCRUD, + "DescribeEventSubscriptions": TierAutoCRUD, + "DescribeEvents": TierAutoCRUD, + "DescribeHsmClientCertificates": TierAutoCRUD, + "DescribeHsmConfigurations": TierAutoCRUD, + "DescribeInboundIntegrations": TierAutoCRUD, + "DescribeIntegrations": TierAutoCRUD, "DescribeLoggingStatus": TierHandVerified, - "DescribeNodeConfigurationOptions": TierUnimplemented, - "DescribeOrderableClusterOptions": TierUnimplemented, - "DescribePartners": TierUnimplemented, - "DescribeRedshiftIdcApplications": TierUnimplemented, - "DescribeReservedNodeExchangeStatus": TierUnimplemented, - "DescribeReservedNodeOfferings": TierUnimplemented, - "DescribeReservedNodes": TierUnimplemented, - "DescribeResize": TierUnimplemented, - "DescribeScheduledActions": TierUnimplemented, - "DescribeSnapshotCopyGrants": TierUnimplemented, - "DescribeSnapshotSchedules": TierUnimplemented, - "DescribeStorage": TierUnimplemented, - "DescribeTableRestoreStatus": TierUnimplemented, + "DescribeNodeConfigurationOptions": TierAutoCRUD, + "DescribeOrderableClusterOptions": TierAutoCRUD, + "DescribePartners": TierAutoCRUD, + "DescribeRedshiftIdcApplications": TierAutoCRUD, + "DescribeReservedNodeExchangeStatus": TierAutoCRUD, + "DescribeReservedNodeOfferings": TierAutoCRUD, + "DescribeReservedNodes": TierAutoCRUD, + "DescribeResize": TierAutoCRUD, + "DescribeScheduledActions": TierAutoCRUD, + "DescribeSnapshotCopyGrants": TierAutoCRUD, + "DescribeSnapshotSchedules": TierAutoCRUD, + "DescribeStorage": TierAutoCRUD, + "DescribeTableRestoreStatus": TierAutoCRUD, "DescribeTags": TierHandVerified, - "DescribeUsageLimits": TierUnimplemented, + "DescribeUsageLimits": TierAutoCRUD, "DisableLogging": TierHandVerified, "DisableSnapshotCopy": TierUnimplemented, "DisassociateDataShareConsumer": TierUnimplemented, @@ -9865,36 +9865,36 @@ var Services = map[string]Service{ "FailoverPrimaryCompute": TierUnimplemented, "GetClusterCredentials": TierHandVerified, "GetClusterCredentialsWithIAM": TierHandVerified, - "GetIdentityCenterAuthToken": TierUnimplemented, - "GetReservedNodeExchangeConfigurationOptions": TierUnimplemented, - "GetReservedNodeExchangeOfferings": TierUnimplemented, - "GetResourcePolicy": TierUnimplemented, - "ListRecommendations": TierUnimplemented, - "ModifyAquaConfiguration": TierUnimplemented, - "ModifyAuthenticationProfile": TierUnimplemented, + "GetIdentityCenterAuthToken": TierAutoCRUD, + "GetReservedNodeExchangeConfigurationOptions": TierAutoCRUD, + "GetReservedNodeExchangeOfferings": TierAutoCRUD, + "GetResourcePolicy": TierAutoCRUD, + "ListRecommendations": TierAutoCRUD, + "ModifyAquaConfiguration": TierAutoCRUD, + "ModifyAuthenticationProfile": TierAutoCRUD, "ModifyCluster": TierHandVerified, - "ModifyClusterDbRevision": TierUnimplemented, - "ModifyClusterIamRoles": TierUnimplemented, - "ModifyClusterMaintenance": TierUnimplemented, + "ModifyClusterDbRevision": TierAutoCRUD, + "ModifyClusterIamRoles": TierAutoCRUD, + "ModifyClusterMaintenance": TierAutoCRUD, "ModifyClusterParameterGroup": TierHandVerified, - "ModifyClusterSnapshot": TierUnimplemented, - "ModifyClusterSnapshotSchedule": TierUnimplemented, + "ModifyClusterSnapshot": TierAutoCRUD, + "ModifyClusterSnapshotSchedule": TierAutoCRUD, "ModifyClusterSubnetGroup": TierHandVerified, - "ModifyCustomDomainAssociation": TierUnimplemented, - "ModifyEndpointAccess": TierUnimplemented, - "ModifyEventSubscription": TierUnimplemented, - "ModifyIntegration": TierUnimplemented, - "ModifyLakehouseConfiguration": TierUnimplemented, - "ModifyRedshiftIdcApplication": TierUnimplemented, - "ModifyScheduledAction": TierUnimplemented, - "ModifySnapshotCopyRetentionPeriod": TierUnimplemented, - "ModifySnapshotSchedule": TierUnimplemented, - "ModifyUsageLimit": TierUnimplemented, + "ModifyCustomDomainAssociation": TierAutoCRUD, + "ModifyEndpointAccess": TierAutoCRUD, + "ModifyEventSubscription": TierAutoCRUD, + "ModifyIntegration": TierAutoCRUD, + "ModifyLakehouseConfiguration": TierAutoCRUD, + "ModifyRedshiftIdcApplication": TierAutoCRUD, + "ModifyScheduledAction": TierAutoCRUD, + "ModifySnapshotCopyRetentionPeriod": TierAutoCRUD, + "ModifySnapshotSchedule": TierAutoCRUD, + "ModifyUsageLimit": TierAutoCRUD, "PauseCluster": TierHandVerified, "PurchaseReservedNodeOffering": TierUnimplemented, - "PutResourcePolicy": TierUnimplemented, + "PutResourcePolicy": TierAutoCRUD, "RebootCluster": TierHandVerified, - "RegisterNamespace": TierUnimplemented, + "RegisterNamespace": TierAutoCRUD, "RejectDataShare": TierUnimplemented, "ResetClusterParameterGroup": TierHandVerified, "ResizeCluster": TierUnimplemented, @@ -9905,7 +9905,7 @@ var Services = map[string]Service{ "RevokeEndpointAccess": TierUnimplemented, "RevokeSnapshotAccess": TierUnimplemented, "RotateEncryptionKey": TierUnimplemented, - "UpdatePartnerStatus": TierUnimplemented, + "UpdatePartnerStatus": TierAutoCRUD, }}, "redshiftdata": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchExecuteStatement": TierUnimplemented, diff --git a/internal/services/autoscaling/provider.go b/internal/services/autoscaling/provider.go index 2bd4f229..3d6a92de 100644 --- a/internal/services/autoscaling/provider.go +++ b/internal/services/autoscaling/provider.go @@ -174,10 +174,17 @@ func (p *Provider) HandleRequest(ctx context.Context, op string, req *http.Reque return p.handleTerminateInstanceInAutoScalingGroup(form) default: - type genericResult struct { - XMLName xml.Name `xml:"GenericResponse"` - } - return asXMLResponse(http.StatusOK, genericResult{XMLName: xml.Name{Local: action + "Response"}}) + // Hand back to the generic CRUD engine rather than inventing a success. + // This branch used to return 200 with an empty , which + // is a fabricated success for an operation nothing implements — the one + // thing docs/coverage.md says must never happen. It also had no + // wrapper, so botocore's query parser raised KeyError on + // the operations that declare one. + // + // The engine serves the CRUD-shaped actions from the real store and + // refuses the rest with InvalidAction. Either way the caller is told the + // truth. See internal/shared/crud. + return nil, plugin.ErrUnhandledOp } } diff --git a/internal/services/cloudformation/provider.go b/internal/services/cloudformation/provider.go index cb6f3302..60270f82 100644 --- a/internal/services/cloudformation/provider.go +++ b/internal/services/cloudformation/provider.go @@ -204,10 +204,17 @@ func (p *Provider) HandleRequest(ctx context.Context, op string, req *http.Reque return p.handleDescribePublisher(form) default: - type genericResult struct { - XMLName xml.Name `xml:"GenericResponse"` - } - return shared.XMLResponse(http.StatusOK, genericResult{XMLName: xml.Name{Local: action + "Response"}}) + // Hand back to the generic CRUD engine rather than inventing a success. + // This branch used to return 200 with an empty , which + // is a fabricated success for an operation nothing implements — the one + // thing docs/coverage.md says must never happen. It also had no + // wrapper, so botocore's query parser raised KeyError on + // the operations that declare one. + // + // The engine serves the CRUD-shaped actions from the real store and + // refuses the rest with InvalidAction. Either way the caller is told the + // truth. See internal/shared/crud. + return nil, plugin.ErrUnhandledOp } } diff --git a/internal/services/docdb/provider.go b/internal/services/docdb/provider.go index 461054c9..2abe2b19 100644 --- a/internal/services/docdb/provider.go +++ b/internal/services/docdb/provider.go @@ -187,10 +187,17 @@ func (p *Provider) HandleRequest(ctx context.Context, op string, req *http.Reque return p.handleSwitchoverGlobalCluster(form) default: - type genericResult struct { - XMLName xml.Name `xml:"GenericResponse"` - } - return shared.XMLResponse(http.StatusOK, genericResult{XMLName: xml.Name{Local: action + "Response"}}) + // Hand back to the generic CRUD engine rather than inventing a success. + // This branch used to return 200 with an empty , which + // is a fabricated success for an operation nothing implements — the one + // thing docs/coverage.md says must never happen. It also had no + // wrapper, so botocore's query parser raised KeyError on + // the operations that declare one. + // + // The engine serves the CRUD-shaped actions from the real store and + // refuses the rest with InvalidAction. Either way the caller is told the + // truth. See internal/shared/crud. + return nil, plugin.ErrUnhandledOp } } diff --git a/internal/services/elasticache/provider.go b/internal/services/elasticache/provider.go index 32e1108c..def85ab4 100644 --- a/internal/services/elasticache/provider.go +++ b/internal/services/elasticache/provider.go @@ -175,10 +175,17 @@ func (p *Provider) HandleRequest(ctx context.Context, op string, req *http.Reque return p.handleListTagsForResource(form) default: - type genericResponse struct { - XMLName xml.Name `xml:"GenericResponse"` - } - return ecXMLResponse(http.StatusOK, genericResponse{XMLName: xml.Name{Local: action + "Response"}}) + // Hand back to the generic CRUD engine rather than inventing a success. + // This branch used to return 200 with an empty , which + // is a fabricated success for an operation nothing implements — the one + // thing docs/coverage.md says must never happen. It also had no + // wrapper, so botocore's query parser raised KeyError on + // the operations that declare one. + // + // The engine serves the CRUD-shaped actions from the real store and + // refuses the rest with InvalidAction. Either way the caller is told the + // truth. See internal/shared/crud. + return nil, plugin.ErrUnhandledOp } } diff --git a/internal/services/elasticloadbalancingv2/provider.go b/internal/services/elasticloadbalancingv2/provider.go index bbd5ca01..de76a4be 100644 --- a/internal/services/elasticloadbalancingv2/provider.go +++ b/internal/services/elasticloadbalancingv2/provider.go @@ -145,10 +145,17 @@ func (p *Provider) HandleRequest(ctx context.Context, op string, req *http.Reque return p.handleDescribeListenerCertificates(form) default: - type genericResult struct { - XMLName xml.Name `xml:"GenericResponse"` - } - return shared.XMLResponse(http.StatusOK, genericResult{XMLName: xml.Name{Local: action + "Response"}}) + // Hand back to the generic CRUD engine rather than inventing a success. + // This branch used to return 200 with an empty , which + // is a fabricated success for an operation nothing implements — the one + // thing docs/coverage.md says must never happen. It also had no + // wrapper, so botocore's query parser raised KeyError on + // the operations that declare one. + // + // The engine serves the CRUD-shaped actions from the real store and + // refuses the rest with InvalidAction. Either way the caller is told the + // truth. See internal/shared/crud. + return nil, plugin.ErrUnhandledOp } } diff --git a/internal/services/neptune/provider.go b/internal/services/neptune/provider.go index 1427d5e5..de9f737d 100644 --- a/internal/services/neptune/provider.go +++ b/internal/services/neptune/provider.go @@ -225,10 +225,17 @@ func (p *Provider) HandleRequest(ctx context.Context, op string, req *http.Reque return p.handleSwitchoverGlobalCluster(form) default: - type genericResult struct { - XMLName xml.Name `xml:"GenericResponse"` - } - return shared.XMLResponse(http.StatusOK, genericResult{XMLName: xml.Name{Local: action + "Response"}}) + // Hand back to the generic CRUD engine rather than inventing a success. + // This branch used to return 200 with an empty , which + // is a fabricated success for an operation nothing implements — the one + // thing docs/coverage.md says must never happen. It also had no + // wrapper, so botocore's query parser raised KeyError on + // the operations that declare one. + // + // The engine serves the CRUD-shaped actions from the real store and + // refuses the rest with InvalidAction. Either way the caller is told the + // truth. See internal/shared/crud. + return nil, plugin.ErrUnhandledOp } } diff --git a/internal/services/rds/provider.go b/internal/services/rds/provider.go index 21c3103b..be9bd304 100644 --- a/internal/services/rds/provider.go +++ b/internal/services/rds/provider.go @@ -201,10 +201,17 @@ func (p *Provider) HandleRequest(ctx context.Context, op string, req *http.Reque return p.handleApplyPendingMaintenanceAction(form) default: - type genericResult struct { - XMLName xml.Name `xml:"GenericResponse"` - } - return shared.XMLResponse(http.StatusOK, genericResult{XMLName: xml.Name{Local: action + "Response"}}) + // Hand back to the generic CRUD engine rather than inventing a success. + // This branch used to return 200 with an empty , which + // is a fabricated success for an operation nothing implements — the one + // thing docs/coverage.md says must never happen. It also had no + // wrapper, so botocore's query parser raised KeyError on + // the operations that declare one. + // + // The engine serves the CRUD-shaped actions from the real store and + // refuses the rest with InvalidAction. Either way the caller is told the + // truth. See internal/shared/crud. + return nil, plugin.ErrUnhandledOp } } diff --git a/internal/services/redshift/provider.go b/internal/services/redshift/provider.go index d91a76ac..462076a0 100644 --- a/internal/services/redshift/provider.go +++ b/internal/services/redshift/provider.go @@ -135,10 +135,17 @@ func (p *Provider) HandleRequest(ctx context.Context, op string, req *http.Reque return p.handleGetClusterCredentialsWithIAM(form) default: - type genericResult struct { - XMLName xml.Name `xml:"GenericResponse"` - } - return shared.XMLResponse(http.StatusOK, genericResult{XMLName: xml.Name{Local: action + "Response"}}) + // Hand back to the generic CRUD engine rather than inventing a success. + // This branch used to return 200 with an empty , which + // is a fabricated success for an operation nothing implements — the one + // thing docs/coverage.md says must never happen. It also had no + // wrapper, so botocore's query parser raised KeyError on + // the operations that declare one. + // + // The engine serves the CRUD-shaped actions from the real store and + // refuses the rest with InvalidAction. Either way the caller is told the + // truth. See internal/shared/crud. + return nil, plugin.ErrUnhandledOp } } diff --git a/tests/compatibility/test_no_fabricated_success.py b/tests/compatibility/test_no_fabricated_success.py new file mode 100644 index 00000000..9c659c90 --- /dev/null +++ b/tests/compatibility/test_no_fabricated_success.py @@ -0,0 +1,144 @@ +"""An operation DevCloud does not serve must never answer 200. + +This is the one guarantee docs/coverage.md calls absolute: + + What it must never do is fabricate a success. + +Registering a service DevCloud cannot fully serve is worth doing — the call is +routed and answered locally instead of silently reaching a billed AWS account — +but only while the answer is an honest error. A fabricated 200 is worse than not +registering the service at all, because the caller believes it. + +test_service_smoke.py already asserts this for services that serve *nothing*. +The gap this file closes is the other case, and the one the defect lived in: a +service that serves plenty and answers an operation it does not implement with +an empty success anyway. The fidelity manifest says which operations are served; +every operation it does not list must decline. +""" + +import pytest +from botocore import xform_name +from botocore.exceptions import ClientError, ParamValidationError + +import _coverage + +MANIFEST = _coverage.load_manifest() + +# Operations to avoid probing with. A refusal is observable without writing +# anything, so nothing that could create or overwrite state is used. Delete and +# Modify of a resource that does not exist stay in scope — an empty store has +# nothing to lose. +_MUTATING_PREFIXES = ("Create", "Put", "Register", "Add", "Import", "Start", "Run") + + +def _unserved_probe(service_id, entry): + """Return an operation the manifest says is not served, or None. + + Reads first, so a failure reads unambiguously. + """ + name = _coverage.boto3_name(service_id) + if name is None: + return None, None + + model = _coverage.service_model(name) + unserved = sorted(set(model.operation_names) - set(entry["servedOps"])) + + for prefix in ("Describe", "List", "Get"): + for op in unserved: + if op.startswith(prefix): + return name, op + + for op in unserved: + if not op.startswith(_MUTATING_PREFIXES): + return name, op + return name, None + + +# Two fabricated successes that this file's fix does not reach, marked strict so +# they fail the moment they start passing rather than rotting into an accepted +# state. Only what was observed is recorded — the mechanism behind each is not +# the provider `default` branch that was fixed here, and has not been identified: +# +# s3.ListBucketAnalyticsConfigurations +# GET /{Bucket}?analytics answers 200 with an empty body. S3's provider +# default returns MethodNotAllowed, so this is not that branch. +# +# resourcegroups.Tag +# PUT /resources/{Arn}/tags answers 200 echoing the request's Arn and +# Tags. The manifest lists the operation as unimplemented and the CRUD +# registry does not hold it; it holds GetTags at the same path under GET, +# and httproute.Match does compare methods (match.go:42), so the obvious +# explanation is ruled out rather than confirmed. +# +# Both are real violations of the guarantee and neither is fixed here: they are +# different defects that deserve their own diagnosis and their own change. +KNOWN_UNFIXED = { + ( + "s3", + "ListBucketAnalyticsConfigurations", + ): "empty 200 from S3's sub-resource routing", + ( + "resourcegroups", + "Tag", + ): "engine-shaped echo for an operation the manifest calls unimplemented", +} + +# Every service that is addressable, routable, and has an unserved operation to +# ask for. Built at collection time so the parametrisation names the operation +# rather than an index. +_PROBES = [] +for _service in sorted(MANIFEST): + if ( + _service in _coverage.NO_BOTO3_CLIENT + or _service in _coverage.UNREACHABLE_FROM_BOTO3 + ): + continue + _name, _op = _unserved_probe(_service, MANIFEST[_service]) + if _op is not None: + _PROBES.append((_service, _name, _op)) + + +def _case(service, client_name, operation): + reason = KNOWN_UNFIXED.get((service, operation)) + marks = [pytest.mark.xfail(strict=True, reason=reason)] if reason else [] + return pytest.param(service, client_name, operation, marks=marks) + + +@pytest.mark.parametrize( + "service,client_name,operation", + [_case(*probe) for probe in _PROBES], + ids=[f"{s}.{op}" for s, _, op in _PROBES], +) +def test_unserved_operation_declines(service_client, service, client_name, operation): + client = service_client(client_name) + params = _coverage.stub_params(client_name, operation) + + try: + response = getattr(client, xform_name(operation))(**params) + except ParamValidationError: + pytest.skip( + f"{client_name}.{operation}: the stub builder cannot satisfy this input " + "shape, so the request never reaches DevCloud" + ) + except ClientError as exc: + assert exc.response.get("Error", {}).get("Code"), ( + f"{service} ({client_name}.{operation}) failed without an AWS error " + f"code: {exc.response.get('Error')}" + ) + return + except Exception as exc: # noqa: BLE001 - reported, not swallowed + pytest.fail( + f"{service} ({client_name}.{operation}, {MANIFEST[service]['protocol']}) " + f"answered something botocore could not parse ({type(exc).__name__}: " + f"{exc}). The manifest does not list this operation as served, so the " + "answer should have been a clean AWS error." + ) + + pytest.fail( + f"{service} ({client_name}.{operation}, {MANIFEST[service]['protocol']}) " + f"returned {response['ResponseMetadata']['HTTPStatusCode']} for an " + "operation the fidelity manifest does not list as served. That is a " + "fabricated success — the guarantee docs/coverage.md calls absolute. " + "The provider's default branch most likely answers unknown operations " + "itself instead of returning plugin.ErrUnhandledOp." + )