Skip to content

Commit 87118a0

Browse files
authored
feat(ubuntu): add eol date for 20.04-ESM (#8981)
1 parent 87fda76 commit 87118a0

File tree

2 files changed

+82
-21
lines changed

2 files changed

+82
-21
lines changed

pkg/detector/ospkg/ubuntu/ubuntu.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ var (
5454
"18.10": time.Date(2019, 7, 18, 23, 59, 59, 0, time.UTC),
5555
"19.04": time.Date(2020, 1, 18, 23, 59, 59, 0, time.UTC),
5656
"19.10": time.Date(2020, 7, 17, 23, 59, 59, 0, time.UTC),
57-
"20.04": time.Date(2025, 4, 23, 23, 59, 59, 0, time.UTC),
57+
"20.04": time.Date(2025, 5, 31, 23, 59, 59, 0, time.UTC),
58+
"20.04-ESM": time.Date(2030, 4, 30, 23, 59, 59, 0, time.UTC),
5859
"20.10": time.Date(2021, 7, 22, 23, 59, 59, 0, time.UTC),
5960
"21.04": time.Date(2022, 1, 20, 23, 59, 59, 0, time.UTC),
6061
"21.10": time.Date(2022, 7, 14, 23, 59, 59, 0, time.UTC),
@@ -67,16 +68,32 @@ var (
6768
}
6869
)
6970

71+
type Option func(*Scanner)
72+
73+
// WithEOLDates takes eol dates for testability
74+
func WithEOLDates(dates map[string]time.Time) Option {
75+
return func(s *Scanner) {
76+
s.eolDates = dates
77+
}
78+
}
79+
7080
// Scanner implements the Ubuntu scanner
7181
type Scanner struct {
72-
vs ubuntu.VulnSrc
82+
eolDates map[string]time.Time
83+
vs ubuntu.VulnSrc
7384
}
7485

7586
// NewScanner is the factory method for Scanner
76-
func NewScanner() *Scanner {
77-
return &Scanner{
78-
vs: ubuntu.NewVulnSrc(),
87+
func NewScanner(opts ...Option) *Scanner {
88+
s := &Scanner{
89+
eolDates: eolDates,
90+
vs: ubuntu.NewVulnSrc(),
91+
}
92+
93+
for _, opt := range opts {
94+
opt(s)
7995
}
96+
return s
8097
}
8198

8299
// Detect scans and returns the vulnerabilities
@@ -133,12 +150,13 @@ func (s *Scanner) Detect(ctx context.Context, osVer string, _ *ftypes.Repository
133150

134151
// IsSupportedVersion checks is OSFamily can be scanned using Ubuntu scanner
135152
func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool {
136-
return osver.Supported(ctx, eolDates, osFamily, osVer)
153+
osVer = s.versionFromEolDates(ctx, osVer)
154+
return osver.Supported(ctx, s.eolDates, osFamily, osVer)
137155
}
138156

139157
// versionFromEolDates checks if actual (not ESM) version is not outdated
140158
func (s *Scanner) versionFromEolDates(ctx context.Context, osVer string) string {
141-
if _, ok := eolDates[osVer]; ok {
159+
if _, ok := s.eolDates[osVer]; ok {
142160
return osVer
143161
}
144162

@@ -148,7 +166,7 @@ func (s *Scanner) versionFromEolDates(ctx context.Context, osVer string) string
148166
// then we need to get vulnerabilities for `18.04`
149167
// if `18.04` is outdated - we need to use `18.04-ESM` (we will return error until we add `18.04-ESM` to eolDates)
150168
ver := strings.TrimRight(osVer, "-ESM")
151-
if eol, ok := eolDates[ver]; ok && clock.Now(ctx).Before(eol) {
169+
if eol, ok := s.eolDates[ver]; ok && clock.Now(ctx).Before(eol) {
152170
return ver
153171
}
154172
return osVer

pkg/detector/ospkg/ubuntu/ubuntu_test.go

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ubuntu_test
22

33
import (
4+
"bytes"
45
"sort"
56
"testing"
67
"time"
@@ -15,9 +16,20 @@ import (
1516
"github.com/aquasecurity/trivy/pkg/clock"
1617
"github.com/aquasecurity/trivy/pkg/detector/ospkg/ubuntu"
1718
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
19+
"github.com/aquasecurity/trivy/pkg/log"
1820
"github.com/aquasecurity/trivy/pkg/types"
1921
)
2022

23+
var testEOLDates = map[string]time.Time{
24+
"12.04": time.Date(2019, 4, 26, 23, 59, 59, 0, time.UTC),
25+
"12.04-ESM": time.Date(2019, 4, 28, 23, 59, 59, 0, time.UTC),
26+
"18.04": time.Date(2023, 5, 31, 23, 59, 59, 0, time.UTC),
27+
"18.04-ESM": time.Date(2028, 3, 31, 23, 59, 59, 0, time.UTC),
28+
"19.04": time.Date(2020, 1, 18, 23, 59, 59, 0, time.UTC),
29+
"20.04": time.Date(2025, 5, 31, 23, 59, 59, 0, time.UTC),
30+
"21.04": time.Date(2022, 1, 20, 23, 59, 59, 0, time.UTC),
31+
}
32+
2133
func TestScanner_Detect(t *testing.T) {
2234
type args struct {
2335
osVer string
@@ -180,7 +192,7 @@ func TestScanner_Detect(t *testing.T) {
180192
_ = dbtest.InitDB(t, tt.fixtures)
181193
defer db.Close()
182194

183-
s := ubuntu.NewScanner()
195+
s := ubuntu.NewScanner(ubuntu.WithEOLDates(testEOLDates))
184196
got, err := s.Detect(ctx, tt.args.osVer, nil, tt.args.pkgs)
185197
if tt.wantErr != "" {
186198
require.ErrorContains(t, err, tt.wantErr)
@@ -201,10 +213,11 @@ func TestScanner_IsSupportedVersion(t *testing.T) {
201213
osVer string
202214
}
203215
tests := []struct {
204-
name string
205-
now time.Time
206-
args args
207-
want bool
216+
name string
217+
now time.Time
218+
args args
219+
want bool
220+
wantLog string
208221
}{
209222
{
210223
name: "ubuntu 12.04 eol ends",
@@ -216,7 +229,7 @@ func TestScanner_IsSupportedVersion(t *testing.T) {
216229
want: true,
217230
},
218231
{
219-
name: "ubuntu12.04",
232+
name: "ubuntu 12.04",
220233
now: time.Date(2019, 4, 31, 23, 59, 59, 0, time.UTC),
221234
args: args{
222235
osFamily: "ubuntu",
@@ -225,22 +238,41 @@ func TestScanner_IsSupportedVersion(t *testing.T) {
225238
want: false,
226239
},
227240
{
228-
name: "ubuntu 18.04 ESM. 18.04 is not outdated",
229-
now: time.Date(2022, 4, 31, 23, 59, 59, 0, time.UTC),
241+
name: "ubuntu 18.04 ESM and 18.04 are outdated",
242+
now: time.Date(2030, 4, 31, 23, 59, 59, 0, time.UTC),
243+
args: args{
244+
osFamily: "ubuntu",
245+
osVer: "18.04-ESM",
246+
},
247+
want: false,
248+
},
249+
{
250+
name: "ubuntu 18.04 ESM. Only 18.04 is outdated",
251+
now: time.Date(2027, 4, 31, 23, 59, 59, 0, time.UTC),
230252
args: args{
231253
osFamily: "ubuntu",
232254
osVer: "18.04-ESM",
233255
},
234256
want: true,
235257
},
236258
{
237-
name: "ubuntu 18.04 ESM. 18.04 is outdated",
259+
name: "ubuntu 20.04 ESM. 20.04 is not outdated, 20.04 ESM not added in EOL dates",
260+
now: time.Date(2022, 4, 31, 23, 59, 59, 0, time.UTC),
261+
args: args{
262+
osFamily: "ubuntu",
263+
osVer: "20.04-ESM",
264+
},
265+
want: true,
266+
},
267+
{
268+
name: "ubuntu 20.04 ESM. 20.04 is outdated, 20.04 ESM not added in EOL dates",
238269
now: time.Date(2030, 4, 31, 23, 59, 59, 0, time.UTC),
239270
args: args{
240271
osFamily: "ubuntu",
241-
osVer: "18.04-ESM",
272+
osVer: "20.04-ESM",
242273
},
243-
want: false,
274+
want: true,
275+
wantLog: "This OS version is not on the EOL list\tfamily=\"ubuntu\" version=\"20.04-ESM\"",
244276
},
245277
{
246278
name: "latest",
@@ -249,15 +281,26 @@ func TestScanner_IsSupportedVersion(t *testing.T) {
249281
osFamily: "ubuntu",
250282
osVer: "99.04",
251283
},
252-
want: true,
284+
want: true,
285+
wantLog: "This OS version is not on the EOL list\tfamily=\"ubuntu\" version=\"99.04\"",
253286
},
254287
}
255288
for _, tt := range tests {
256289
t.Run(tt.name, func(t *testing.T) {
290+
out := bytes.NewBuffer(nil)
291+
logger := log.New(log.NewHandler(out, &log.Options{Level: log.LevelInfo}))
292+
log.SetDefault(logger)
293+
257294
ctx := clock.With(t.Context(), tt.now)
258-
s := ubuntu.NewScanner()
295+
s := ubuntu.NewScanner(ubuntu.WithEOLDates(testEOLDates))
259296
got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer)
260297
assert.Equal(t, tt.want, got)
298+
299+
if out.Len() > 0 && tt.wantLog == "" {
300+
t.Errorf("IsSupportedVersion() logs not expected. Found logs: %s", out.String())
301+
return
302+
}
303+
assert.Contains(t, out.String(), tt.wantLog)
261304
})
262305
}
263306
}

0 commit comments

Comments
 (0)