Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arch op: turn into string, implement pattern match #195

Merged
merged 2 commits into from
Jun 23, 2020
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
85 changes: 85 additions & 0 deletions archop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package claircore

import (
"bytes"
"database/sql/driver"
"fmt"
"regexp"
)

type ArchOp uint

const (
opInvalid ArchOp = iota // invalid

OpEquals // equals
OpNotEquals // not equals
OpPatternMatch // pattern match
)

func (o ArchOp) Cmp(a, b string) bool {
switch {
case b == "":
return true
case a == "":
return false
default:
}
switch o {
case OpEquals:
return a == b
case OpNotEquals:
return a != b
case OpPatternMatch:
re, err := regexp.Compile(b)
if err != nil {
return false
}
return re.MatchString(a)
default:
}
return false
}

//go:generate stringer -type=ArchOp -linecomment

func (o ArchOp) MarshalText() (text []byte, err error) {
return []byte(o.String()), nil
}

func (o *ArchOp) UnmarshalText(text []byte) error {
i := bytes.Index([]byte(_ArchOp_name), text)
if i == -1 {
*o = ArchOp(0)
return nil
}
idx := uint8(i)
for i, off := range _ArchOp_index {
if off == idx {
*o = ArchOp(i)
return nil
}
}
panic("unreachable")
}

func (o ArchOp) Value() (driver.Value, error) {
return o.String(), nil
}

func (o *ArchOp) Scan(i interface{}) error {
switch v := i.(type) {
case []byte:
return o.UnmarshalText(v)
case string:
return o.UnmarshalText([]byte(v))
case int64:
if v >= int64(len(_ArchOp_index)-1) {
return fmt.Errorf("unable to scan ArchOp from enum %d", v)
}
*o = ArchOp(v)
default:
return fmt.Errorf("unable to scan ArchOp from type %T", i)
}
return nil
}
9 changes: 5 additions & 4 deletions archop_string.go

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

2 changes: 1 addition & 1 deletion internal/vulnstore/postgres/update_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ func (e *e2e) DeleteUpdateOperations(ctx context.Context) func(*testing.T) {
}

// checkInsertedVulns confirms vulnerabilitiles are inserted into the database correctly when
// store.UpdateVulnerabilities is calld.
// store.UpdateVulnerabilities is called.
func checkInsertedVulns(ctx context.Context, t *testing.T, db *sqlx.DB, id uuid.UUID, vulns []*claircore.Vulnerability) {
const query = `SELECT
vuln.hash_kind,
Expand Down
2 changes: 1 addition & 1 deletion libvuln/migrations/migration1.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const (
repo_key TEXT,
repo_uri TEXT,
fixed_in_version TEXT,
arch_operation bigint,
arch_operation TEXT,
vulnerable_range VersionRange NOT NULL DEFAULT VersionRange('{}', '{}', '()'),
version_kind TEXT,
UNIQUE (hash_kind, hash)
Expand Down
72 changes: 18 additions & 54 deletions osrelease/scanner_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package osrelease

import (
"compress/gzip"
"context"
"errors"
"io"
"net/http"
"os"
"path/filepath"
"runtime/trace"
Expand All @@ -15,7 +11,7 @@ import (

"github.com/quay/claircore"
"github.com/quay/claircore/pkg/cpe"
"github.com/quay/claircore/test/integration"
"github.com/quay/claircore/test/fetch"
"github.com/quay/claircore/test/log"
)

Expand Down Expand Up @@ -135,50 +131,13 @@ func TestParse(t *testing.T) {
}

type layercase struct {
Name string
URL string
Want []*claircore.Distribution
Name string
Layer layerspec
Want []*claircore.Distribution
}

func (lc *layercase) name() string {
return filepath.Join("testdata", lc.Name+".layer")
}

func (lc layercase) Prep(t *testing.T) {
t.Helper()
fn := lc.name()
_, err := os.Stat(fn)
switch {
case err == nil:
t.Logf("found layer cached: %q", fn)
return
case errors.Is(err, os.ErrNotExist):
integration.Skip(t)
t.Logf("fetching %q → %q", lc.URL, fn)
default:
t.Fatal(err)
}
f, err := os.Create(fn)
if err != nil {
t.Fatal(err)
}
defer f.Close()
res, err := http.Get(lc.URL)
if err != nil {
t.Fatal(err)
}
if res.StatusCode != http.StatusOK {
t.Fatal(res.Status)
}
rd, err := gzip.NewReader(res.Body)
if err != nil {
t.Fatal(err)
}
defer rd.Close()
if _, err := io.Copy(f, rd); err != nil {
t.Fatal(err)
}
t.Logf("fetched %q", fn)
type layerspec struct {
From, Repo string
Blob claircore.Digest
}

func (lc layercase) Test(t *testing.T) {
Expand All @@ -188,7 +147,12 @@ func (lc layercase) Test(t *testing.T) {
ctx = log.TestLogger(ctx, t)
s := Scanner{}
l := &claircore.Layer{}
if err := l.SetLocal(lc.name()); err != nil {
f, err := fetch.Layer(ctx, t, nil, lc.Layer.From, lc.Layer.Repo, lc.Layer.Blob)
if err != nil {
t.Fatal(err)
}
defer f.Close()
if err := l.SetLocal(f.Name()); err != nil {
t.Fatal(err)
}
ds, err := s.Scan(ctx, l)
Expand All @@ -205,7 +169,11 @@ func TestLayer(t *testing.T) {
tt := []layercase{
{
Name: "ubuntu_18.04",
URL: "https://storage.googleapis.com/quay-sandbox-01/datastorage/registry/sha256/35/35c102085707f703de2d9eaad8752d6fe1b8f02b5d2149f1d8357c9cc7fb7d0a",
Layer: layerspec{
From: "docker.io",
Repo: "library/ubuntu",
Blob: claircore.MustParseDigest(`sha256:35c102085707f703de2d9eaad8752d6fe1b8f02b5d2149f1d8357c9cc7fb7d0a`),
},
Want: []*claircore.Distribution{
&claircore.Distribution{
DID: "ubuntu",
Expand All @@ -219,10 +187,6 @@ func TestLayer(t *testing.T) {
},
}

for _, tc := range tt {
tc.Prep(t)
}

for _, tc := range tt {
t.Run(tc.Name, tc.Test)
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/ovalutil/rpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ func mapArchOp(op oval.Operation) claircore.ArchOp {
return claircore.OpEquals
case oval.OpNotEquals:
return claircore.OpNotEquals
case oval.OpPatternMatch:
return claircore.OpPatternMatch
default:
}
return claircore.ArchOp(0)
Expand Down
31 changes: 2 additions & 29 deletions vulnerability.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,9 @@
package claircore

import "time"

type ArchOp uint

const (
_ ArchOp = iota // invalid

OpEquals // equals
OpNotEquals // not equals
import (
"time"
)

func (o ArchOp) Cmp(a, b string) bool {
switch {
case b == "":
return true
case a == "":
return false
default:
}
switch o {
case OpEquals:
return a == b
case OpNotEquals:
return a != b
default:
}
return false
}

//go:generate stringer -type=ArchOp -linecomment

type Vulnerability struct {
// unique ID of this vulnerability. this will be created as discovered by the library
// and used for persistence and hash map indexes
Expand Down