refactor: unregister EKS NotImplemented stubs so coverage counts only served operations (#1172)

This commit is contained in:
Julian Sommer
2026-10-06 15:57:04 +11:00
committed by GitHub
parent 144a449b82
commit cfc7b76cca
24 changed files with 81 additions and 555 deletions
+3 -3
View File
@@ -17,7 +17,7 @@ tags:
## Overview
The platform serves **400 operations** across the AWS APIs below. Every page names the operations its service implements from the pinned model, generated from the dispatch tables on each build rather than written by hand.
The platform serves **391 operations** across the AWS APIs below. Every page names the operations its service implements from the pinned model, generated from the dispatch tables on each build rather than written by hand.
| Service | Operations |
|---|---:|
@@ -25,10 +25,10 @@ The platform serves **400 operations** across the AWS APIs below. Every page nam
| [EC2](/coverage/ec2) | 127 |
| [ECR](/coverage/ecr) | 22 |
| [ECS](/coverage/ecs) | 31 |
| [EKS](/coverage/eks) | 36 |
| [EKS](/coverage/eks) | 27 |
| [ELBv2](/coverage/elbv2) | 36 |
| [IAM](/coverage/iam) | 81 |
| [RDS](/coverage/rds) | 27 |
| [S3](/coverage/s3) | 26 |
| [STS](/coverage/sts) | 5 |
| **Total** | **400** |
| **Total** | **391** |
+10 -19
View File
@@ -2348,7 +2348,6 @@
],
"registered": [
"AssociateAccessPolicy",
"AssociateIdentityProviderConfig",
"CreateAccessEntry",
"CreateAddon",
"CreateCluster",
@@ -2361,36 +2360,27 @@
"DescribeAddon",
"DescribeAddonVersions",
"DescribeCluster",
"DescribeIdentityProviderConfig",
"DescribeNodegroup",
"DescribeUpdate",
"DisassociateAccessPolicy",
"DisassociateIdentityProviderConfig",
"GetRecoveryDirective",
"ListAccessEntries",
"ListAccessPolicies",
"ListAddons",
"ListAssociatedAccessPolicies",
"ListClusters",
"ListIdentityProviderConfigs",
"ListInternalAddons",
"ListNodegroups",
"ListTagsForResource",
"ListUpdates",
"PublishInternal",
"TagResource",
"UntagResource",
"UpdateAccessEntry",
"UpdateAddon",
"UpdateClusterConfig",
"UpdateClusterVersion",
"UpdateNodegroupConfig",
"UpdateNodegroupVersion",
"WebhookTokenReview"
],
"implemented": [
"AssociateAccessPolicy",
"AssociateIdentityProviderConfig",
"CreateAccessEntry",
"CreateAddon",
"CreateCluster",
@@ -2403,34 +2393,27 @@
"DescribeAddon",
"DescribeAddonVersions",
"DescribeCluster",
"DescribeIdentityProviderConfig",
"DescribeNodegroup",
"DescribeUpdate",
"DisassociateAccessPolicy",
"DisassociateIdentityProviderConfig",
"ListAccessEntries",
"ListAccessPolicies",
"ListAddons",
"ListAssociatedAccessPolicies",
"ListClusters",
"ListIdentityProviderConfigs",
"ListNodegroups",
"ListTagsForResource",
"ListUpdates",
"TagResource",
"UntagResource",
"UpdateAccessEntry",
"UpdateAddon",
"UpdateClusterConfig",
"UpdateClusterVersion",
"UpdateNodegroupConfig",
"UpdateNodegroupVersion"
"UpdateNodegroupConfig"
],
"stubbed": [],
"unsupported": [],
"missing": [
"ActivateCertificateAuthority",
"AssociateEncryptionConfig",
"AssociateIdentityProviderConfig",
"CancelUpdate",
"CreateCapability",
"CreateCertificateAuthority",
@@ -2449,19 +2432,27 @@
"DescribeClusterVersions",
"DescribeEksAnywhereSubscription",
"DescribeFargateProfile",
"DescribeIdentityProviderConfig",
"DescribeInsight",
"DescribeInsightsRefresh",
"DescribePodIdentityAssociation",
"DescribeUpdate",
"DisassociateIdentityProviderConfig",
"ListCapabilities",
"ListCertificateAuthorities",
"ListEksAnywhereSubscriptions",
"ListFargateProfiles",
"ListIdentityProviderConfigs",
"ListInsights",
"ListPodIdentityAssociations",
"ListUpdates",
"RegisterCluster",
"StartInsightsRefresh",
"UpdateCapability",
"UpdateClusterConfig",
"UpdateClusterVersion",
"UpdateEksAnywhereSubscription",
"UpdateNodegroupVersion",
"UpdatePodIdentityAssociation"
],
"extra": [
+1 -10
View File
@@ -18,14 +18,13 @@ tags:
## Overview
Spinifex implements **36 operations** in the EKS `2017-11-01` API model.
Spinifex implements **27 operations** in the EKS `2017-11-01` API model.
### Operations
| Operation |
|---|
| `AssociateAccessPolicy` |
| `AssociateIdentityProviderConfig` |
| `CreateAccessEntry` |
| `CreateAddon` |
| `CreateCluster` |
@@ -38,25 +37,17 @@ Spinifex implements **36 operations** in the EKS `2017-11-01` API model.
| `DescribeAddon` |
| `DescribeAddonVersions` |
| `DescribeCluster` |
| `DescribeIdentityProviderConfig` |
| `DescribeNodegroup` |
| `DescribeUpdate` |
| `DisassociateAccessPolicy` |
| `DisassociateIdentityProviderConfig` |
| `ListAccessEntries` |
| `ListAccessPolicies` |
| `ListAddons` |
| `ListAssociatedAccessPolicies` |
| `ListClusters` |
| `ListIdentityProviderConfigs` |
| `ListNodegroups` |
| `ListTagsForResource` |
| `ListUpdates` |
| `TagResource` |
| `UntagResource` |
| `UpdateAccessEntry` |
| `UpdateAddon` |
| `UpdateClusterConfig` |
| `UpdateClusterVersion` |
| `UpdateNodegroupConfig` |
| `UpdateNodegroupVersion` |
+10 -1
View File
@@ -882,12 +882,13 @@ spot-price: On owned hardware there is no spot-to-on-demand price differential,
## eks
`2017-11-01` — 36 of 70 modelled operations implemented (51.4%), 0 stubbed, 0 not applicable, 4 registered outside the pinned model.
`2017-11-01` — 27 of 70 modelled operations implemented (38.6%), 0 stubbed, 0 not applicable, 4 registered outside the pinned model.
### Not implemented
- `ActivateCertificateAuthority`
- `AssociateEncryptionConfig`
- `AssociateIdentityProviderConfig`
- `CancelUpdate`
- `CreateCapability`
- `CreateCertificateAuthority`
@@ -906,19 +907,27 @@ spot-price: On owned hardware there is no spot-to-on-demand price differential,
- `DescribeClusterVersions`
- `DescribeEksAnywhereSubscription`
- `DescribeFargateProfile`
- `DescribeIdentityProviderConfig`
- `DescribeInsight`
- `DescribeInsightsRefresh`
- `DescribePodIdentityAssociation`
- `DescribeUpdate`
- `DisassociateIdentityProviderConfig`
- `ListCapabilities`
- `ListCertificateAuthorities`
- `ListEksAnywhereSubscriptions`
- `ListFargateProfiles`
- `ListIdentityProviderConfigs`
- `ListInsights`
- `ListPodIdentityAssociations`
- `ListUpdates`
- `RegisterCluster`
- `StartInsightsRefresh`
- `UpdateCapability`
- `UpdateClusterConfig`
- `UpdateClusterVersion`
- `UpdateEksAnywhereSubscription`
- `UpdateNodegroupVersion`
- `UpdatePodIdentityAssociation`
### Registered outside the pinned model
+1 -10
View File
@@ -1076,22 +1076,17 @@ func (d *Daemon) subscribeAll() error {
)
}
// EKS gateway → daemon subscriptions. Every handler currently returns
// NotImplemented; topics are subscribed up-front so the wiring layer is
// stable while real bodies land.
// EKS gateway → daemon subscriptions.
if d.eksService != nil {
subs = append(subs,
natsSub{"eks.CreateCluster", handleNATSRequestWithPrincipal(d.node, d.eksService.CreateCluster), "spinifex-workers"},
natsSub{"eks.DescribeCluster", handleNATSRequest(d.node, d.eksService.DescribeCluster), "spinifex-workers"},
natsSub{"eks.ListClusters", handleNATSRequest(d.node, d.eksService.ListClusters), "spinifex-workers"},
natsSub{"eks.UpdateClusterConfig", handleNATSRequest(d.node, d.eksService.UpdateClusterConfig), "spinifex-workers"},
natsSub{"eks.UpdateClusterVersion", handleNATSRequest(d.node, d.eksService.UpdateClusterVersion), "spinifex-workers"},
natsSub{"eks.DeleteCluster", handleNATSRequest(d.node, d.eksService.DeleteCluster), "spinifex-workers"},
natsSub{"eks.CreateNodegroup", handleNATSRequest(d.node, d.eksService.CreateNodegroup), "spinifex-workers"},
natsSub{"eks.DescribeNodegroup", handleNATSRequest(d.node, d.eksService.DescribeNodegroup), "spinifex-workers"},
natsSub{"eks.ListNodegroups", handleNATSRequest(d.node, d.eksService.ListNodegroups), "spinifex-workers"},
natsSub{"eks.UpdateNodegroupConfig", handleNATSRequest(d.node, d.eksService.UpdateNodegroupConfig), "spinifex-workers"},
natsSub{"eks.UpdateNodegroupVersion", handleNATSRequest(d.node, d.eksService.UpdateNodegroupVersion), "spinifex-workers"},
natsSub{"eks.DeleteNodegroup", handleNATSRequest(d.node, d.eksService.DeleteNodegroup), "spinifex-workers"},
natsSub{"eks.CreateAccessEntry", handleNATSRequest(d.node, d.eksService.CreateAccessEntry), "spinifex-workers"},
natsSub{"eks.DescribeAccessEntry", handleNATSRequest(d.node, d.eksService.DescribeAccessEntry), "spinifex-workers"},
@@ -1112,10 +1107,6 @@ func (d *Daemon) subscribeAll() error {
natsSub{"eks.GetRecoveryDirective", handleNATSRequest(d.node, d.eksService.GetRecoveryDirective), "spinifex-workers"},
natsSub{"eks.SetRecoveryDirective", handleNATSRequest(d.node, d.eksService.SetRecoveryDirective), "spinifex-workers"},
natsSub{"eks.RestoreSnapshot", handleNATSRequest(d.node, d.eksService.RestoreSnapshot), "spinifex-workers"},
natsSub{"eks.AssociateIdentityProviderConfig", handleNATSRequest(d.node, d.eksService.AssociateIdentityProviderConfig), "spinifex-workers"},
natsSub{"eks.DescribeIdentityProviderConfig", handleNATSRequest(d.node, d.eksService.DescribeIdentityProviderConfig), "spinifex-workers"},
natsSub{"eks.ListIdentityProviderConfigs", handleNATSRequest(d.node, d.eksService.ListIdentityProviderConfigs), "spinifex-workers"},
natsSub{"eks.DisassociateIdentityProviderConfig", handleNATSRequest(d.node, d.eksService.DisassociateIdentityProviderConfig), "spinifex-workers"},
natsSub{"eks.TagResource", handleNATSRequest(d.node, d.eksService.TagResource), "spinifex-workers"},
natsSub{"eks.UntagResource", handleNATSRequest(d.node, d.eksService.UntagResource), "spinifex-workers"},
natsSub{"eks.ListTagsForResource", handleNATSRequest(d.node, d.eksService.ListTagsForResource), "spinifex-workers"},
+2 -10
View File
@@ -63,21 +63,17 @@ func TestDaemonHandleEKS_AllHandlersDispatchToService(t *testing.T) {
invalid := awserrors.ErrorInvalidParameterValue
// Nodegroup mutators gate on orchestration deps, which the shim service
// lacks → ServiceUnavailable. The read paths reach input validation and an
// empty body fails with InvalidParameterValue. UpdateNodegroupVersion stays
// NotImplemented (v1 doesn't do AMI upgrades).
// empty body fails with InvalidParameterValue.
unavailable := awserrors.ErrorServiceUnavailable
cases := []struct {
subject string
handler nats.MsgHandler
wantCode string
}{
{"eks.UpdateClusterConfig", asMsgHandler(handleNATSRequest(d.node, d.eksService.UpdateClusterConfig)), notImpl},
{"eks.UpdateClusterVersion", asMsgHandler(handleNATSRequest(d.node, d.eksService.UpdateClusterVersion)), notImpl},
{"eks.CreateNodegroup", asMsgHandler(handleNATSRequest(d.node, d.eksService.CreateNodegroup)), unavailable},
{"eks.DescribeNodegroup", asMsgHandler(handleNATSRequest(d.node, d.eksService.DescribeNodegroup)), invalid},
{"eks.ListNodegroups", asMsgHandler(handleNATSRequest(d.node, d.eksService.ListNodegroups)), invalid},
{"eks.UpdateNodegroupConfig", asMsgHandler(handleNATSRequest(d.node, d.eksService.UpdateNodegroupConfig)), unavailable},
{"eks.UpdateNodegroupVersion", asMsgHandler(handleNATSRequest(d.node, d.eksService.UpdateNodegroupVersion)), notImpl},
{"eks.DeleteNodegroup", asMsgHandler(handleNATSRequest(d.node, d.eksService.DeleteNodegroup)), unavailable},
{"eks.CreateAccessEntry", asMsgHandler(handleNATSRequest(d.node, d.eksService.CreateAccessEntry)), invalid},
{"eks.DescribeAccessEntry", asMsgHandler(handleNATSRequest(d.node, d.eksService.DescribeAccessEntry)), invalid},
@@ -97,15 +93,11 @@ func TestDaemonHandleEKS_AllHandlersDispatchToService(t *testing.T) {
{"eks.DeleteAddon", asMsgHandler(handleNATSRequest(d.node, d.eksService.DeleteAddon)), invalid},
{"eks.DescribeAddon", asMsgHandler(handleNATSRequest(d.node, d.eksService.DescribeAddon)), invalid},
{"eks.UpdateAddon", asMsgHandler(handleNATSRequest(d.node, d.eksService.UpdateAddon)), invalid},
{"eks.AssociateIdentityProviderConfig", asMsgHandler(handleNATSRequest(d.node, d.eksService.AssociateIdentityProviderConfig)), notImpl},
{"eks.DescribeIdentityProviderConfig", asMsgHandler(handleNATSRequest(d.node, d.eksService.DescribeIdentityProviderConfig)), notImpl},
{"eks.ListIdentityProviderConfigs", asMsgHandler(handleNATSRequest(d.node, d.eksService.ListIdentityProviderConfigs)), notImpl},
{"eks.DisassociateIdentityProviderConfig", asMsgHandler(handleNATSRequest(d.node, d.eksService.DisassociateIdentityProviderConfig)), notImpl},
{"eks.TagResource", asMsgHandler(handleNATSRequest(d.node, d.eksService.TagResource)), notImpl},
{"eks.UntagResource", asMsgHandler(handleNATSRequest(d.node, d.eksService.UntagResource)), notImpl},
{"eks.ListTagsForResource", asMsgHandler(handleNATSRequest(d.node, d.eksService.ListTagsForResource)), notImpl},
}
require.Len(t, cases, 30, "expected exactly one handler per non-lifecycle AWS EKS action")
require.Len(t, cases, 23, "expected exactly one handler per non-lifecycle AWS EKS action")
for _, c := range cases {
t.Run(c.subject, func(t *testing.T) {
-42
View File
@@ -44,26 +44,6 @@ var eksRoutes = []eksRoute{
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.ListClusters(ctx, gw.NATSConn, acct)
}},
{"POST", "/clusters/{clusterName}/update-config", "UpdateClusterConfig",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.UpdateClusterConfig(ctx, gw.NATSConn, acct, p[0], b)
}},
{"POST", "/clusters/{clusterName}/updates", "UpdateClusterVersion",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.UpdateClusterVersion(ctx, gw.NATSConn, acct, p[0], b)
}},
// The update surface these two read is absent, so they refuse here rather
// than through a service method: a round-trip to reach a constant refusal
// is surface for its own sake. Left unregistered they would answer
// InvalidAction, which blames the caller's spelling for a routing gap.
{"GET", "/clusters/{clusterName}/updates", "ListUpdates",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return nil, errors.New(awserrors.ErrorNotImplemented)
}},
{"GET", "/clusters/{clusterName}/updates/{updateId}", "DescribeUpdate",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return nil, errors.New(awserrors.ErrorNotImplemented)
}},
// Control-plane VM broker: relays bootstrap/state POSTs onto eks.bus.*/eks.state.* NATS subjects.
// acct and callerARN are ignored; cluster account comes from the body.
{"POST", "/clusters/{clusterName}/internal-publish", "PublishInternal",
@@ -108,10 +88,6 @@ var eksRoutes = []eksRoute{
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.UpdateNodegroupConfig(ctx, gw.NATSConn, acct, p[0], p[1], b)
}},
{"POST", "/clusters/{clusterName}/node-groups/{nodegroupName}/update-version", "UpdateNodegroupVersion",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.UpdateNodegroupVersion(ctx, gw.NATSConn, acct, p[0], p[1], b)
}},
{"GET", "/clusters/{clusterName}/node-groups/{nodegroupName}", "DescribeNodegroup",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.DescribeNodegroup(ctx, gw.NATSConn, acct, p[0], p[1])
@@ -185,24 +161,6 @@ var eksRoutes = []eksRoute{
return gateway_eks.DeleteAddon(ctx, gw.NATSConn, acct, p[0], p[1])
}},
// OIDC identity-provider configs
{"POST", "/clusters/{clusterName}/identity-provider-configs/associate", "AssociateIdentityProviderConfig",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.AssociateIdentityProviderConfig(ctx, gw.NATSConn, acct, p[0], b)
}},
{"POST", "/clusters/{clusterName}/identity-provider-configs/describe", "DescribeIdentityProviderConfig",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.DescribeIdentityProviderConfig(ctx, gw.NATSConn, acct, p[0], b)
}},
{"POST", "/clusters/{clusterName}/identity-provider-configs/disassociate", "DisassociateIdentityProviderConfig",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.DisassociateIdentityProviderConfig(ctx, gw.NATSConn, acct, p[0], b)
}},
{"GET", "/clusters/{clusterName}/identity-provider-configs", "ListIdentityProviderConfigs",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
return gateway_eks.ListIdentityProviderConfigs(ctx, gw.NATSConn, acct, p[0])
}},
// Cluster CRUD — listed after more-specific /clusters/{name}/... routes.
{"GET", "/clusters/{clusterName}", "DescribeCluster",
func(ctx context.Context, gw *GatewayConfig, acct, callerARN string, p []string, b []byte) (any, error) {
+9 -22
View File
@@ -44,14 +44,10 @@ const (
// dispatch table in both directions.
var eksScopes = map[string][]resourceSource{
// Cluster.
"CreateCluster": {sourceClusterFromBody},
"DescribeCluster": {sourceCluster},
"DeleteCluster": {sourceCluster},
"UpdateClusterConfig": {sourceCluster},
"UpdateClusterVersion": {sourceCluster},
"ListUpdates": {sourceCluster},
"DescribeUpdate": {sourceCluster},
"ListClusters": {sourceAny},
"CreateCluster": {sourceClusterFromBody},
"DescribeCluster": {sourceCluster},
"DeleteCluster": {sourceCluster},
"ListClusters": {sourceAny},
// Internal control-plane routes. The cluster's owning account is a path
// segment on these two, and the ARN names that account rather than the
@@ -65,12 +61,11 @@ var eksScopes = map[string][]resourceSource{
// Nodegroups. Create evaluates the cluster and the nodegroup it is about
// to create, matching AWS.
"CreateNodegroup": {sourceCluster, sourceNodegroupFromBody},
"DescribeNodegroup": {sourceNodegroup},
"DeleteNodegroup": {sourceNodegroup},
"UpdateNodegroupConfig": {sourceNodegroup},
"UpdateNodegroupVersion": {sourceNodegroup},
"ListNodegroups": {sourceCluster},
"CreateNodegroup": {sourceCluster, sourceNodegroupFromBody},
"DescribeNodegroup": {sourceNodegroup},
"DeleteNodegroup": {sourceNodegroup},
"UpdateNodegroupConfig": {sourceNodegroup},
"ListNodegroups": {sourceCluster},
// Access entries and policies.
"CreateAccessEntry": {sourceCluster, sourceAccessEntryFromBody},
@@ -93,14 +88,6 @@ var eksScopes = map[string][]resourceSource{
// The add-on version catalogue is not an account resource.
"DescribeAddonVersions": {sourceAny},
// Identity-provider configs. All four handlers are stubs and no
// identity-provider-config object exists here, so the cluster is the only
// resource these name.
"AssociateIdentityProviderConfig": {sourceCluster},
"DescribeIdentityProviderConfig": {sourceCluster},
"DisassociateIdentityProviderConfig": {sourceCluster},
"ListIdentityProviderConfigs": {sourceCluster},
// Tags.
"TagResource": {sourceTagARN},
"UntagResource": {sourceTagARN},
-20
View File
@@ -31,26 +31,6 @@ func ListClusters(ctx context.Context, natsConn *nats.Conn, accountID string) (*
return handlers_eks.NewNATSEKSService(natsConn).ListClusters(ctx, &eks.ListClustersInput{}, accountID)
}
// UpdateClusterConfig — POST /clusters/{name}/update-config.
func UpdateClusterConfig(ctx context.Context, natsConn *nats.Conn, accountID, name string, body []byte) (*eks.UpdateClusterConfigOutput, error) {
input := new(eks.UpdateClusterConfigInput)
if err := unmarshalIfBody(body, input); err != nil {
return nil, err
}
input.Name = aws.String(name)
return handlers_eks.NewNATSEKSService(natsConn).UpdateClusterConfig(ctx, input, accountID)
}
// UpdateClusterVersion — POST /clusters/{name}/update-version.
func UpdateClusterVersion(ctx context.Context, natsConn *nats.Conn, accountID, name string, body []byte) (*eks.UpdateClusterVersionOutput, error) {
input := new(eks.UpdateClusterVersionInput)
if err := unmarshalIfBody(body, input); err != nil {
return nil, err
}
input.Name = aws.String(name)
return handlers_eks.NewNATSEKSService(natsConn).UpdateClusterVersion(ctx, input, accountID)
}
// DeleteCluster — DELETE /clusters/{name}.
func DeleteCluster(ctx context.Context, natsConn *nats.Conn, accountID, name string) (*eks.DeleteClusterOutput, error) {
input := &eks.DeleteClusterInput{Name: aws.String(name)}
-11
View File
@@ -44,17 +44,6 @@ func UpdateNodegroupConfig(ctx context.Context, natsConn *nats.Conn, accountID,
return handlers_eks.NewNATSEKSService(natsConn).UpdateNodegroupConfig(ctx, input, accountID)
}
// UpdateNodegroupVersion — POST /clusters/{name}/node-groups/{ng}/update-version.
func UpdateNodegroupVersion(ctx context.Context, natsConn *nats.Conn, accountID, cluster, ng string, body []byte) (*eks.UpdateNodegroupVersionOutput, error) {
input := new(eks.UpdateNodegroupVersionInput)
if err := unmarshalIfBody(body, input); err != nil {
return nil, err
}
input.ClusterName = aws.String(cluster)
input.NodegroupName = aws.String(ng)
return handlers_eks.NewNATSEKSService(natsConn).UpdateNodegroupVersion(ctx, input, accountID)
}
// DeleteNodegroup — DELETE /clusters/{name}/node-groups/{ng}.
func DeleteNodegroup(ctx context.Context, natsConn *nats.Conn, accountID, cluster, ng string) (*eks.DeleteNodegroupOutput, error) {
input := &eks.DeleteNodegroupInput{
-45
View File
@@ -1,45 +0,0 @@
package gateway_eks
import (
"context"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/eks"
handlers_eks "github.com/mulgadc/spinifex/spinifex/handlers/eks"
"github.com/nats-io/nats.go"
)
// AssociateIdentityProviderConfig — POST /clusters/{name}/identity-provider-configs/associate.
func AssociateIdentityProviderConfig(ctx context.Context, natsConn *nats.Conn, accountID, cluster string, body []byte) (*eks.AssociateIdentityProviderConfigOutput, error) {
input := new(eks.AssociateIdentityProviderConfigInput)
if err := unmarshalIfBody(body, input); err != nil {
return nil, err
}
input.ClusterName = aws.String(cluster)
return handlers_eks.NewNATSEKSService(natsConn).AssociateIdentityProviderConfig(ctx, input, accountID)
}
// DescribeIdentityProviderConfig — POST /clusters/{name}/identity-provider-configs/describe.
func DescribeIdentityProviderConfig(ctx context.Context, natsConn *nats.Conn, accountID, cluster string, body []byte) (*eks.DescribeIdentityProviderConfigOutput, error) {
input := new(eks.DescribeIdentityProviderConfigInput)
if err := unmarshalIfBody(body, input); err != nil {
return nil, err
}
input.ClusterName = aws.String(cluster)
return handlers_eks.NewNATSEKSService(natsConn).DescribeIdentityProviderConfig(ctx, input, accountID)
}
// ListIdentityProviderConfigs — GET /clusters/{name}/identity-provider-configs.
func ListIdentityProviderConfigs(ctx context.Context, natsConn *nats.Conn, accountID, cluster string) (*eks.ListIdentityProviderConfigsOutput, error) {
input := &eks.ListIdentityProviderConfigsInput{ClusterName: aws.String(cluster)}
return handlers_eks.NewNATSEKSService(natsConn).ListIdentityProviderConfigs(ctx, input, accountID)
}
// DisassociateIdentityProviderConfig — POST /clusters/{name}/identity-provider-configs/disassociate.
func DisassociateIdentityProviderConfig(ctx context.Context, natsConn *nats.Conn, accountID, cluster string, body []byte) (*eks.DisassociateIdentityProviderConfigOutput, error) {
input := new(eks.DisassociateIdentityProviderConfigInput)
if err := unmarshalIfBody(body, input); err != nil {
return nil, err
}
input.ClusterName = aws.String(cluster)
return handlers_eks.NewNATSEKSService(natsConn).DisassociateIdentityProviderConfig(ctx, input, accountID)
}
+2 -77
View File
@@ -47,25 +47,9 @@ func TestGatewayWrappers_Cluster(t *testing.T) {
require.NoError(t, err)
assert.NotNil(t, out4)
out5, err := UpdateClusterConfig(context.Background(), nc, acct, "alpha", []byte(`{}`))
out5, err := DeleteCluster(context.Background(), nc, acct, "alpha")
require.NoError(t, err)
assert.NotNil(t, out5)
out6, err := UpdateClusterConfig(context.Background(), nc, acct, "alpha", nil)
require.NoError(t, err)
assert.NotNil(t, out6)
out7, err := UpdateClusterVersion(context.Background(), nc, acct, "alpha", []byte(`{"version":"1.30"}`))
require.NoError(t, err)
assert.NotNil(t, out7)
out8, err := UpdateClusterVersion(context.Background(), nc, acct, "alpha", nil)
require.NoError(t, err)
assert.NotNil(t, out8)
out9, err := DeleteCluster(context.Background(), nc, acct, "alpha")
require.NoError(t, err)
assert.NotNil(t, out9)
}
func TestGatewayWrappers_Cluster_BadJSON(t *testing.T) {
@@ -74,10 +58,6 @@ func TestGatewayWrappers_Cluster_BadJSON(t *testing.T) {
_, err := CreateCluster(context.Background(), nc, acct, "", []byte(`{not-json`))
require.Error(t, err)
_, err = UpdateClusterConfig(context.Background(), nc, acct, "alpha", []byte(`{not-json`))
require.Error(t, err)
_, err = UpdateClusterVersion(context.Background(), nc, acct, "alpha", []byte(`{not-json`))
require.Error(t, err)
}
func TestGatewayWrappers_Nodegroup(t *testing.T) {
@@ -108,17 +88,9 @@ func TestGatewayWrappers_Nodegroup(t *testing.T) {
require.NoError(t, err)
assert.NotNil(t, out6)
out7, err := UpdateNodegroupVersion(context.Background(), nc, acct, "alpha", "ng1", []byte(`{}`))
out7, err := DeleteNodegroup(context.Background(), nc, acct, "alpha", "ng1")
require.NoError(t, err)
assert.NotNil(t, out7)
out8, err := UpdateNodegroupVersion(context.Background(), nc, acct, "alpha", "ng1", nil)
require.NoError(t, err)
assert.NotNil(t, out8)
out9, err := DeleteNodegroup(context.Background(), nc, acct, "alpha", "ng1")
require.NoError(t, err)
assert.NotNil(t, out9)
}
func TestGatewayWrappers_Nodegroup_BadJSON(t *testing.T) {
@@ -129,8 +101,6 @@ func TestGatewayWrappers_Nodegroup_BadJSON(t *testing.T) {
require.Error(t, err)
_, err = UpdateNodegroupConfig(context.Background(), nc, acct, "alpha", "ng1", []byte(`{nope`))
require.Error(t, err)
_, err = UpdateNodegroupVersion(context.Background(), nc, acct, "alpha", "ng1", []byte(`{nope`))
require.Error(t, err)
}
func TestGatewayWrappers_Access(t *testing.T) {
@@ -245,51 +215,6 @@ func TestGatewayWrappers_Addons_BadJSON(t *testing.T) {
require.Error(t, err)
}
func TestGatewayWrappers_OIDC(t *testing.T) {
_, nc := testutil.StartTestNATS(t)
stubEKSResponder(t, nc)
out1, err := AssociateIdentityProviderConfig(context.Background(), nc, acct, "alpha", []byte(`{}`))
require.NoError(t, err)
assert.NotNil(t, out1)
out2, err := AssociateIdentityProviderConfig(context.Background(), nc, acct, "alpha", nil)
require.NoError(t, err)
assert.NotNil(t, out2)
out3, err := DescribeIdentityProviderConfig(context.Background(), nc, acct, "alpha", []byte(`{}`))
require.NoError(t, err)
assert.NotNil(t, out3)
out4, err := DescribeIdentityProviderConfig(context.Background(), nc, acct, "alpha", nil)
require.NoError(t, err)
assert.NotNil(t, out4)
out5, err := ListIdentityProviderConfigs(context.Background(), nc, acct, "alpha")
require.NoError(t, err)
assert.NotNil(t, out5)
out6, err := DisassociateIdentityProviderConfig(context.Background(), nc, acct, "alpha", []byte(`{}`))
require.NoError(t, err)
assert.NotNil(t, out6)
out7, err := DisassociateIdentityProviderConfig(context.Background(), nc, acct, "alpha", nil)
require.NoError(t, err)
assert.NotNil(t, out7)
}
func TestGatewayWrappers_OIDC_BadJSON(t *testing.T) {
_, nc := testutil.StartTestNATS(t)
stubEKSResponder(t, nc)
_, err := AssociateIdentityProviderConfig(context.Background(), nc, acct, "alpha", []byte(`{x`))
require.Error(t, err)
_, err = DescribeIdentityProviderConfig(context.Background(), nc, acct, "alpha", []byte(`{x`))
require.Error(t, err)
_, err = DisassociateIdentityProviderConfig(context.Background(), nc, acct, "alpha", []byte(`{x`))
require.Error(t, err)
}
func TestGatewayWrappers_Tags(t *testing.T) {
_, nc := testutil.StartTestNATS(t)
stubEKSResponder(t, nc)
+30 -72
View File
@@ -24,16 +24,11 @@ func TestLookupEKSAction_ResolvesKnownRoutes(t *testing.T) {
{"GET", "/clusters", "ListClusters", nil},
{"GET", "/clusters/alpha", "DescribeCluster", []string{"alpha"}},
{"DELETE", "/clusters/alpha", "DeleteCluster", []string{"alpha"}},
{"POST", "/clusters/alpha/update-config", "UpdateClusterConfig", []string{"alpha"}},
{"POST", "/clusters/alpha/updates", "UpdateClusterVersion", []string{"alpha"}},
{"GET", "/clusters/alpha/updates", "ListUpdates", []string{"alpha"}},
{"GET", "/clusters/alpha/updates/upd1", "DescribeUpdate", []string{"alpha", "upd1"}},
{"POST", "/clusters/alpha/node-groups", "CreateNodegroup", []string{"alpha"}},
{"GET", "/clusters/alpha/node-groups", "ListNodegroups", []string{"alpha"}},
{"GET", "/clusters/alpha/node-groups/ng1", "DescribeNodegroup", []string{"alpha", "ng1"}},
{"DELETE", "/clusters/alpha/node-groups/ng1", "DeleteNodegroup", []string{"alpha", "ng1"}},
{"POST", "/clusters/alpha/node-groups/ng1/update-config", "UpdateNodegroupConfig", []string{"alpha", "ng1"}},
{"POST", "/clusters/alpha/node-groups/ng1/update-version", "UpdateNodegroupVersion", []string{"alpha", "ng1"}},
{"POST", "/clusters/alpha/access-entries", "CreateAccessEntry", []string{"alpha"}},
{"GET", "/clusters/alpha/access-entries", "ListAccessEntries", []string{"alpha"}},
{"GET", "/clusters/alpha/access-entries/arn-user", "DescribeAccessEntry", []string{"alpha", "arn-user"}},
@@ -49,10 +44,6 @@ func TestLookupEKSAction_ResolvesKnownRoutes(t *testing.T) {
{"GET", "/clusters/alpha/addons/vpc-cni", "DescribeAddon", []string{"alpha", "vpc-cni"}},
{"DELETE", "/clusters/alpha/addons/vpc-cni", "DeleteAddon", []string{"alpha", "vpc-cni"}},
{"POST", "/clusters/alpha/addons/vpc-cni/update", "UpdateAddon", []string{"alpha", "vpc-cni"}},
{"POST", "/clusters/alpha/identity-provider-configs/associate", "AssociateIdentityProviderConfig", []string{"alpha"}},
{"POST", "/clusters/alpha/identity-provider-configs/describe", "DescribeIdentityProviderConfig", []string{"alpha"}},
{"POST", "/clusters/alpha/identity-provider-configs/disassociate", "DisassociateIdentityProviderConfig", []string{"alpha"}},
{"GET", "/clusters/alpha/identity-provider-configs", "ListIdentityProviderConfigs", []string{"alpha"}},
{"POST", "/tags/arn-cluster", "TagResource", []string{"arn-cluster"}},
{"DELETE", "/tags/arn-cluster", "UntagResource", []string{"arn-cluster"}},
{"GET", "/tags/arn-cluster", "ListTagsForResource", []string{"arn-cluster"}},
@@ -118,45 +109,36 @@ func TestLookupEKSAction_CoversAllActions(t *testing.T) {
expected := map[string]bool{
"CreateCluster": false,
// Internal control-plane broker routes, not AWS-SDK EKS actions.
"PublishInternal": false,
"WebhookTokenReview": false,
"ListInternalAddons": false,
"GetRecoveryDirective": false,
"DescribeCluster": false,
"ListClusters": false,
"UpdateClusterConfig": false,
"UpdateClusterVersion": false,
"ListUpdates": false,
"DescribeUpdate": false,
"DeleteCluster": false,
"CreateNodegroup": false,
"DescribeNodegroup": false,
"ListNodegroups": false,
"UpdateNodegroupConfig": false,
"UpdateNodegroupVersion": false,
"DeleteNodegroup": false,
"CreateAccessEntry": false,
"DescribeAccessEntry": false,
"ListAccessEntries": false,
"UpdateAccessEntry": false,
"DeleteAccessEntry": false,
"AssociateAccessPolicy": false,
"DisassociateAccessPolicy": false,
"ListAssociatedAccessPolicies": false,
"ListAccessPolicies": false,
"ListAddons": false,
"DescribeAddonVersions": false,
"CreateAddon": false,
"DeleteAddon": false,
"DescribeAddon": false,
"UpdateAddon": false,
"AssociateIdentityProviderConfig": false,
"DescribeIdentityProviderConfig": false,
"ListIdentityProviderConfigs": false,
"DisassociateIdentityProviderConfig": false,
"TagResource": false,
"UntagResource": false,
"ListTagsForResource": false,
"PublishInternal": false,
"WebhookTokenReview": false,
"ListInternalAddons": false,
"GetRecoveryDirective": false,
"DescribeCluster": false,
"ListClusters": false,
"DeleteCluster": false,
"CreateNodegroup": false,
"DescribeNodegroup": false,
"ListNodegroups": false,
"UpdateNodegroupConfig": false,
"DeleteNodegroup": false,
"CreateAccessEntry": false,
"DescribeAccessEntry": false,
"ListAccessEntries": false,
"UpdateAccessEntry": false,
"DeleteAccessEntry": false,
"AssociateAccessPolicy": false,
"DisassociateAccessPolicy": false,
"ListAssociatedAccessPolicies": false,
"ListAccessPolicies": false,
"ListAddons": false,
"DescribeAddonVersions": false,
"CreateAddon": false,
"DeleteAddon": false,
"DescribeAddon": false,
"UpdateAddon": false,
"TagResource": false,
"UntagResource": false,
"ListTagsForResource": false,
}
for _, route := range eksRoutes {
if _, ok := expected[route.action]; ok {
@@ -230,27 +212,3 @@ type awsCodeError struct{ code string }
func (e *awsCodeError) Error() string { return e.code }
func errAWS(code string) error { return &awsCodeError{code: code} }
// The update surface is absent, and the honest answer for an action that exists
// and is not served is NotImplemented. Unregistered, these two answered
// InvalidAction, which tells the caller they typed something that does not exist.
func TestLookupEKSAction_UpdateReadsRefuseAsNotImplemented(t *testing.T) {
for _, path := range []string{"/clusters/alpha/updates", "/clusters/alpha/updates/upd1"} {
t.Run(path, func(t *testing.T) {
_, params, handler, ok := eksRouter.lookup(http.MethodGet, path)
require.True(t, ok)
out, err := handler(context.Background(), nil, "000000000001", "", params, nil)
assert.Nil(t, out)
require.Error(t, err)
assert.Equal(t, awserrors.ErrorNotImplemented, err.Error())
})
}
}
// update-version is the nodegroup pattern. The cluster action has never been
// reachable at it on AWS, so keeping it registered would serve a path no caller
// sends and hide the one they do.
func TestLookupEKSAction_ClusterUpdateVersionIsNotAtTheNodegroupPath(t *testing.T) {
_, _, _, ok := eksRouter.lookup(http.MethodPost, "/clusters/alpha/update-version")
assert.False(t, ok)
}
-9
View File
@@ -1117,15 +1117,6 @@ func (s *EKSServiceImpl) casPutNodegroup(ctx context.Context, kv jetstream.KeyVa
return true, nil
}
func (s *EKSServiceImpl) updateNodegroupVersion(input *eks.UpdateNodegroupVersionInput) (*eks.UpdateNodegroupVersionOutput, error) {
// Worker AMI version upgrades (drain + replace) are not implemented in v1.
if input != nil {
slog.Info("UpdateNodegroupVersion not implemented in v1",
"cluster", aws.StringValue(input.ClusterName), "nodegroup", aws.StringValue(input.NodegroupName))
}
return nil, notImpl()
}
func (s *EKSServiceImpl) deleteNodegroup(ctx context.Context, acctKV jetstream.KeyValue, input *eks.DeleteNodegroupInput, accountID string) (*eks.DeleteNodegroupOutput, error) {
if input == nil {
return nil, errors.New(awserrors.ErrorInvalidParameterValue)
-9
View File
@@ -924,15 +924,6 @@ func TestDeleteNodegroup_TerminatesAndIsIdempotent(t *testing.T) {
require.EqualError(t, err, awserrors.ErrorEKSResourceNotFound)
}
func TestUpdateNodegroupVersion_NotImplemented(t *testing.T) {
t.Parallel()
f := newEKSServiceFixture(t)
_, err := f.svc.UpdateNodegroupVersion(context.Background(), &eks.UpdateNodegroupVersionInput{
ClusterName: aws.String("c1"), NodegroupName: aws.String("ng1"),
}, testAccountID)
require.EqualError(t, err, awserrors.ErrorNotImplemented)
}
// TestSelectWorkerHost_NoSchedulerOrCapacity returns "" so the caller falls back
// to a local launch when no scheduler is wired or no host has free capacity.
func TestSelectWorkerHost_NoSchedulerOrCapacity(t *testing.T) {
-9
View File
@@ -13,8 +13,6 @@ type EKSService interface {
CreateCluster(ctx context.Context, input *eks.CreateClusterInput, accountID, callerPrincipalARN string) (*eks.CreateClusterOutput, error)
DescribeCluster(ctx context.Context, input *eks.DescribeClusterInput, accountID string) (*eks.DescribeClusterOutput, error)
ListClusters(ctx context.Context, input *eks.ListClustersInput, accountID string) (*eks.ListClustersOutput, error)
UpdateClusterConfig(ctx context.Context, input *eks.UpdateClusterConfigInput, accountID string) (*eks.UpdateClusterConfigOutput, error)
UpdateClusterVersion(ctx context.Context, input *eks.UpdateClusterVersionInput, accountID string) (*eks.UpdateClusterVersionOutput, error)
DeleteCluster(ctx context.Context, input *eks.DeleteClusterInput, accountID string) (*eks.DeleteClusterOutput, error)
// Nodegroup
@@ -22,7 +20,6 @@ type EKSService interface {
DescribeNodegroup(ctx context.Context, input *eks.DescribeNodegroupInput, accountID string) (*eks.DescribeNodegroupOutput, error)
ListNodegroups(ctx context.Context, input *eks.ListNodegroupsInput, accountID string) (*eks.ListNodegroupsOutput, error)
UpdateNodegroupConfig(ctx context.Context, input *eks.UpdateNodegroupConfigInput, accountID string) (*eks.UpdateNodegroupConfigOutput, error)
UpdateNodegroupVersion(ctx context.Context, input *eks.UpdateNodegroupVersionInput, accountID string) (*eks.UpdateNodegroupVersionOutput, error)
DeleteNodegroup(ctx context.Context, input *eks.DeleteNodegroupInput, accountID string) (*eks.DeleteNodegroupOutput, error)
// AccessEntry + AccessPolicy
@@ -60,12 +57,6 @@ type EKSService interface {
// and NLB re-point.
RestoreSnapshot(ctx context.Context, input *RestoreSnapshotInput, accountID string) (*RestoreSnapshotOutput, error)
// OIDC identity-provider configs.
AssociateIdentityProviderConfig(ctx context.Context, input *eks.AssociateIdentityProviderConfigInput, accountID string) (*eks.AssociateIdentityProviderConfigOutput, error)
DescribeIdentityProviderConfig(ctx context.Context, input *eks.DescribeIdentityProviderConfigInput, accountID string) (*eks.DescribeIdentityProviderConfigOutput, error)
ListIdentityProviderConfigs(ctx context.Context, input *eks.ListIdentityProviderConfigsInput, accountID string) (*eks.ListIdentityProviderConfigsOutput, error)
DisassociateIdentityProviderConfig(ctx context.Context, input *eks.DisassociateIdentityProviderConfigInput, accountID string) (*eks.DisassociateIdentityProviderConfigOutput, error)
// Tags
TagResource(ctx context.Context, input *eks.TagResourceInput, accountID string) (*eks.TagResourceOutput, error)
UntagResource(ctx context.Context, input *eks.UntagResourceInput, accountID string) (*eks.UntagResourceOutput, error)
-30
View File
@@ -1452,14 +1452,6 @@ func (s *EKSServiceImpl) purgeClusterInfra(ctx context.Context, accountID, name
return nil
}
func (s *EKSServiceImpl) UpdateClusterConfig(ctx context.Context, _ *eks.UpdateClusterConfigInput, _ string) (*eks.UpdateClusterConfigOutput, error) {
return nil, notImpl()
}
func (s *EKSServiceImpl) UpdateClusterVersion(ctx context.Context, _ *eks.UpdateClusterVersionInput, _ string) (*eks.UpdateClusterVersionOutput, error) {
return nil, notImpl()
}
// --- Nodegroup ---
func (s *EKSServiceImpl) CreateNodegroup(ctx context.Context, input *eks.CreateNodegroupInput, accountID string) (*eks.CreateNodegroupOutput, error) {
@@ -1506,10 +1498,6 @@ func (s *EKSServiceImpl) UpdateNodegroupConfig(ctx context.Context, input *eks.U
return s.updateNodegroupConfig(ctx, acctKV, input, accountID)
}
func (s *EKSServiceImpl) UpdateNodegroupVersion(ctx context.Context, input *eks.UpdateNodegroupVersionInput, accountID string) (*eks.UpdateNodegroupVersionOutput, error) {
return s.updateNodegroupVersion(input)
}
func (s *EKSServiceImpl) DeleteNodegroup(ctx context.Context, input *eks.DeleteNodegroupInput, accountID string) (*eks.DeleteNodegroupOutput, error) {
if err := s.requireOrchestrationDeps("DeleteNodegroup"); err != nil {
return nil, err
@@ -1813,24 +1801,6 @@ func accessPolicyName(arn string) string {
// --- Addons (see addons.go) ---
// --- OIDC identity-provider configs ---
func (s *EKSServiceImpl) AssociateIdentityProviderConfig(ctx context.Context, _ *eks.AssociateIdentityProviderConfigInput, _ string) (*eks.AssociateIdentityProviderConfigOutput, error) {
return nil, notImpl()
}
func (s *EKSServiceImpl) DescribeIdentityProviderConfig(ctx context.Context, _ *eks.DescribeIdentityProviderConfigInput, _ string) (*eks.DescribeIdentityProviderConfigOutput, error) {
return nil, notImpl()
}
func (s *EKSServiceImpl) ListIdentityProviderConfigs(ctx context.Context, _ *eks.ListIdentityProviderConfigsInput, _ string) (*eks.ListIdentityProviderConfigsOutput, error) {
return nil, notImpl()
}
func (s *EKSServiceImpl) DisassociateIdentityProviderConfig(ctx context.Context, _ *eks.DisassociateIdentityProviderConfigInput, _ string) (*eks.DisassociateIdentityProviderConfigOutput, error) {
return nil, notImpl()
}
// --- Tags ---
//
// Store-only against the cluster meta record or nodegroup record (no
+2 -30
View File
@@ -29,8 +29,7 @@ func setupTestService(t *testing.T) *EKSServiceImpl {
// are absent so CreateCluster/DeleteCluster short-circuit to ServiceUnavailable
// (the missing deps are logged at ERROR), DescribeCluster hits an empty
// per-account bucket and surfaces ResourceNotFoundException, and ListClusters
// returns an empty list. The UpdateClusterConfig + UpdateClusterVersion paths
// stay NotImplemented.
// returns an empty list.
func TestEKSServiceImpl_ClusterLifecycleShimMode(t *testing.T) {
t.Parallel()
svc := setupTestService(t)
@@ -46,12 +45,6 @@ func TestEKSServiceImpl_ClusterLifecycleShimMode(t *testing.T) {
require.NotNil(t, out)
require.Empty(t, out.Clusters)
_, err = svc.UpdateClusterConfig(context.Background(), &eks.UpdateClusterConfigInput{Name: aws.String("c1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorNotImplemented)
_, err = svc.UpdateClusterVersion(context.Background(), &eks.UpdateClusterVersionInput{Name: aws.String("c1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorNotImplemented)
_, err = svc.DeleteCluster(context.Background(), &eks.DeleteClusterInput{Name: aws.String("c1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorServiceUnavailable)
}
@@ -206,8 +199,7 @@ func TestDeleteCluster_ZeroizesOIDCKeyBeforeTeardown(t *testing.T) {
// In shim mode (orchestration deps absent) the mutating nodegroup methods
// short-circuit to ServiceUnavailable, the read methods reach an empty
// per-account bucket and surface ResourceNotFoundException, and
// UpdateNodegroupVersion stays NotImplemented (v1 doesn't do AMI upgrades).
// per-account bucket and surface ResourceNotFoundException.
func TestEKSServiceImpl_NodegroupMethodsShimMode(t *testing.T) {
t.Parallel()
svc := setupTestService(t)
@@ -224,9 +216,6 @@ func TestEKSServiceImpl_NodegroupMethodsShimMode(t *testing.T) {
_, err = svc.UpdateNodegroupConfig(context.Background(), &eks.UpdateNodegroupConfigInput{ClusterName: aws.String("c1"), NodegroupName: aws.String("ng1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorServiceUnavailable)
_, err = svc.UpdateNodegroupVersion(context.Background(), &eks.UpdateNodegroupVersionInput{ClusterName: aws.String("c1"), NodegroupName: aws.String("ng1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorNotImplemented)
_, err = svc.DeleteNodegroup(context.Background(), &eks.DeleteNodegroupInput{ClusterName: aws.String("c1"), NodegroupName: aws.String("ng1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorServiceUnavailable)
}
@@ -464,23 +453,6 @@ func TestListAccessPolicies_ReturnsSupportedCatalogue(t *testing.T) {
}
}
func TestEKSServiceImpl_OIDCMethodsReturnNotImplemented(t *testing.T) {
t.Parallel()
svc := setupTestService(t)
_, err := svc.AssociateIdentityProviderConfig(context.Background(), &eks.AssociateIdentityProviderConfigInput{ClusterName: aws.String("c1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorNotImplemented)
_, err = svc.DescribeIdentityProviderConfig(context.Background(), &eks.DescribeIdentityProviderConfigInput{ClusterName: aws.String("c1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorNotImplemented)
_, err = svc.ListIdentityProviderConfigs(context.Background(), &eks.ListIdentityProviderConfigsInput{ClusterName: aws.String("c1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorNotImplemented)
_, err = svc.DisassociateIdentityProviderConfig(context.Background(), &eks.DisassociateIdentityProviderConfigInput{ClusterName: aws.String("c1")}, testAccountID)
require.EqualError(t, err, awserrors.ErrorNotImplemented)
}
func TestEKSServiceImpl_ClusterTagRoundTrip(t *testing.T) {
t.Parallel()
svc := setupTestService(t)
-30
View File
@@ -39,14 +39,6 @@ func (s *NATSEKSService) ListClusters(ctx context.Context, input *eks.ListCluste
return utils.NATSRequest[eks.ListClustersOutput](ctx, s.natsConn, "eks.ListClusters", input, defaultTimeout, accountID)
}
func (s *NATSEKSService) UpdateClusterConfig(ctx context.Context, input *eks.UpdateClusterConfigInput, accountID string) (*eks.UpdateClusterConfigOutput, error) {
return utils.NATSRequest[eks.UpdateClusterConfigOutput](ctx, s.natsConn, "eks.UpdateClusterConfig", input, defaultTimeout, accountID)
}
func (s *NATSEKSService) UpdateClusterVersion(ctx context.Context, input *eks.UpdateClusterVersionInput, accountID string) (*eks.UpdateClusterVersionOutput, error) {
return utils.NATSRequest[eks.UpdateClusterVersionOutput](ctx, s.natsConn, "eks.UpdateClusterVersion", input, defaultTimeout, accountID)
}
func (s *NATSEKSService) DeleteCluster(ctx context.Context, input *eks.DeleteClusterInput, accountID string) (*eks.DeleteClusterOutput, error) {
return utils.NATSRequest[eks.DeleteClusterOutput](ctx, s.natsConn, "eks.DeleteCluster", input, defaultTimeout, accountID)
}
@@ -69,10 +61,6 @@ func (s *NATSEKSService) UpdateNodegroupConfig(ctx context.Context, input *eks.U
return utils.NATSRequest[eks.UpdateNodegroupConfigOutput](ctx, s.natsConn, "eks.UpdateNodegroupConfig", input, defaultTimeout, accountID)
}
func (s *NATSEKSService) UpdateNodegroupVersion(ctx context.Context, input *eks.UpdateNodegroupVersionInput, accountID string) (*eks.UpdateNodegroupVersionOutput, error) {
return utils.NATSRequest[eks.UpdateNodegroupVersionOutput](ctx, s.natsConn, "eks.UpdateNodegroupVersion", input, defaultTimeout, accountID)
}
func (s *NATSEKSService) DeleteNodegroup(ctx context.Context, input *eks.DeleteNodegroupInput, accountID string) (*eks.DeleteNodegroupOutput, error) {
return utils.NATSRequest[eks.DeleteNodegroupOutput](ctx, s.natsConn, "eks.DeleteNodegroup", input, defaultTimeout, accountID)
}
@@ -157,24 +145,6 @@ func (s *NATSEKSService) RestoreSnapshot(ctx context.Context, input *RestoreSnap
return utils.NATSRequest[RestoreSnapshotOutput](ctx, s.natsConn, "eks.RestoreSnapshot", input, defaultTimeout, accountID)
}
// --- OIDC identity-provider configs ---
func (s *NATSEKSService) AssociateIdentityProviderConfig(ctx context.Context, input *eks.AssociateIdentityProviderConfigInput, accountID string) (*eks.AssociateIdentityProviderConfigOutput, error) {
return utils.NATSRequest[eks.AssociateIdentityProviderConfigOutput](ctx, s.natsConn, "eks.AssociateIdentityProviderConfig", input, defaultTimeout, accountID)
}
func (s *NATSEKSService) DescribeIdentityProviderConfig(ctx context.Context, input *eks.DescribeIdentityProviderConfigInput, accountID string) (*eks.DescribeIdentityProviderConfigOutput, error) {
return utils.NATSRequest[eks.DescribeIdentityProviderConfigOutput](ctx, s.natsConn, "eks.DescribeIdentityProviderConfig", input, defaultTimeout, accountID)
}
func (s *NATSEKSService) ListIdentityProviderConfigs(ctx context.Context, input *eks.ListIdentityProviderConfigsInput, accountID string) (*eks.ListIdentityProviderConfigsOutput, error) {
return utils.NATSRequest[eks.ListIdentityProviderConfigsOutput](ctx, s.natsConn, "eks.ListIdentityProviderConfigs", input, defaultTimeout, accountID)
}
func (s *NATSEKSService) DisassociateIdentityProviderConfig(ctx context.Context, input *eks.DisassociateIdentityProviderConfigInput, accountID string) (*eks.DisassociateIdentityProviderConfigOutput, error) {
return utils.NATSRequest[eks.DisassociateIdentityProviderConfigOutput](ctx, s.natsConn, "eks.DisassociateIdentityProviderConfig", input, defaultTimeout, accountID)
}
// --- Tags ---
func (s *NATSEKSService) TagResource(ctx context.Context, input *eks.TagResourceInput, accountID string) (*eks.TagResourceOutput, error) {
@@ -20,7 +20,6 @@ import {
useDeleteNodegroup,
useScaleNodegroup,
useUpdateAddon,
useUpdateNodegroupVersion,
} from "./eks"
let queryClient: QueryClient
@@ -187,30 +186,6 @@ describe("eks mutations", () => {
})
})
describe("useUpdateNodegroupVersion", () => {
it("sends UpdateNodegroupVersionCommand with target version", async () => {
createQueryClient()
const { result } = renderHook(() => useUpdateNodegroupVersion(), {
wrapper,
})
result.current.mutate({
clusterName: "c1",
nodegroupName: "ng1",
version: "1.32",
})
await waitFor(() => {
expect(result.current.isSuccess).toBeTruthy()
})
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
clusterName: "c1",
nodegroupName: "ng1",
version: "1.32",
})
})
})
describe("useDeleteNodegroup", () => {
it("sends DeleteNodegroupCommand", async () => {
createQueryClient()
@@ -11,7 +11,6 @@ import {
DisassociateAccessPolicyCommand,
UpdateAddonCommand,
UpdateNodegroupConfigCommand,
UpdateNodegroupVersionCommand,
} from "@aws-sdk/client-eks"
import { useMutation, useQueryClient } from "@tanstack/react-query"
@@ -124,29 +123,6 @@ export function useScaleNodegroup() {
})
}
export function useUpdateNodegroupVersion() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async (params: {
clusterName: string
nodegroupName: string
version?: string
}) => {
const command = new UpdateNodegroupVersionCommand({
clusterName: params.clusterName,
nodegroupName: params.nodegroupName,
version: params.version,
})
return await getEksClient().send(command)
},
onSuccess: (_data, params) => {
void queryClient.invalidateQueries({
queryKey: ["eks", "clusters", params.clusterName, "nodegroups"],
})
},
})
}
export function useDeleteNodegroup() {
const queryClient = useQueryClient()
return useMutation({
@@ -142,7 +142,7 @@ describe("NodegroupsTab", () => {
).toBeInTheDocument()
})
it("surfaces an upgrade affordance when the node group lags the cluster", () => {
it("shows the version lag without an upgrade action when the node group lags the cluster", () => {
renderWithClient(
<NodegroupsTab
clusterName={CLUSTER}
@@ -151,10 +151,10 @@ describe("NodegroupsTab", () => {
/>,
seed({ nodegroupVersion: "1.29" }),
)
expect(
screen.getByRole("button", { name: "Update node group version" }),
).toBeInTheDocument()
expect(screen.getByText("1.29 (cluster on 1.30)")).toBeInTheDocument()
expect(
screen.queryByRole("button", { name: "Update node group version" }),
).not.toBeInTheDocument()
})
it("opens the delete confirmation for a node group", () => {
@@ -1,7 +1,7 @@
import type { InstanceTypeInfo } from "@aws-sdk/client-ec2"
import { zodResolver } from "@hookform/resolvers/zod"
import { useQuery, useSuspenseQuery } from "@tanstack/react-query"
import { ArrowUpCircle, SlidersHorizontal, Trash2 } from "lucide-react"
import { SlidersHorizontal, Trash2 } from "lucide-react"
import { useState } from "react"
import { Controller, useForm, useWatch } from "react-hook-form"
@@ -34,7 +34,6 @@ import {
useCreateNodegroup,
useDeleteNodegroup,
useScaleNodegroup,
useUpdateNodegroupVersion,
} from "@/mutations/eks"
import {
ec2InstanceTypesQueryOptions,
@@ -198,11 +197,9 @@ function NodegroupRow({
const { data } = useQuery(
eksNodegroupQueryOptions(clusterName, nodegroupName),
)
const updateVersion = useUpdateNodegroupVersion()
const ng = data?.nodegroup
const scaling = ng?.scalingConfig
const [showScale, setShowScale] = useState(false)
const [showUpdate, setShowUpdate] = useState(false)
const updateAvailable =
!!clusterVersion && !!ng?.version && ng.version !== clusterVersion
@@ -217,18 +214,6 @@ function NodegroupRow({
{isGpu && <Badge variant="secondary">GPU</Badge>}
</div>
<div className="flex items-center gap-1">
{updateAvailable && (
<Button
aria-label="Update node group version"
onClick={() => {
setShowUpdate(true)
}}
size="icon"
variant="ghost"
>
<ArrowUpCircle className="size-4" />
</Button>
)}
<Button
aria-label="Scale node group"
onClick={() => {
@@ -285,25 +270,6 @@ function NodegroupRow({
onOpenChange={setShowScale}
open={showScale}
/>
<DeleteConfirmationDialog
confirmLabel="Update"
description={`Update node group "${nodegroupName}" from ${ng?.version} to ${clusterVersion}? Nodes are replaced in a rolling update.`}
isPending={updateVersion.isPending}
onConfirm={() => {
updateVersion.mutate(
{ clusterName, nodegroupName, version: clusterVersion },
{
onSuccess: () => {
setShowUpdate(false)
},
},
)
}}
onOpenChange={setShowUpdate}
open={showUpdate}
title="Update node group version"
/>
</DetailCard>
)
}
+6 -8
View File
@@ -428,15 +428,13 @@ func eksUncased() map[string]string {
"UntagResource": sameHelper("ListTagsForResource"),
}
for _, action := range []string{
"AssociateAccessPolicy", "AssociateIdentityProviderConfig", "CreateAccessEntry", "CreateAddon",
"CreateCluster", "CreateNodegroup", "DeleteAccessEntry", "DeleteAddon", "DeleteCluster",
"DeleteNodegroup", "DescribeAccessEntry", "DescribeAddon", "DescribeAddonVersions",
"DescribeCluster", "DescribeIdentityProviderConfig", "DescribeNodegroup", "DescribeUpdate",
"DisassociateAccessPolicy", "DisassociateIdentityProviderConfig", "GetRecoveryDirective",
"AssociateAccessPolicy", "CreateAccessEntry", "CreateAddon", "CreateCluster",
"CreateNodegroup", "DeleteAccessEntry", "DeleteAddon", "DeleteCluster", "DeleteNodegroup",
"DescribeAccessEntry", "DescribeAddon", "DescribeAddonVersions", "DescribeCluster",
"DescribeNodegroup", "DisassociateAccessPolicy", "GetRecoveryDirective",
"ListAccessEntries", "ListAccessPolicies", "ListAddons", "ListAssociatedAccessPolicies",
"ListClusters", "ListIdentityProviderConfigs", "ListInternalAddons", "ListNodegroups",
"ListUpdates", "PublishInternal", "UpdateAccessEntry", "UpdateAddon", "UpdateClusterConfig",
"UpdateClusterVersion", "UpdateNodegroupConfig", "UpdateNodegroupVersion", "WebhookTokenReview",
"ListClusters", "ListInternalAddons", "ListNodegroups", "PublishInternal",
"UpdateAccessEntry", "UpdateAddon", "UpdateNodegroupConfig", "WebhookTokenReview",
} {
uncased[action] = byName
}