fix: standardize casing of initialisms (#112)
* fix: standardize casing of initialisms * fix: rename intoto -> inToto and Intoto to InToto * fix: fix all linting errors
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/theupdateframework/go-tuf/v2/metadata"
|
||||
)
|
||||
|
||||
func ExampleNewTufClient_registry() {
|
||||
func ExampleNewClient_registry() {
|
||||
// create a tuf client
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
@@ -21,7 +21,7 @@ func ExampleNewTufClient_registry() {
|
||||
metadataURI := "registry-1.docker.io/docker/tuf-metadata:latest"
|
||||
targetsURI := "registry-1.docker.io/docker/tuf-targets"
|
||||
|
||||
registryClient, err := tuf.NewTufClient(embed.RootStaging.Data, tufOutputPath, metadataURI, targetsURI, tuf.NewMockVersionChecker())
|
||||
registryClient, err := tuf.NewClient(embed.RootStaging.Data, tufOutputPath, metadataURI, targetsURI, tuf.NewMockVersionChecker())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -6,25 +6,25 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type mockTufClient struct {
|
||||
type MockTufClient struct {
|
||||
srcPath string
|
||||
dstPath string
|
||||
}
|
||||
|
||||
func NewMockTufClient(srcPath string, dstPath string) *mockTufClient {
|
||||
func NewMockTufClient(srcPath string, dstPath string) *MockTufClient {
|
||||
if srcPath == "" {
|
||||
panic("srcPath must be set")
|
||||
}
|
||||
if dstPath == "" {
|
||||
panic("dstPath must be set")
|
||||
}
|
||||
return &mockTufClient{
|
||||
return &MockTufClient{
|
||||
srcPath: srcPath,
|
||||
dstPath: dstPath,
|
||||
}
|
||||
}
|
||||
|
||||
func (dc *mockTufClient) DownloadTarget(target string, filePath string) (actualFilePath string, data []byte, err error) {
|
||||
func (dc *MockTufClient) DownloadTarget(target string, filePath string) (actualFilePath string, data []byte, err error) {
|
||||
src, err := os.Open(filepath.Join(dc.srcPath, target))
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
@@ -59,14 +59,14 @@ func (dc *mockTufClient) DownloadTarget(target string, filePath string) (actualF
|
||||
return dstFilePath, b, nil
|
||||
}
|
||||
|
||||
type mockVersionChecker struct {
|
||||
type MockVersionChecker struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func NewMockVersionChecker() *mockVersionChecker {
|
||||
return &mockVersionChecker{}
|
||||
func NewMockVersionChecker() *MockVersionChecker {
|
||||
return &MockVersionChecker{}
|
||||
}
|
||||
|
||||
func (vc *mockVersionChecker) CheckVersion(client TUFClient) error {
|
||||
func (vc *MockVersionChecker) CheckVersion(_ Downloader) error {
|
||||
return vc.err
|
||||
}
|
||||
|
||||
@@ -19,14 +19,14 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
TufFileNameAnnotation = "tuf.io/filename"
|
||||
TUFFileNameAnnotation = "tuf.io/filename"
|
||||
)
|
||||
|
||||
type TufRole string
|
||||
type Role string
|
||||
|
||||
var TufRoles = []TufRole{metadata.ROOT, metadata.SNAPSHOT, metadata.TARGETS, metadata.TIMESTAMP}
|
||||
var Roles = []Role{metadata.ROOT, metadata.SNAPSHOT, metadata.TARGETS, metadata.TIMESTAMP}
|
||||
|
||||
// RegistryFetcher implements Fetcher
|
||||
// RegistryFetcher implements Fetcher.
|
||||
type RegistryFetcher struct {
|
||||
httpUserAgent string
|
||||
metadataRepo string
|
||||
@@ -46,13 +46,13 @@ func NewImageCache() *ImageCache {
|
||||
}
|
||||
}
|
||||
|
||||
// Get image from cache
|
||||
// Get image from cache.
|
||||
func (c *ImageCache) Get(imgRef string) ([]byte, bool) {
|
||||
img, found := c.cache[imgRef]
|
||||
return img, found
|
||||
}
|
||||
|
||||
// Add image to cache
|
||||
// Add image to cache.
|
||||
func (c *ImageCache) Put(imgRef string, img []byte) {
|
||||
c.cache[imgRef] = img
|
||||
}
|
||||
@@ -113,7 +113,7 @@ func (d *RegistryFetcher) DownloadFile(urlPath string, maxLength int64, timeout
|
||||
}
|
||||
}
|
||||
|
||||
// getManifest returns the manifest for an image or index
|
||||
// getManifest returns the manifest for an image or index.
|
||||
func (d *RegistryFetcher) getManifest(ref string) ([]byte, error) {
|
||||
// Pull image manifest
|
||||
var err error
|
||||
@@ -135,7 +135,7 @@ func (d *RegistryFetcher) getManifest(ref string) ([]byte, error) {
|
||||
return mf, nil
|
||||
}
|
||||
|
||||
// pullFileLayer pulls a layer for an image or index and returns its data
|
||||
// pullFileLayer pulls a layer for an image or index and returns its data.
|
||||
func (d *RegistryFetcher) pullFileLayer(ref string, maxLength int64) ([]byte, error) {
|
||||
var data []byte
|
||||
var found bool
|
||||
@@ -159,7 +159,7 @@ func (d *RegistryFetcher) pullFileLayer(ref string, maxLength int64) ([]byte, er
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// getDataFromLayer returns the data from a layer in an image
|
||||
// getDataFromLayer returns the data from a layer in an image.
|
||||
func getDataFromLayer(fileLayer v1.Layer, maxLength int64) ([]byte, error) {
|
||||
length, err := fileLayer.Size()
|
||||
if err != nil {
|
||||
@@ -185,7 +185,7 @@ func getDataFromLayer(fileLayer v1.Layer, maxLength int64) ([]byte, error) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// parseImgRef maintains the Fetcher interface by parsing a URL path to an image reference and file name
|
||||
// parseImgRef maintains the Fetcher interface by parsing a URL path to an image reference and file name.
|
||||
func (d *RegistryFetcher) parseImgRef(urlPath string) (imgRef, fileName string, err error) {
|
||||
// Check if repo is target or metadata
|
||||
if strings.Contains(urlPath, d.targetsRepo) {
|
||||
@@ -208,12 +208,11 @@ func (d *RegistryFetcher) parseImgRef(urlPath string) (imgRef, fileName string,
|
||||
return fmt.Sprintf("%s:%s", d.metadataRepo, role), fileName, nil
|
||||
}
|
||||
return fmt.Sprintf("%s:%s", d.metadataRepo, d.metadataTag), fileName, nil
|
||||
} else {
|
||||
return "", "", fmt.Errorf("urlPath: %s must be in metadata or targets repo", urlPath)
|
||||
}
|
||||
return "", "", fmt.Errorf("urlPath: %s must be in metadata or targets repo", urlPath)
|
||||
}
|
||||
|
||||
// findFileInManifest searches the image or index manifest for a file with the given name and returns its digest
|
||||
// findFileInManifest searches the image or index manifest for a file with the given name and returns its digest.
|
||||
func (d *RegistryFetcher) findFileInManifest(mf []byte, name string) (*v1.Hash, error) {
|
||||
var index bool
|
||||
|
||||
@@ -226,20 +225,21 @@ func (d *RegistryFetcher) findFileInManifest(mf []byte, name string) (*v1.Hash,
|
||||
|
||||
// determine image or index manifest
|
||||
var layers []Layer
|
||||
if l.MediaType == string(types.OCIImageIndex) {
|
||||
switch l.MediaType {
|
||||
case string(types.OCIImageIndex):
|
||||
layers = l.Manifests
|
||||
index = true
|
||||
} else if l.MediaType == string(types.OCIManifestSchema1) {
|
||||
case string(types.OCIManifestSchema1):
|
||||
layers = l.Layers
|
||||
index = false
|
||||
} else {
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid manifest media type: %s", l.MediaType)
|
||||
}
|
||||
|
||||
// find annotation with file name
|
||||
var digest string
|
||||
for _, layer := range layers {
|
||||
if layer.Annotations[TufFileNameAnnotation] == name {
|
||||
if layer.Annotations[TUFFileNameAnnotation] == name {
|
||||
digest = layer.Digest
|
||||
break
|
||||
}
|
||||
@@ -267,7 +267,7 @@ func (d *RegistryFetcher) findFileInManifest(mf []byte, name string) (*v1.Hash,
|
||||
return hash, nil
|
||||
}
|
||||
|
||||
// transportWithTimeout returns a http.RoundTripper with a specified timeout
|
||||
// transportWithTimeout returns a http.RoundTripper with a specified timeout.
|
||||
func transportWithTimeout(timeout time.Duration) http.RoundTripper {
|
||||
// transport is based on go-containerregistry remote.DefaultTransport
|
||||
// with modifications to include a specified timeout
|
||||
@@ -286,9 +286,9 @@ func transportWithTimeout(timeout time.Duration) http.RoundTripper {
|
||||
}
|
||||
}
|
||||
|
||||
// isDelegatedRole returns true if the role is a delegated role
|
||||
// isDelegatedRole returns true if the role is a delegated role.
|
||||
func isDelegatedRole(role string) bool {
|
||||
for _, r := range TufRoles {
|
||||
for _, r := range Roles {
|
||||
if role == string(r) {
|
||||
return false // role is not a delegated role
|
||||
}
|
||||
@@ -296,7 +296,7 @@ func isDelegatedRole(role string) bool {
|
||||
return true // role is a delegated role
|
||||
}
|
||||
|
||||
// roleFromConsistentName returns the role name from a consistent snapshot file name
|
||||
// roleFromConsistentName returns the role name from a consistent snapshot file name.
|
||||
func roleFromConsistentName(filename string) string {
|
||||
name := strings.TrimSuffix(filename, ".json")
|
||||
role := strings.Split(name, ".")
|
||||
|
||||
@@ -30,6 +30,8 @@ import (
|
||||
|
||||
const (
|
||||
tufTargetMediaType = "application/vnd.tuf.target"
|
||||
testRole = "test-role"
|
||||
tufMetadataRepo = "tuf-metadata"
|
||||
)
|
||||
|
||||
func TestRegistryFetcher(t *testing.T) {
|
||||
@@ -40,13 +42,13 @@ func TestRegistryFetcher(t *testing.T) {
|
||||
t.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
|
||||
}
|
||||
}()
|
||||
LoadRegistryTestData(t, regAddr, OciTufTestDataPath)
|
||||
LoadRegistryTestData(t, regAddr, OCITUFTestDataPath)
|
||||
|
||||
metadataRepo := regAddr.Host + "/tuf-metadata"
|
||||
metadataImgTag := "latest"
|
||||
metadataImgTag := LatestTag
|
||||
targetsRepo := regAddr.Host + "/tuf-targets"
|
||||
targetFile := "test.txt"
|
||||
delegatedRole := "test-role"
|
||||
delegatedRole := testRole
|
||||
dir := CreateTempDir(t, "", "tuf_temp")
|
||||
delegatedDir := CreateTempDir(t, dir, delegatedRole)
|
||||
delegatedTargetFile := fmt.Sprintf("%s/%s", delegatedRole, targetFile)
|
||||
@@ -126,11 +128,11 @@ func TestFindFileInManifest(t *testing.T) {
|
||||
img = mutate.ConfigMediaType(img, types.OCIConfigJSON)
|
||||
// add test layer
|
||||
name := strings.Join([]string{hash.Hex, file}, ".")
|
||||
ann := map[string]string{TufFileNameAnnotation: name}
|
||||
ann := map[string]string{TUFFileNameAnnotation: name}
|
||||
layer := mutate.Addendum{Layer: static.NewLayer(data, tufTargetMediaType), Annotations: ann}
|
||||
img, err := mutate.Append(img, layer)
|
||||
assert.NoError(t, err)
|
||||
image_manifest, err := img.RawManifest()
|
||||
imageManifest, err := img.RawManifest()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// make test index manifest
|
||||
@@ -141,11 +143,11 @@ func TestFindFileInManifest(t *testing.T) {
|
||||
Add: img,
|
||||
Descriptor: v1.Descriptor{
|
||||
Annotations: map[string]string{
|
||||
TufFileNameAnnotation: name,
|
||||
TUFFileNameAnnotation: name,
|
||||
},
|
||||
},
|
||||
})
|
||||
index_manifest, err := idx.RawManifest()
|
||||
indexManifest, err := idx.RawManifest()
|
||||
assert.NoError(t, err)
|
||||
// cache image layer
|
||||
targetsRepo := "test/tuf-targets"
|
||||
@@ -155,7 +157,7 @@ func TestFindFileInManifest(t *testing.T) {
|
||||
}
|
||||
imgHash, err := img.Digest()
|
||||
assert.NoError(t, err)
|
||||
d.cache.Put(fmt.Sprintf("%s@%s", targetsRepo, imgHash.String()), image_manifest)
|
||||
d.cache.Put(fmt.Sprintf("%s@%s", targetsRepo, imgHash.String()), imageManifest)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -163,9 +165,9 @@ func TestFindFileInManifest(t *testing.T) {
|
||||
file string
|
||||
expected string
|
||||
}{
|
||||
{"consistent filename image", image_manifest, fmt.Sprintf("%s.%s", hash.Hex, file), hash.Hex},
|
||||
{"filename image", image_manifest, file, ""},
|
||||
{"consistent filename index", index_manifest, fmt.Sprintf("%s.%s", hash.Hex, file), hash.Hex},
|
||||
{"consistent filename image", imageManifest, fmt.Sprintf("%s.%s", hash.Hex, file), hash.Hex},
|
||||
{"filename image", imageManifest, file, ""},
|
||||
{"consistent filename index", indexManifest, fmt.Sprintf("%s.%s", hash.Hex, file), hash.Hex},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
@@ -182,9 +184,9 @@ func TestFindFileInManifest(t *testing.T) {
|
||||
|
||||
func TestParseImgRef(t *testing.T) {
|
||||
metadataRepo := "test/tuf-metadata"
|
||||
metadataTag := "latest"
|
||||
metadataTag := LatestTag
|
||||
targetsRepo := "test/tuf-targets"
|
||||
delegatedRole := "test-role"
|
||||
delegatedRole := testRole
|
||||
testCases := []struct {
|
||||
name string
|
||||
ref string
|
||||
@@ -200,7 +202,7 @@ func TestParseImgRef(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
d := &RegistryFetcher{
|
||||
metadataRepo: metadataRepo,
|
||||
metadataTag: "latest",
|
||||
metadataTag: LatestTag,
|
||||
targetsRepo: targetsRepo,
|
||||
}
|
||||
imgRef, file, err := d.parseImgRef(tc.ref)
|
||||
@@ -246,7 +248,7 @@ func TestPullFileLayer(t *testing.T) {
|
||||
}()
|
||||
|
||||
// make test layer
|
||||
repo := "tuf-metadata"
|
||||
repo := tufMetadataRepo
|
||||
data := []byte("test")
|
||||
testLayer := static.NewLayer(data, tufTargetMediaType)
|
||||
hash, err := testLayer.Digest()
|
||||
@@ -303,7 +305,7 @@ func TestGetManifest(t *testing.T) {
|
||||
}()
|
||||
|
||||
// make test manifest
|
||||
repo := "tuf-metadata"
|
||||
repo := tufMetadataRepo
|
||||
img := empty.Image
|
||||
img = mutate.MediaType(img, types.OCIManifestSchema1)
|
||||
img = mutate.ConfigMediaType(img, types.OCIConfigJSON)
|
||||
@@ -339,7 +341,7 @@ func TestGetManifest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// RunTestRegistry starts a registry testcontainer for TUF on OCI testdata
|
||||
// RunTestRegistry starts a registry testcontainer for TUF on OCI testdata.
|
||||
func RunTestRegistry(t *testing.T) (*registry.RegistryContainer, *url.URL) {
|
||||
registryContainer, err := registry.Run(context.Background(), "registry:2.8.3")
|
||||
if err != nil {
|
||||
@@ -359,22 +361,21 @@ func RunTestRegistry(t *testing.T) (*registry.RegistryContainer, *url.URL) {
|
||||
return registryContainer, addr
|
||||
}
|
||||
|
||||
// LoadRegistryTestData pushes TUF metadata and targets to an OCI registry
|
||||
// LoadRegistryTestData pushes TUF metadata and targets to an OCI registry.
|
||||
func LoadRegistryTestData(t *testing.T, registry *url.URL, path string) {
|
||||
// push tuf metadata and targets to local registry
|
||||
METADATA_REPO := "tuf-metadata"
|
||||
METADATA_TAG := "latest"
|
||||
TARGETS_REPO := "tuf-targets"
|
||||
DELEGATED_ROLE := "test-role"
|
||||
MetadataRepo := tufMetadataRepo
|
||||
TargetsRepo := "tuf-targets"
|
||||
DelegatedRole := testRole
|
||||
|
||||
// push top-level metadata -> metadata:latest
|
||||
err := LoadMetadata(filepath.Join(path, "metadata"), registry.Host, METADATA_REPO, METADATA_TAG)
|
||||
err := LoadMetadata(filepath.Join(path, "metadata"), registry.Host, MetadataRepo, LatestTag)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// push delegated metadata -> metadata:<DELEGATED_ROLE>
|
||||
err = LoadMetadata(filepath.Join(path, "metadata", DELEGATED_ROLE), registry.Host, METADATA_REPO, DELEGATED_ROLE)
|
||||
err = LoadMetadata(filepath.Join(path, "metadata", DelegatedRole), registry.Host, MetadataRepo, DelegatedRole)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -392,7 +393,7 @@ func LoadRegistryTestData(t *testing.T, registry *url.URL, path string) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ref, err := name.ParseReference(fmt.Sprintf("%s/%s:%s", registry.Host, TARGETS_REPO, dir.Name()))
|
||||
ref, err := name.ParseReference(fmt.Sprintf("%s/%s:%s", registry.Host, TargetsRepo, dir.Name()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -400,7 +401,8 @@ func LoadRegistryTestData(t *testing.T, registry *url.URL, path string) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(mf.Manifests) == 1 {
|
||||
switch len(mf.Manifests) {
|
||||
case 1:
|
||||
// top-level target
|
||||
img, err := tIdx.Image(mf.Manifests[0].Digest)
|
||||
if err != nil {
|
||||
@@ -410,19 +412,19 @@ func LoadRegistryTestData(t *testing.T, registry *url.URL, path string) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
} else if len(mf.Manifests) > 1 {
|
||||
case 2:
|
||||
// delegated target
|
||||
err = remote.WriteIndex(ref, tIdx, oci.MultiKeychainOption())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
t.Fatal("no manifests found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LoadMetadata loads TUF metadata from a local path and pushes to a registry
|
||||
// LoadMetadata loads TUF metadata from a local path and pushes to a registry.
|
||||
func LoadMetadata(path, host, repo, tag string) error {
|
||||
mIdx, err := layout.ImageIndexFromPath(path)
|
||||
if err != nil {
|
||||
|
||||
@@ -20,36 +20,37 @@ import (
|
||||
"github.com/theupdateframework/go-tuf/v2/metadata/updater"
|
||||
)
|
||||
|
||||
type TufSource string
|
||||
type Source string
|
||||
|
||||
const (
|
||||
HttpSource TufSource = "http"
|
||||
OciSource TufSource = "oci"
|
||||
HTTPSource Source = "http"
|
||||
OCISource Source = "oci"
|
||||
LatestTag string = "latest"
|
||||
)
|
||||
|
||||
var (
|
||||
DockerTufRootProd = embed.RootProd
|
||||
DockerTufRootStaging = embed.RootStaging
|
||||
DockerTufRootDev = embed.RootDev
|
||||
DockerTufRootDefault = embed.RootDefault
|
||||
DockerTUFRootProd = embed.RootProd
|
||||
DockerTUFRootStaging = embed.RootStaging
|
||||
DockerTUFRootDev = embed.RootDev
|
||||
DockerTUFRootDefault = embed.RootDefault
|
||||
)
|
||||
|
||||
type TUFClient interface {
|
||||
type Downloader interface {
|
||||
DownloadTarget(target, filePath string) (actualFilePath string, data []byte, err error)
|
||||
}
|
||||
|
||||
type TufClient struct {
|
||||
type Client struct {
|
||||
updater *updater.Updater
|
||||
cfg *config.UpdaterConfig
|
||||
}
|
||||
|
||||
// NewTufClient creates a new TUF client
|
||||
func NewTufClient(initialRoot []byte, tufPath, metadataSource, targetsSource string, versionChecker VersionChecker) (*TufClient, error) {
|
||||
var tufSource TufSource
|
||||
// NewClient creates a new TUF client.
|
||||
func NewClient(initialRoot []byte, tufPath, metadataSource, targetsSource string, versionChecker VersionChecker) (*Client, error) {
|
||||
var tufSource Source
|
||||
if strings.HasPrefix(metadataSource, "https://") || strings.HasPrefix(metadataSource, "http://") {
|
||||
tufSource = HttpSource
|
||||
tufSource = HTTPSource
|
||||
} else {
|
||||
tufSource = OciSource
|
||||
tufSource = OCISource
|
||||
}
|
||||
|
||||
tufRootDigest := util.SHA256Hex(initialRoot)
|
||||
@@ -84,11 +85,11 @@ func NewTufClient(initialRoot []byte, tufPath, metadataSource, targetsSource str
|
||||
cfg.LocalTargetsDir = filepath.Join(metadataPath, "download")
|
||||
cfg.RemoteTargetsURL = targetsSource
|
||||
|
||||
if tufSource == OciSource {
|
||||
if tufSource == OCISource {
|
||||
metadataRepo, metadataTag, found := strings.Cut(metadataSource, ":")
|
||||
if !found {
|
||||
fmt.Printf("metadata tag not found in URL, using latest\n")
|
||||
metadataTag = "latest"
|
||||
metadataTag = LatestTag
|
||||
}
|
||||
cfg.Fetcher = NewRegistryFetcher(metadataRepo, metadataTag, targetsSource)
|
||||
}
|
||||
@@ -105,7 +106,7 @@ func NewTufClient(initialRoot []byte, tufPath, metadataSource, targetsSource str
|
||||
return nil, fmt.Errorf("failed to refresh trusted metadata: %w", err)
|
||||
}
|
||||
|
||||
client := &TufClient{
|
||||
client := &Client{
|
||||
updater: up,
|
||||
cfg: cfg,
|
||||
}
|
||||
@@ -121,7 +122,7 @@ func NewTufClient(initialRoot []byte, tufPath, metadataSource, targetsSource str
|
||||
// DownloadTarget downloads the target file using Updater. The Updater gets the target
|
||||
// information, verifies if the target is already cached, and if it is not cached,
|
||||
// downloads the target file.
|
||||
func (t *TufClient) DownloadTarget(target string, filePath string) (actualFilePath string, data []byte, err error) {
|
||||
func (t *Client) DownloadTarget(target string, filePath string) (actualFilePath string, data []byte, err error) {
|
||||
// search if the desired target is available
|
||||
targetInfo, err := t.updater.GetTargetInfo(target)
|
||||
if err != nil {
|
||||
@@ -154,15 +155,15 @@ func (t *TufClient) DownloadTarget(target string, filePath string) (actualFilePa
|
||||
return actualFilePath, data, err
|
||||
}
|
||||
|
||||
func (t *TufClient) GetMetadata() trustedmetadata.TrustedMetadata {
|
||||
func (t *Client) GetMetadata() trustedmetadata.TrustedMetadata {
|
||||
return t.updater.GetTrustedMetadataSet()
|
||||
}
|
||||
|
||||
func (t *TufClient) MaxRootLength() int64 {
|
||||
func (t *Client) MaxRootLength() int64 {
|
||||
return t.cfg.RootMaxLength
|
||||
}
|
||||
|
||||
func (t *TufClient) GetPriorRoots(metadataURL string) (map[string][]byte, error) {
|
||||
func (t *Client) GetPriorRoots(metadataURL string) (map[string][]byte, error) {
|
||||
rootMetadata := map[string][]byte{}
|
||||
trustedMetadata := t.GetMetadata()
|
||||
client := fetcher.DefaultFetcher{}
|
||||
@@ -176,12 +177,12 @@ func (t *TufClient) GetPriorRoots(metadataURL string) (map[string][]byte, error)
|
||||
return rootMetadata, nil
|
||||
}
|
||||
|
||||
func (t *TufClient) SetRemoteTargetsURL(url string) {
|
||||
func (t *Client) SetRemoteTargetsURL(url string) {
|
||||
t.cfg.RemoteTargetsURL = url
|
||||
}
|
||||
|
||||
// Derived from updater.loadTargets() in theupdateframework/go-tuf
|
||||
func (t *TufClient) LoadDelegatedTargets(roleName, parentName string) (*metadata.Metadata[metadata.TargetsType], error) {
|
||||
// Derived from updater.loadTargets() in theupdateframework/go-tuf.
|
||||
func (t *Client) LoadDelegatedTargets(roleName, parentName string) (*metadata.Metadata[metadata.TargetsType], error) {
|
||||
// extract the targets meta from the trusted snapshot metadata
|
||||
meta := t.updater.GetTrustedMetadataSet()
|
||||
metaInfo := meta.Snapshot.Signed.Meta[fmt.Sprintf("%s.json", roleName)]
|
||||
@@ -208,8 +209,8 @@ func (t *TufClient) LoadDelegatedTargets(roleName, parentName string) (*metadata
|
||||
return delegatedTargets, nil
|
||||
}
|
||||
|
||||
// downloadMetadata download a metadata file and return it as bytes
|
||||
func (t *TufClient) downloadMetadata(roleName string, length int64, version string) ([]byte, error) {
|
||||
// downloadMetadata download a metadata file and return it as bytes.
|
||||
func (t *Client) downloadMetadata(roleName string, length int64, version string) ([]byte, error) {
|
||||
urlPath := ensureTrailingSlash(t.cfg.RemoteMetadataURL)
|
||||
// build urlPath
|
||||
if version == "" {
|
||||
@@ -220,7 +221,7 @@ func (t *TufClient) downloadMetadata(roleName string, length int64, version stri
|
||||
return t.cfg.Fetcher.DownloadFile(urlPath, length, time.Second*15)
|
||||
}
|
||||
|
||||
// ensureTrailingSlash ensures url ends with a slash
|
||||
// ensureTrailingSlash ensures url ends with a slash.
|
||||
func ensureTrailingSlash(url string) string {
|
||||
if updater.IsWindowsPath(url) {
|
||||
slash := string(filepath.Separator)
|
||||
@@ -235,7 +236,7 @@ func ensureTrailingSlash(url string) string {
|
||||
return url + "/"
|
||||
}
|
||||
|
||||
// GetEmbeddedTufRoot returns the embedded TUF root based on the given root name
|
||||
func GetEmbeddedTufRoot(root string) (*embed.EmbeddedRoot, error) {
|
||||
// GetEmbeddedRoot returns the embedded TUF root based on the given root name.
|
||||
func GetEmbeddedRoot(root string) (*embed.EmbeddedRoot, error) {
|
||||
return embed.GetRootFromName(root)
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
HttpTufTestDataPath = filepath.Join("..", "..", "test", "testdata", "tuf", "test-repo")
|
||||
OciTufTestDataPath = filepath.Join("..", "..", "test", "testdata", "tuf", "test-repo-oci")
|
||||
HTTPTUFTestDataPath = filepath.Join("..", "..", "test", "testdata", "tuf", "test-repo")
|
||||
OCITUFTestDataPath = filepath.Join("..", "..", "test", "testdata", "tuf", "test-repo-oci")
|
||||
)
|
||||
|
||||
func CreateTempDir(t *testing.T, dir, pattern string) string {
|
||||
@@ -35,12 +35,12 @@ func CreateTempDir(t *testing.T, dir, pattern string) string {
|
||||
return tempDir
|
||||
}
|
||||
|
||||
// NewTufClient creates a new TUF client
|
||||
// NewTufClient creates a new TUF client.
|
||||
func TestRootInit(t *testing.T) {
|
||||
tufPath := CreateTempDir(t, "", "tuf_temp")
|
||||
|
||||
// Start a test HTTP server to serve data from /test/testdata/tuf/test-repo/ paths
|
||||
server := httptest.NewServer(http.FileServer(http.Dir(HttpTufTestDataPath)))
|
||||
server := httptest.NewServer(http.FileServer(http.Dir(HTTPTUFTestDataPath)))
|
||||
defer server.Close()
|
||||
|
||||
// run local registry
|
||||
@@ -50,10 +50,10 @@ func TestRootInit(t *testing.T) {
|
||||
t.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
|
||||
}
|
||||
}()
|
||||
LoadRegistryTestData(t, regAddr, OciTufTestDataPath)
|
||||
LoadRegistryTestData(t, regAddr, OCITUFTestDataPath)
|
||||
|
||||
alwaysGoodVersionChecker := &mockVersionChecker{err: nil}
|
||||
alwaysBadVersionChecker := &mockVersionChecker{err: assert.AnError}
|
||||
alwaysGoodVersionChecker := &MockVersionChecker{err: nil}
|
||||
alwaysBadVersionChecker := &MockVersionChecker{err: assert.AnError}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -65,17 +65,17 @@ func TestRootInit(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
_, err := NewTufClient(embed.RootDev.Data, tufPath, tc.metadataSource, tc.targetsSource, alwaysGoodVersionChecker)
|
||||
_, err := NewClient(embed.RootDev.Data, tufPath, tc.metadataSource, tc.targetsSource, alwaysGoodVersionChecker)
|
||||
assert.NoErrorf(t, err, "Failed to create TUF client: %v", err)
|
||||
|
||||
// recreation should work with same root
|
||||
_, err = NewTufClient(embed.RootDev.Data, tufPath, tc.metadataSource, tc.targetsSource, alwaysGoodVersionChecker)
|
||||
_, err = NewClient(embed.RootDev.Data, tufPath, tc.metadataSource, tc.targetsSource, alwaysGoodVersionChecker)
|
||||
assert.NoErrorf(t, err, "Failed to recreate TUF client: %v", err)
|
||||
|
||||
_, err = NewTufClient([]byte("broken"), tufPath, tc.metadataSource, tc.targetsSource, alwaysGoodVersionChecker)
|
||||
_, err = NewClient([]byte("broken"), tufPath, tc.metadataSource, tc.targetsSource, alwaysGoodVersionChecker)
|
||||
assert.Errorf(t, err, "Expected error recreating TUF client with broken root: %v", err)
|
||||
|
||||
_, err = NewTufClient(embed.RootDev.Data, tufPath, tc.metadataSource, tc.targetsSource, alwaysBadVersionChecker)
|
||||
_, err = NewClient(embed.RootDev.Data, tufPath, tc.metadataSource, tc.targetsSource, alwaysBadVersionChecker)
|
||||
assert.Errorf(t, err, "Expected error creating TUF client with bad attest version: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -83,11 +83,11 @@ func TestRootInit(t *testing.T) {
|
||||
func TestDownloadTarget(t *testing.T) {
|
||||
tufPath := CreateTempDir(t, "", "tuf_temp")
|
||||
targetFile := "test.txt"
|
||||
delegatedRole := "test-role"
|
||||
delegatedRole := testRole
|
||||
delegatedTargetFile := fmt.Sprintf("%s/%s", delegatedRole, targetFile)
|
||||
|
||||
// Start a test HTTP server to serve data from /test/testdata/tuf/test-repo/ paths
|
||||
server := httptest.NewServer(http.FileServer(http.Dir(HttpTufTestDataPath)))
|
||||
server := httptest.NewServer(http.FileServer(http.Dir(HTTPTUFTestDataPath)))
|
||||
defer server.Close()
|
||||
|
||||
// run local registry
|
||||
@@ -97,9 +97,9 @@ func TestDownloadTarget(t *testing.T) {
|
||||
t.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
|
||||
}
|
||||
}()
|
||||
LoadRegistryTestData(t, regAddr, OciTufTestDataPath)
|
||||
LoadRegistryTestData(t, regAddr, OCITUFTestDataPath)
|
||||
|
||||
alwaysGoodVersionChecker := &mockVersionChecker{err: nil}
|
||||
alwaysGoodVersionChecker := &MockVersionChecker{err: nil}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -111,7 +111,7 @@ func TestDownloadTarget(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tufClient, err := NewTufClient(embed.RootDev.Data, tufPath, tc.metadataSource, tc.targetsSource, alwaysGoodVersionChecker)
|
||||
tufClient, err := NewClient(embed.RootDev.Data, tufPath, tc.metadataSource, tc.targetsSource, alwaysGoodVersionChecker)
|
||||
assert.NoErrorf(t, err, "Failed to create TUF client: %v", err)
|
||||
|
||||
// get trusted tuf metadata
|
||||
@@ -135,22 +135,22 @@ func TestDownloadTarget(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetEmbeddedTufRootBytes(t *testing.T) {
|
||||
dev, err := GetEmbeddedTufRoot("dev")
|
||||
dev, err := GetEmbeddedRoot("dev")
|
||||
assert.NoError(t, err)
|
||||
|
||||
staging, err := GetEmbeddedTufRoot("staging")
|
||||
staging, err := GetEmbeddedRoot("staging")
|
||||
assert.NoError(t, err)
|
||||
assert.NotEqual(t, dev.Data, staging.Data)
|
||||
|
||||
prod, err := GetEmbeddedTufRoot("prod")
|
||||
prod, err := GetEmbeddedRoot("prod")
|
||||
assert.NoError(t, err)
|
||||
assert.NotEqual(t, dev.Data, prod.Data)
|
||||
assert.NotEqual(t, staging.Data, prod.Data)
|
||||
|
||||
def, err := GetEmbeddedTufRoot("")
|
||||
def, err := GetEmbeddedRoot("")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, def.Data, prod.Data)
|
||||
|
||||
_, err = GetEmbeddedTufRoot("invalid")
|
||||
_, err = GetEmbeddedRoot("invalid")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ const ThisModulePath = "github.com/docker/attest"
|
||||
|
||||
type VersionChecker interface {
|
||||
// CheckVersion checks if the current version of this library meets the constraints from the TUF repo
|
||||
CheckVersion(tufClient TUFClient) error
|
||||
CheckVersion(tufClient Downloader) error
|
||||
}
|
||||
|
||||
type InvalidVersionError struct {
|
||||
@@ -32,13 +32,13 @@ func (e *InvalidVersionError) Error() string {
|
||||
return fmt.Sprintf("%s version %s does not satisfy constraints %s: %s", ThisModulePath, e.AttestVersion, e.VersionConstraint, errsStr.String())
|
||||
}
|
||||
|
||||
func NewVersionChecker() *versionChecker {
|
||||
return &versionChecker{}
|
||||
func NewDefaultVersionChecker() *DefaultVersionChecker {
|
||||
return &DefaultVersionChecker{}
|
||||
}
|
||||
|
||||
type versionChecker struct{}
|
||||
type DefaultVersionChecker struct{}
|
||||
|
||||
func (vc *versionChecker) CheckVersion(client TUFClient) error {
|
||||
func (vc *DefaultVersionChecker) CheckVersion(client Downloader) error {
|
||||
var attestMod *debug.Module
|
||||
bi, ok := debug.ReadBuildInfo()
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user