From 7334cc7278f934309320a1458f3b1f527adfb799 Mon Sep 17 00:00:00 2001 From: Ben Apprederisse Date: Mon, 1 Jun 2026 10:48:16 -0700 Subject: [PATCH] Use actionable EOL date for Lambda runtimes Amp-Thread-ID: https://ampcode.com/threads/T-019e5099-4b6f-7044-b7af-730879f8dee3 Co-authored-by: Amp --- pkg/config/defaults/resources.yaml | 17 ++++++--- pkg/eol/endoflife/ADAPTERS.md | 15 ++++---- pkg/eol/endoflife/adapters_test.go | 58 ++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 12 deletions(-) diff --git a/pkg/config/defaults/resources.yaml b/pkg/config/defaults/resources.yaml index 501e2db..800304c 100644 --- a/pkg/config/defaults/resources.yaml +++ b/pkg/config/defaults/resources.yaml @@ -318,11 +318,18 @@ resources: eol: provider: endoflife-date product: aws-lambda - # Lambda uses the standard API shape: `support` marks the start of - # deprecated runtime support and `eol` is the terminal date. There is - # no `extendedSupport` field, so the standard adapter classifies that - # window as deprecated support, not paid extended support. - schema: standard + # Lambda's `support` date is the first/actionable runtime EOL date + # shown to service owners. The upstream `eol` date is AWS's later + # terminal deprecated-support date, so keep it as structured lifecycle + # detail but do not use it as the primary EOLDate. + schema: declarative + lifecycle: + deprecation_date: + field: support + extended_support_end: + field: eol + eol_date: + field: support # To add a new resource type, follow skills/add-version-guard-resource. # Standalone copy-paste templates live in skills/add-version-guard-resource/examples/. diff --git a/pkg/eol/endoflife/ADAPTERS.md b/pkg/eol/endoflife/ADAPTERS.md index d919a89..8f7047c 100644 --- a/pkg/eol/endoflife/ADAPTERS.md +++ b/pkg/eol/endoflife/ADAPTERS.md @@ -127,7 +127,9 @@ boolean and no terminal EOL date is available. ### Lambda Lambda uses Standard Support and Deprecated Support columns instead of -`extendedSupport`. The deprecated-support window should be YELLOW. +`extendedSupport`. For Version Guard's user-facing `EOLDate`, Lambda uses +the first/actionable date (`support`) so dashboards do not show AWS's later +terminal deprecated-support date as the runtime EOL. ```yaml eol: @@ -140,14 +142,13 @@ eol: extended_support_end: field: eol eol_date: - field: eol - deprecated_window: extended_support - past_extended_support: eol + field: support ``` -For `python3.8` (`support: 2024-10-14`, `eol: 2026-09-30`), dates -between those two boundaries become YELLOW. Dates after `eol` become -true EOL / RED. +For `python3.8` (`support: 2024-10-14`, `eol: 2027-03-03`), the emitted +`EOLDate` is `2024-10-14`, while `ExtendedSupportEnd` preserves the later +AWS terminal date for downstream consumers that need it. Dates after +`support` become true EOL / RED. --- diff --git a/pkg/eol/endoflife/adapters_test.go b/pkg/eol/endoflife/adapters_test.go index c30c980..172ca90 100644 --- a/pkg/eol/endoflife/adapters_test.go +++ b/pkg/eol/endoflife/adapters_test.go @@ -261,6 +261,18 @@ func eksDeclarativeAdapter(t *testing.T) *DeclarativeSchemaAdapter { return adapter } +func lambdaActionableEOLAdapter(t *testing.T) *DeclarativeSchemaAdapter { + t.Helper() + + adapter, err := NewDeclarativeSchemaAdapter(&DeclarativeLifecycleConfig{ + DeprecationDate: LifecycleDateSource{Field: lifecycleFieldSupport}, + ExtendedSupportEnd: LifecycleDateSource{Field: lifecycleFieldEOL}, + EOLDate: LifecycleDateSource{Field: lifecycleFieldSupport}, + }) + require.NoError(t, err) + return adapter +} + func TestStandardSchemaAdapter_LambdaDeprecatedSupportWindow(t *testing.T) { adapter := &StandardSchemaAdapter{} @@ -328,6 +340,52 @@ func TestStandardSchemaAdapter_LambdaCurrentStandardSupport(t *testing.T) { assert.False(t, lifecycle.IsEOL) } +func TestDeclarativeSchemaAdapter_LambdaUsesSupportAsActionableEOL(t *testing.T) { + adapter := lambdaActionableEOLAdapter(t) + + support := time.Now().AddDate(0, 0, 60) + terminal := time.Now().AddDate(1, 0, 0) + cycle := &ProductCycle{ + Cycle: "python3.10", + ReleaseDate: "2023-04-18", + Support: support.Format("2006-01-02"), + EOL: terminal.Format("2006-01-02"), + } + + lifecycle, err := adapter.AdaptCycle(cycle) + require.NoError(t, err) + + require.NotNil(t, lifecycle.EOLDate) + require.NotNil(t, lifecycle.DeprecationDate) + require.NotNil(t, lifecycle.ExtendedSupportEnd) + assert.Equal(t, support.Format("2006-01-02"), lifecycle.EOLDate.Format("2006-01-02")) + assert.Equal(t, support.Format("2006-01-02"), lifecycle.DeprecationDate.Format("2006-01-02")) + assert.Equal(t, terminal.Format("2006-01-02"), lifecycle.ExtendedSupportEnd.Format("2006-01-02")) + assert.True(t, lifecycle.IsSupported) + assert.False(t, lifecycle.IsDeprecated) + assert.False(t, lifecycle.IsEOL) +} + +func TestDeclarativeSchemaAdapter_LambdaPastActionableEOLIsEOL(t *testing.T) { + adapter := lambdaActionableEOLAdapter(t) + + cycle := &ProductCycle{ + Cycle: "python3.8", + ReleaseDate: "2019-11-18", + Support: time.Now().AddDate(0, -1, 0).Format("2006-01-02"), + EOL: time.Now().AddDate(1, 0, 0).Format("2006-01-02"), + } + + lifecycle, err := adapter.AdaptCycle(cycle) + require.NoError(t, err) + + assert.False(t, lifecycle.IsSupported) + assert.True(t, lifecycle.IsDeprecated) + assert.True(t, lifecycle.IsEOL) + assert.False(t, lifecycle.IsDeprecatedSupport) + assert.False(t, lifecycle.IsExtendedSupport) +} + func TestDeclarativeSchemaAdapter_EKSCurrentVersion(t *testing.T) { adapter := eksDeclarativeAdapter(t)