Skip to content
Merged
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
9 changes: 6 additions & 3 deletions pkg/config/defaults/resources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,12 @@ resources:
field: extendedSupport
bool_true_fallback: eol
deprecated_window: extended_support
# EKS clusters keep running after extended support, but AWS stops
# patching them. Leave eol_date unset and classify post-extended as
# unsupported rather than true EOL.
# EKS true EOL is the end of extended support. The upstream
# extendedSupport field is now a date; if archived data has the old
# boolean shape, eol_date stays unset rather than treating the end of
# standard support as terminal EOL.
eol_date:
field: extendedSupport
past_extended_support: unsupported

# ElastiCache is split per-engine because each engine has its own
Expand Down
3 changes: 3 additions & 0 deletions pkg/config/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ resources:
extended_support_end:
field: extendedSupport
bool_true_fallback: eol
eol_date:
field: extendedSupport
deprecated_window: extended_support
past_extended_support: unsupported
`
Expand All @@ -127,6 +129,7 @@ resources:
assert.Equal(t, "declarative", cfg.Resources[1].EOL.Schema)
require.NotNil(t, cfg.Resources[1].EOL.Lifecycle)
assert.Equal(t, "eol", cfg.Resources[1].EOL.Lifecycle.DeprecationDate.Field)
assert.Equal(t, "extendedSupport", cfg.Resources[1].EOL.Lifecycle.EOLDate.Field)
}

// TestLoadResourcesConfig_EmbeddedDefault asserts the binary works
Expand Down
14 changes: 9 additions & 5 deletions pkg/eol/endoflife/ADAPTERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ Supported actions:

### EKS

EKS cycle `eol` means end of standard support, not true EOL. Clusters
keep running after extended support, but AWS stops patching them.
EKS cycle `eol` means end of standard support, not true EOL.
`extendedSupport` is the end of paid extended support and the terminal
EOL date used in findings.

```yaml
eol:
Expand All @@ -102,6 +103,8 @@ eol:
extended_support_end:
field: extendedSupport
bool_true_fallback: eol
eol_date:
field: extendedSupport
deprecated_window: extended_support
past_extended_support: unsupported
```
Expand All @@ -111,14 +114,15 @@ For amazon-eks cycle 1.30 (`eol: 2025-07-23`,

| Field | Value | Source / note |
| --- | --- | --- |
| `EOLDate` | `nil` | omitted in YAML |
| `EOLDate` | `2026-07-23` | `cycle.extendedSupport` |
| `DeprecationDate` | `2025-07-23` | `cycle.eol` |
| `ExtendedSupportEnd` | `2026-07-23` | `cycle.extendedSupport` |
| `IsExtendedSupport` | `true` | `deprecated_window: extended_support` |

Policy classifies that as YELLOW. Past `extendedSupport`, the
`past_extended_support: unsupported` action makes it RED without
claiming the cluster has a true EOL date.
`EOLDate` check makes it RED. The `past_extended_support: unsupported`
fallback only matters for archived data where `extendedSupport` was a
boolean and no terminal EOL date is available.

### Lambda

Expand Down
24 changes: 15 additions & 9 deletions pkg/eol/endoflife/adapters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ func eksDeclarativeAdapter(t *testing.T) *DeclarativeSchemaAdapter {
Field: lifecycleFieldExtendedSupport,
BoolTrueFallback: lifecycleFieldEOL,
},
EOLDate: LifecycleDateSource{Field: lifecycleFieldExtendedSupport},
DeprecatedWindow: lifecycleActionExtendedSupport,
PastExtendedSupport: lifecycleActionUnsupported,
})
Expand Down Expand Up @@ -351,12 +352,13 @@ func TestDeclarativeSchemaAdapter_EKSCurrentVersion(t *testing.T) {
assert.False(t, lifecycle.IsEOL)
assert.False(t, lifecycle.IsExtendedSupport)

// EKS has NO true EOL.
assert.Nil(t, lifecycle.EOLDate)
// EKS true EOL is the end of extended support.
assert.NotNil(t, lifecycle.EOLDate)
// DeprecationDate = cycle.eol (end of standard support).
assert.NotNil(t, lifecycle.DeprecationDate)
// ExtendedSupportEnd = cycle.extendedSupport.
// ExtendedSupportEnd and EOLDate = cycle.extendedSupport.
assert.NotNil(t, lifecycle.ExtendedSupportEnd)
assert.Equal(t, *lifecycle.ExtendedSupportEnd, *lifecycle.EOLDate)
}

func TestDeclarativeSchemaAdapter_EKSInExtendedSupport(t *testing.T) {
Expand All @@ -378,8 +380,9 @@ func TestDeclarativeSchemaAdapter_EKSInExtendedSupport(t *testing.T) {

assert.True(t, lifecycle.IsSupported)
assert.True(t, lifecycle.IsDeprecated)
assert.False(t, lifecycle.IsEOL) // EKS never truly EOL
assert.False(t, lifecycle.IsEOL)
assert.True(t, lifecycle.IsExtendedSupport)
assert.NotNil(t, lifecycle.EOLDate)
}

func TestDeclarativeSchemaAdapter_EKSPastExtendedSupport(t *testing.T) {
Expand All @@ -398,11 +401,11 @@ func TestDeclarativeSchemaAdapter_EKSPastExtendedSupport(t *testing.T) {

assert.False(t, lifecycle.IsSupported)
assert.True(t, lifecycle.IsDeprecated)
assert.False(t, lifecycle.IsEOL) // EKS clusters keep running
assert.True(t, lifecycle.IsEOL)
assert.False(t, lifecycle.IsExtendedSupport)
}

func TestDeclarativeSchemaAdapter_EKSNoTrueEOL(t *testing.T) {
func TestDeclarativeSchemaAdapter_EKSEOLIsExtendedSupportEnd(t *testing.T) {
adapter := eksDeclarativeAdapter(t)

cycle := &ProductCycle{
Expand All @@ -415,12 +418,13 @@ func TestDeclarativeSchemaAdapter_EKSNoTrueEOL(t *testing.T) {
lifecycle, err := adapter.AdaptCycle(cycle)
require.NoError(t, err)

// Verify EKS has NO true EOL date.
assert.Nil(t, lifecycle.EOLDate)
// Verify EKS true EOL is the end of extended support.
assert.NotNil(t, lifecycle.EOLDate)
expectedDate, _ := time.Parse("2006-01-02", "2022-07-15")
assert.Equal(t, expectedDate, *lifecycle.EOLDate)

// ExtendedSupportEnd comes from cycle.extendedSupport (NOT cycle.eol).
assert.NotNil(t, lifecycle.ExtendedSupportEnd)
expectedDate, _ := time.Parse("2006-01-02", "2022-07-15")
assert.Equal(t, expectedDate, *lifecycle.ExtendedSupportEnd)

// DeprecationDate comes from cycle.eol (end of standard support).
Expand Down Expand Up @@ -453,6 +457,8 @@ func TestDeclarativeSchemaAdapter_EKSLegacyBooleanExtendedSupport(t *testing.T)
assert.False(t, lifecycle.IsSupported)
assert.True(t, lifecycle.IsDeprecated)
assert.False(t, lifecycle.IsExtendedSupport)
// Legacy boolean extendedSupport has no terminal date, so EOLDate stays nil
// rather than using cycle.eol (standard-support end) as true EOL.
assert.Nil(t, lifecycle.EOLDate)
}

Expand Down
11 changes: 7 additions & 4 deletions pkg/eol/endoflife/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ func TestProvider_DeclarativeLifecycle(t *testing.T) {
Field: lifecycleFieldExtendedSupport,
BoolTrueFallback: lifecycleFieldEOL,
},
EOLDate: LifecycleDateSource{Field: lifecycleFieldExtendedSupport},
DeprecatedWindow: lifecycleActionExtendedSupport,
PastExtendedSupport: lifecycleActionUnsupported,
}
Expand Down Expand Up @@ -370,14 +371,16 @@ func TestProvider_DeclarativeLifecycle(t *testing.T) {
t.Errorf("Expected version 1.32, got %s", v.Version)
}
// Declarative EKS config: cycle.EOL → DeprecationDate and
// cycle.ExtendedSupport → ExtendedSupportEnd. EOLDate stays nil
// because EKS clusters never truly EOL.
if v.EOLDate != nil {
t.Errorf("EOLDate = %v, want nil (EKS has no true EOL)", v.EOLDate)
// cycle.ExtendedSupport → ExtendedSupportEnd and EOLDate.
if v.EOLDate == nil {
t.Error("EOLDate should be set from cycle.ExtendedSupport")
}
if v.ExtendedSupportEnd == nil {
t.Error("ExtendedSupportEnd should be set from cycle.ExtendedSupport")
}
if v.EOLDate != nil && v.ExtendedSupportEnd != nil && !v.EOLDate.Equal(*v.ExtendedSupportEnd) {
t.Errorf("EOLDate = %v, want ExtendedSupportEnd %v", v.EOLDate, v.ExtendedSupportEnd)
}
})
}
}
Expand Down
11 changes: 11 additions & 0 deletions pkg/policy/messages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ func TestGetMessage_Yellow_ExtendedSupport(t *testing.T) {
assert.Contains(t, got, "extended support")
}

func TestGetMessage_Yellow_ExtendedSupport_WithEOL(t *testing.T) {
p := NewDefaultPolicy()
res := &types.Resource{Engine: "eks", CurrentVersion: "1.32"}
eol := time.Date(2027, 3, 23, 0, 0, 0, 0, time.UTC)
lc := &types.VersionLifecycle{IsExtendedSupport: true, EOLDate: &eol}

got := p.GetMessage(res, lc, types.StatusYellow)
assert.Contains(t, got, "extended support")
assert.NotContains(t, got, "End-of-Life")
}

func TestGetMessage_Yellow_DeprecatedSupport_WithEOL(t *testing.T) {
// Lambda-style: IsDeprecatedSupport with a deprecated-support
// end date. Exercises the IsDeprecatedSupport+EOLDate branch and
Expand Down
Loading