Skip to content

Commit

Permalink
feat(analyzer): more general support for os-release (#470)
Browse files Browse the repository at this point in the history
Co-authored-by: DmitriyLewen <[email protected]>
  • Loading branch information
knqyf263 and DmitriyLewen authored May 3, 2022
1 parent 2ac98ef commit 873c6de
Show file tree
Hide file tree
Showing 21 changed files with 253 additions and 299 deletions.
3 changes: 1 addition & 2 deletions analyzer/all/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ import (
_ "github.com/aquasecurity/fanal/analyzer/os/amazonlinux"
_ "github.com/aquasecurity/fanal/analyzer/os/debian"
_ "github.com/aquasecurity/fanal/analyzer/os/mariner"
_ "github.com/aquasecurity/fanal/analyzer/os/photon"
_ "github.com/aquasecurity/fanal/analyzer/os/redhatbase"
_ "github.com/aquasecurity/fanal/analyzer/os/suse"
_ "github.com/aquasecurity/fanal/analyzer/os/release"
_ "github.com/aquasecurity/fanal/analyzer/os/ubuntu"
_ "github.com/aquasecurity/fanal/analyzer/pkg/apk"
_ "github.com/aquasecurity/fanal/analyzer/pkg/dpkg"
Expand Down
1 change: 1 addition & 0 deletions analyzer/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const (
// ======
// OS
// ======
TypeOSRelease Type = "os-release"
TypeAlpine Type = "alpine"
TypeAmazon Type = "amazon"
TypeCBLMariner Type = "cbl-mariner"
Expand Down
65 changes: 0 additions & 65 deletions analyzer/os/photon/photon.go

This file was deleted.

61 changes: 0 additions & 61 deletions analyzer/os/photon/photon_test.go

This file was deleted.

1 change: 0 additions & 1 deletion analyzer/os/photon/testdata/not_photon/os-release

This file was deleted.

84 changes: 84 additions & 0 deletions analyzer/os/release/release.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package release

import (
"bufio"
"context"
"os"
"strings"

"golang.org/x/exp/slices"

"github.com/aquasecurity/fanal/analyzer"
aos "github.com/aquasecurity/fanal/analyzer/os"
"github.com/aquasecurity/fanal/types"
)

func init() {
analyzer.RegisterAnalyzer(&osReleaseAnalyzer{})
}

const version = 1

var requiredFiles = []string{
"etc/os-release",
"usr/lib/os-release",
}

type osReleaseAnalyzer struct{}

func (a osReleaseAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
var id, versionID string
scanner := bufio.NewScanner(input.Content)
for scanner.Scan() {
line := scanner.Text()

ss := strings.SplitN(line, "=", 2)
if len(ss) != 2 {
continue
}
key, value := strings.TrimSpace(ss[0]), strings.TrimSpace(ss[1])

switch key {
case "ID":
id = strings.Trim(value, `"'`)
case "VERSION_ID":
versionID = strings.Trim(value, `"'`)
default:
continue
}

var family string
switch id {
case "alpine":
family = aos.Alpine
case "opensuse-tumbleweed":
family = aos.OpenSUSETumbleweed
case "opensuse-leap", "opensuse": // opensuse for leap:42, opensuse-leap for leap:15
family = aos.OpenSUSELeap
case "sles":
family = aos.SLES
case "photon":
family = aos.Photon
}

if family != "" && versionID != "" {
return &analyzer.AnalysisResult{
OS: &types.OS{Family: family, Name: versionID},
}, nil
}
}

return nil, nil
}

func (a osReleaseAnalyzer) Required(filePath string, _ os.FileInfo) bool {
return slices.Contains(requiredFiles, filePath)
}

func (a osReleaseAnalyzer) Type() analyzer.Type {
return analyzer.TypeOSRelease
}

func (a osReleaseAnalyzer) Version() int {
return version
}
112 changes: 112 additions & 0 deletions analyzer/os/release/release_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package release

import (
"context"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/aquasecurity/fanal/analyzer"
aos "github.com/aquasecurity/fanal/analyzer/os"
"github.com/aquasecurity/fanal/types"
)

func Test_osReleaseAnalyzer_Analyze(t *testing.T) {
tests := []struct {
name string
inputFile string
input analyzer.AnalysisInput
want *analyzer.AnalysisResult
wantErr string
}{
{
name: "alpine",
inputFile: "testdata/alpine",
want: &analyzer.AnalysisResult{
OS: &types.OS{Family: aos.Alpine, Name: "3.15.4"},
},
},
{
name: "openSUSE-leap 15.2.1",
inputFile: "testdata/opensuseleap-15.2.1",
want: &analyzer.AnalysisResult{
OS: &types.OS{Family: aos.OpenSUSELeap, Name: "15.2.1"},
},
},
{
name: "openSUSE-leap 42.3",
inputFile: "testdata/opensuseleap-42.3",
want: &analyzer.AnalysisResult{
OS: &types.OS{Family: aos.OpenSUSELeap, Name: "42.3"},
},
},
{
name: "openSUSE-tumbleweed",
inputFile: "testdata/opensusetumbleweed",
want: &analyzer.AnalysisResult{
OS: &types.OS{Family: aos.OpenSUSETumbleweed, Name: "20220412"},
},
},
{
name: "SUSE Linux Enterprise Server",
inputFile: "testdata/sles",
want: &analyzer.AnalysisResult{
OS: &types.OS{Family: aos.SLES, Name: "15.3"},
},
},
{
name: "Photon OS",
inputFile: "testdata/photon",
want: &analyzer.AnalysisResult{
OS: &types.OS{Family: aos.Photon, Name: "4.0"},
},
},
{
name: "Photon OS",
inputFile: "testdata/photon",
want: &analyzer.AnalysisResult{
OS: &types.OS{Family: aos.Photon, Name: "4.0"},
},
},
{
name: "Unknown OS",
inputFile: "testdata/unknown",
want: nil,
},
{
name: "No 'ID' field",
inputFile: "testdata/no-id",
want: nil,
},
{
name: "No 'VERSION_ID' field",
inputFile: "testdata/no-version",
want: nil,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f, err := os.Open(tt.inputFile)
require.NoError(t, err)
defer f.Close()

a := osReleaseAnalyzer{}
res, err := a.Analyze(context.Background(), analyzer.AnalysisInput{
FilePath: "etc/os-release",
Content: f,
})

if tt.wantErr != "" {
assert.Error(t, err)
assert.Equal(t, tt.wantErr, err.Error())
return
}

assert.NoError(t, err)
assert.Equal(t, tt.want, res)
})
}
}
6 changes: 6 additions & 0 deletions analyzer/os/release/testdata/alpine
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.15.4
PRETTY_NAME="Alpine Linux v3.15"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
5 changes: 5 additions & 0 deletions analyzer/os/release/testdata/no-id
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
NAME="Alpine Linux"
VERSION_ID=3.15.4
PRETTY_NAME="Alpine Linux v3.15"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
5 changes: 5 additions & 0 deletions analyzer/os/release/testdata/no-version
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
NAME="Alpine Linux"
ID=alpine
PRETTY_NAME="Alpine Linux v3.15"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
10 changes: 10 additions & 0 deletions analyzer/os/release/testdata/opensuseleap-15.2.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
NAME="openSUSE Leap"
VERSION="15.2.1 Beta"
ID="opensuse-leap"
ID_LIKE="suse opensuse"
VERSION_ID="15.2.1"
PRETTY_NAME="openSUSE Leap 15.2.1 Beta"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap:15.2.1"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
10 changes: 10 additions & 0 deletions analyzer/os/release/testdata/opensuseleap-42.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
NAME="openSUSE Leap"
VERSION="42.3"
ID=opensuse
ID_LIKE="suse"
VERSION_ID="42.3"
PRETTY_NAME="openSUSE Leap 42.3"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap:42.3"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
Loading

0 comments on commit 873c6de

Please sign in to comment.