Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions apis/v1alpha1/ack-generate-metadata.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
ack_generate_info:
build_date: "2026-02-19T00:10:17Z"
build_hash: af61bc1478baf08196fb6e2c81590518a754e45e
build_date: "2026-02-24T04:42:15Z"
build_hash: b0103744b8b2c48e9f8938ff6c2bf3b95ad95406
go_version: go1.25.6
version: v0.57.0-9-gaf61bc1
version: v0.57.0-14-gb010374
api_directory_checksum: df9ec56e987fdc93ed2e7f55c55cf0bc3372b109
api_version: v1alpha1
aws_sdk_go_version: v1.40.1
generator_config_info:
file_checksum: a0b97e79bcd3136d63cafd2a8b98e4b6b5a52c15
file_checksum: 01b155972bea16ddf80b42849a78ca34f00f52eb
original_file_name: generator.yaml
last_modification:
reason: API generation
5 changes: 4 additions & 1 deletion apis/v1alpha1/generator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ resources:
BootstrapSelfManagedAddons:
compare:
is_ignored: true
Logging:
compare:
is_ignored: true
exceptions:
errors:
404:
Expand All @@ -197,7 +200,7 @@ resources:
- ValidationError
hooks:
delta_pre_compare:
code: customPreCompare(a, b)
code: customPreCompare(delta, a, b)
sdk_create_post_set_output:
template_path: hooks/cluster/sdk_create_post_set_output.go.tpl
sdk_read_one_post_set_output:
Expand Down
5 changes: 4 additions & 1 deletion generator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ resources:
BootstrapSelfManagedAddons:
compare:
is_ignored: true
Logging:
compare:
is_ignored: true
exceptions:
errors:
404:
Expand All @@ -197,7 +200,7 @@ resources:
- ValidationError
hooks:
delta_pre_compare:
code: customPreCompare(a, b)
code: customPreCompare(delta, a, b)
sdk_create_post_set_output:
template_path: hooks/cluster/sdk_create_post_set_output.go.tpl
sdk_read_one_post_set_output:
Expand Down
13 changes: 1 addition & 12 deletions pkg/resource/cluster/delta.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

103 changes: 93 additions & 10 deletions pkg/resource/cluster/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ import (
"github.com/aws-controllers-k8s/eks-controller/pkg/util"
)

const (
LoggingNoChangesError = "No changes needed for the logging config provided"
)

