...

Source file src/edge-infra.dev/pkg/f8n/warehouse/packagelock/inspect.go

Documentation: edge-infra.dev/pkg/f8n/warehouse/packagelock

     1  package packagelock
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/go-logr/logr"
     8  	"github.com/google/go-containerregistry/pkg/name"
     9  	"go.uber.org/multierr"
    10  
    11  	"github.com/google/go-containerregistry/pkg/authn"
    12  	"github.com/google/go-containerregistry/pkg/v1/google"
    13  	gremote "github.com/google/go-containerregistry/pkg/v1/remote"
    14  
    15  	"edge-infra.dev/pkg/f8n/warehouse"
    16  	"edge-infra.dev/pkg/f8n/warehouse/oci"
    17  	"edge-infra.dev/pkg/f8n/warehouse/oci/remote"
    18  )
    19  
    20  func InspectPackageLock(ctx context.Context, log logr.Logger, plf PackageLock, location string, project string, repository string) error {
    21  	var expectationErrs []error
    22  	keychain := authn.NewMultiKeychain(
    23  		google.Keychain,
    24  		authn.DefaultKeychain,
    25  	)
    26  	for _, pkg := range plf.Packages {
    27  		log.Info(fmt.Sprintf("validating %s", pkg.Name))
    28  		for _, ver := range pkg.Versions {
    29  			digestRef := fmt.Sprintf("%s-docker.pkg.dev/%s/%s/%s@%s", location, project, repository, pkg.Name, ver.Digest)
    30  			ref, err := name.ParseReference(digestRef)
    31  			if err != nil {
    32  				return err
    33  			}
    34  			digestArtifact, err := remote.Get(ref,
    35  				[]remote.Option{
    36  					remote.WithContext(ctx),
    37  					gremote.WithAuthFromKeychain(keychain),
    38  				}...,
    39  			)
    40  			if err != nil {
    41  				return err
    42  			}
    43  			digestAnnos, err := oci.Annotations(digestArtifact)
    44  			if err != nil {
    45  				return err
    46  			}
    47  
    48  			expectedVersion, found := digestAnnos[warehouse.AnnotationVersion]
    49  			if !found {
    50  				err := fmt.Errorf("no version annotation found for pkg %s@%s", pkg.Name, ver.Digest)
    51  				expectationErrs = append(expectationErrs, err)
    52  				continue
    53  			}
    54  
    55  			if tagErrors := validateTagAnnotations(location, project, repository, pkg.Name, expectedVersion, ver.Tags); tagErrors != nil {
    56  				expectationErrs = append(expectationErrs, tagErrors)
    57  				continue
    58  			}
    59  		}
    60  	}
    61  	if err := multierr.Combine(expectationErrs...); err != nil {
    62  		return fmt.Errorf("all pkg versions must be the same. one or more differ: %+v", err)
    63  	}
    64  	return nil
    65  }
    66  
    67  func validateTagAnnotations(location string, project string, repository string, pkgName string, expectedVersion string, tags []string) error {
    68  	var tagErrors []error
    69  	for _, tag := range tags {
    70  		if tag == "latest" {
    71  			continue
    72  		}
    73  		tagRef := fmt.Sprintf("%s-docker.pkg.dev/%s/%s/%s:%s", location, project, repository, pkgName, tag)
    74  		ref, err := name.ParseReference(tagRef)
    75  		if err != nil {
    76  			tagErrors = append(tagErrors, err)
    77  			continue
    78  		}
    79  		tagArtifact, err := remote.Get(ref)
    80  		if err != nil {
    81  			tagErrors = append(tagErrors, err)
    82  			continue
    83  		}
    84  		tagAnnos, err := oci.Annotations(tagArtifact)
    85  		if err != nil {
    86  			tagErrors = append(tagErrors, err)
    87  			continue
    88  		}
    89  
    90  		tagVersion, found := tagAnnos[warehouse.AnnotationVersion]
    91  		if !found {
    92  			tagErrors = append(tagErrors, fmt.Errorf("tag %s did not contain a version annotation", tag))
    93  			continue
    94  		}
    95  
    96  		if tagVersion != expectedVersion {
    97  			tagErrors = append(tagErrors, fmt.Errorf("tag %s version annotation %s did not match expected version %s", tag, tagVersion, expectedVersion))
    98  			continue
    99  		}
   100  	}
   101  	if err := multierr.Combine(tagErrors...); err != nil {
   102  		return fmt.Errorf("one or more tag versions did not match digest annotation version: %w", err)
   103  	}
   104  	return nil
   105  }
   106  

View as plain text