ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
96
services/mirrored-image/controller/inventory.go
Normal file
96
services/mirrored-image/controller/inventory.go
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
apk "github.com/knqyf263/go-apk-version"
|
||||
)
|
||||
|
||||
type scanInventory struct {
|
||||
Hash string `json:"manifest_hash"`
|
||||
Packages map[string]*scanPackage `json:"packages"`
|
||||
Distributions map[string]*scanDistribution `json:"distributions"`
|
||||
Environments map[string][]*scanEnvironment `json:"environments"`
|
||||
}
|
||||
|
||||
type scanPackage struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Kind string `json:"kind"`
|
||||
Source *scanPackage `json:"source"`
|
||||
}
|
||||
|
||||
type scanDistribution struct {
|
||||
ID string `json:"id"`
|
||||
DID string `json:"did"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
PrettyName string `json:"pretty_name"`
|
||||
}
|
||||
|
||||
type scanEnvironment struct {
|
||||
PackageDB string `json:"package_db"`
|
||||
IntroducedIn string `json:"introduced_in"`
|
||||
DistributionID string `json:"distribution_id"`
|
||||
RepositoryIDs []string `json:"repository_ids"`
|
||||
}
|
||||
|
||||
type featureKey struct {
|
||||
Name string
|
||||
Version string
|
||||
Layer string
|
||||
}
|
||||
|
||||
func checkInventory(data *securityData, digest string, layers map[string]bool) error {
|
||||
if data == nil || data.Inventory == nil || data.Layer == nil || data.Layer.Features == nil {
|
||||
return fmt.Errorf("scan inventory is unavailable")
|
||||
}
|
||||
inv := data.Inventory
|
||||
if inv.Hash != digest || data.Layer.Name != digest {
|
||||
return fmt.Errorf("scan identity does not match candidate")
|
||||
}
|
||||
if len(inv.Packages) == 0 || len(inv.Distributions) == 0 || len(inv.Environments) != len(inv.Packages) {
|
||||
return fmt.Errorf("scan inventory is incomplete")
|
||||
}
|
||||
for id, distro := range inv.Distributions {
|
||||
if distro == nil || distro.ID != id || distro.DID != "alpine" || distro.Version != "3.23" || distro.Name != "Alpine Linux" || distro.PrettyName != "Alpine Linux v3.23" {
|
||||
return fmt.Errorf("distribution coverage is not qualified")
|
||||
}
|
||||
}
|
||||
expected := map[featureKey]int{}
|
||||
for id, pkg := range inv.Packages {
|
||||
if pkg == nil || pkg.ID != id || pkg.Name == "" || pkg.Version == "" || pkg.Kind != "binary" {
|
||||
return fmt.Errorf("package identity is incomplete")
|
||||
}
|
||||
if _, err := apk.NewVersion(pkg.Version); err != nil {
|
||||
return fmt.Errorf("package version is not matchable")
|
||||
}
|
||||
if pkg.Source == nil || pkg.Source.Name == "" || pkg.Source.Kind != "source" {
|
||||
return fmt.Errorf("source package identity is missing")
|
||||
}
|
||||
envs := inv.Environments[id]
|
||||
if len(envs) == 0 {
|
||||
return fmt.Errorf("package environment is missing")
|
||||
}
|
||||
for _, env := range envs {
|
||||
if env == nil || env.PackageDB != "lib/apk/db/installed" || !layers[env.IntroducedIn] || inv.Distributions[env.DistributionID] == nil || len(env.RepositoryIDs) != 0 {
|
||||
return fmt.Errorf("package environment is not qualified")
|
||||
}
|
||||
}
|
||||
expected[featureKey{pkg.Name, pkg.Version, envs[0].IntroducedIn}]++
|
||||
}
|
||||
for _, feature := range *data.Layer.Features {
|
||||
key := featureKey{feature.Name, feature.Version, feature.AddedBy}
|
||||
if expected[key] == 0 {
|
||||
return fmt.Errorf("scan feature does not match inventory")
|
||||
}
|
||||
expected[key]--
|
||||
}
|
||||
for _, count := range expected {
|
||||
if count != 0 {
|
||||
return fmt.Errorf("scan features omit indexed packages")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Loading…
Reference in a new issue