// Taken from the list of cluster statuses on the boto3 documentation
// https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/eks.html#EKS.Client.describe_cluster
const (
Expand Down Expand Up @@ -185,12 +181,38 @@ func (rm *resourceManager) clusterInUse(ctx context.Context, r *resource) (bool,
}

func customPreCompare(
delta *ackcompare.Delta,
a *resource,
b *resource,
) {
if a.ko.Spec.UpgradePolicy == nil && b.ko.Spec.UpgradePolicy != nil {
a.ko.Spec.UpgradePolicy = b.ko.Spec.UpgradePolicy.DeepCopy()
}
// Custom logging comparison. The EKS API always returns both enabled and
// disabled log type entries, but users may only specify enabled ones. A
// missing enabled list means everything is disabled. We compare the
// effective set of enabled log types to avoid false positives.
desiredEnabled := enabledLogTypes(a)
latestEnabled := enabledLogTypes(b)
if !ackcompare.SliceStringPEqual(desiredEnabled, latestEnabled) {
delta.Add("Spec.Logging", a.ko.Spec.Logging, b.ko.Spec.Logging)
}
}

// enabledLogTypes returns the list of log type strings that are enabled in the
// resource's logging config. A nil logging config or missing entries means
// nothing is enabled.
func enabledLogTypes(r *resource) []*string {
var enabled []*string
if r.ko.Spec.Logging == nil {
return enabled
}
for _, ls := range r.ko.Spec.Logging.ClusterLogging {
if ls.Enabled != nil && *ls.Enabled {
enabled = append(enabled, ls.Types...)
}
}
return enabled
}

func (rm *resourceManager) customUpdate(
Expand Down Expand Up @@ -249,15 +271,12 @@ func (rm *resourceManager) customUpdate(
if err := rm.updateConfigLogging(ctx, desired); err != nil {
awsErr, ok := extractAWSError(err)

// The API responds with an error if there were no changes applied
if !ok || awsErr.Message != LoggingNoChangesError {
return nil, err
}

// Check to see if we've raced an async update call and need to requeue
if ok && awsErr.Code == "ResourceInUseException" {
return nil, requeueAfterAsyncUpdate()
}

return nil, err
}
return returnClusterUpdating(updatedRes)
}
Expand Down Expand Up @@ -472,6 +491,15 @@ func (rm *resourceManager) updateVersion(
return nil
}

// allEKSLogTypes is the complete set of EKS control plane log types.
var allEKSLogTypes = []svcsdktypes.LogType{
svcsdktypes.LogTypeApi,
svcsdktypes.LogTypeAudit,
svcsdktypes.LogTypeAuthenticator,
svcsdktypes.LogTypeControllerManager,
svcsdktypes.LogTypeScheduler,
}

func (rm *resourceManager) updateConfigLogging(
ctx context.Context,
r *resource,
Expand All @@ -481,7 +509,7 @@ func (rm *resourceManager) updateConfigLogging(
defer exit(err)
input := &svcsdk.UpdateClusterConfigInput{
Name: r.ko.Spec.Name,
Logging: rm.newLogging(r),
Logging: newFullLogging(r),
}

_, err = rm.sdkapi.UpdateClusterConfig(ctx, input)
Expand All @@ -493,6 +521,61 @@ func (rm *resourceManager) updateConfigLogging(
return nil
}

// newFullLogging builds a complete EKS logging config with all log types
// explicitly set to enabled or disabled. The EKS API expects the full config;
// sending only enabled types causes "No changes needed" errors when the
// effective state hasn't changed.
//
// All user-specified enabled types are passed through to the API (including
// unknown ones, so that EKS can validate and reject them). The disabled set
// is built from the known EKS log types minus whatever the user enabled.
func newFullLogging(r *resource) *svcsdktypes.Logging {
// Collect the set of log types the user wants enabled.
enabled := make(map[svcsdktypes.LogType]bool)
var enabledTypes []svcsdktypes.LogType
if r.ko.Spec.Logging != nil {
for _, ls := range r.ko.Spec.Logging.ClusterLogging {
if ls.Enabled != nil && *ls.Enabled {
for _, t := range ls.Types {
if t != nil {
lt := svcsdktypes.LogType(*t)
if !enabled[lt] {
enabled[lt] = true
enabledTypes = append(enabledTypes, lt)
}
}
}
}
}
}

// Disabled types: known EKS log types that the user did not enable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about logs the user explicitly disabled? If EKS add a new LogType that isn't listed here this will prevent the user from disabling it if it ever became enabled.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using a hardcoded list could we use the values from latest to get the most recent list of LogTypes? The full set of log types to disable would be (latest disabled - user enable + user disabled).

var disabledTypes []svcsdktypes.LogType
for _, lt := range allEKSLogTypes {
if !enabled[lt] {
disabledTypes = append(disabledTypes, lt)
}
}

var clusterLogging []svcsdktypes.LogSetup
if len(enabledTypes) > 0 {
clusterLogging = append(clusterLogging, svcsdktypes.LogSetup{
Enabled: aws.Bool(true),
Types: enabledTypes,
})
}
if len(disabledTypes) > 0 {
clusterLogging = append(clusterLogging, svcsdktypes.LogSetup{
Enabled: aws.Bool(false),
Types: disabledTypes,
})
}

return &svcsdktypes.Logging{
ClusterLogging: clusterLogging,
}
}

func newAccessConfig(r *resource) *svcsdktypes.UpdateAccessConfigRequest {
cfg := &svcsdktypes.UpdateAccessConfigRequest{}
if r.ko.Spec.AccessConfig != nil {
Expand Down
31 changes: 0 additions & 31 deletions pkg/resource/cluster/sdk.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion templates/hooks/cluster/sdk_file_end.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{{/* Find the structure field within the operation */}}
{{- range $fieldName, $field := $CRD.SpecFields -}}
{{- if (or (eq $field.Path "Logging") (eq $field.Path "ResourcesVPCConfig")) }}
{{- if (eq $field.Path "ResourcesVPCConfig") }}

{{- $shapeName := $field.ShapeRef.ShapeName }}

Expand Down
18 changes: 9 additions & 9 deletions test/e2e/tests/test_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,10 @@ def test_create_update_delete_cluster(self, eks_client, simple_cluster):
aws_res = eks_client.describe_cluster(name=cluster_name)
assert sorted(aws_res["cluster"]["resourcesVpcConfig"]["subnetIds"]) == sorted(subnets_ids)

# Update the logging fields
# Update the logging fields specifying only enabled types. The
# controller must handle partial specs correctly — the EKS API
# returns both enabled and disabled entries, but users should not
# be required to list disabled types explicitly.
updates = {
"spec": {
"logging": {
Expand All @@ -242,10 +245,6 @@ def test_create_update_delete_cluster(self, eks_client, simple_cluster):
"enabled": True,
"types": ["api"]
},
{
"enabled": False,
"types": ["audit", "authenticator", "controllerManager", "scheduler"]
},
]
},
}
Expand All @@ -257,10 +256,11 @@ def test_create_update_delete_cluster(self, eks_client, simple_cluster):
wait_for_cluster_active(eks_client, cluster_name)

aws_res = eks_client.describe_cluster(name=cluster_name)
assert len(aws_res["cluster"]["logging"]["clusterLogging"]) > 0
logging = aws_res["cluster"]["logging"]["clusterLogging"][0]
assert logging["enabled"] == True
assert logging["types"] == ["api"]
enabled_types = []
for log_setup in aws_res["cluster"]["logging"]["clusterLogging"]:
if log_setup.get("enabled"):
enabled_types.extend(log_setup["types"])
assert enabled_types == ["api"]

# Update the AccessConfig field
updates = {
Expand Down