versionsapi: replace shortname pkg

Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
This commit is contained in:
Paul Meyer 2023-01-05 15:52:57 +01:00
parent f17b40b44a
commit 66f2c446a4
6 changed files with 27 additions and 168 deletions

View File

@ -20,8 +20,8 @@ import (
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/shortname"
"github.com/edgelesssys/constellation/v2/internal/sigstore"
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)
@ -187,14 +187,15 @@ func (f *fetchMeasurementsFlags) updateURLs(conf *config.Config) error {
}
func measurementURL(provider cloudprovider.Provider, image, file string) (*url.URL, error) {
ref, stream, version, err := shortname.ToParts(image)
ver, err := versionsapi.NewVersionFromShortPath(image, versionsapi.VersionKindImage)
if err != nil {
return nil, fmt.Errorf("parsing image name: %w", err)
return nil, fmt.Errorf("creating version from image name: %w", err)
}
url, err := url.Parse(constants.CDNRepositoryURL)
artifactBaseURL := ver.ArtifactURL()
url, err := url.Parse(artifactBaseURL)
if err != nil {
return nil, fmt.Errorf("parsing image version repository URL: %w", err)
return nil, fmt.Errorf("parsing artifact base URL %s: %w", artifactBaseURL, err)
}
url.Path = path.Join(constants.CDNAPIPrefix, "ref", ref, "stream", stream, version, "image", "csp", strings.ToLower(provider.String()), file)
url.Path = path.Join(url.Path, "image", "csp", strings.ToLower(provider.String()), file)
return url, nil
}

View File

@ -20,6 +20,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -96,6 +97,12 @@ func TestParseFetchMeasurementsFlags(t *testing.T) {
}
func TestUpdateURLs(t *testing.T) {
ver := versionsapi.Version{
Ref: "foo",
Stream: "nightly",
Version: "v7.7.7",
Kind: versionsapi.VersionKindImage,
}
testCases := map[string]struct {
conf *config.Config
flags *fetchMeasurementsFlags
@ -104,14 +111,14 @@ func TestUpdateURLs(t *testing.T) {
}{
"both values nil": {
conf: &config.Config{
Image: "someImageVersion",
Image: ver.ShortPath(),
Provider: config.ProviderConfig{
GCP: &config.GCPConfig{},
},
},
flags: &fetchMeasurementsFlags{},
wantMeasurementsURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/-/stream/stable/someImageVersion/image/csp/gcp/measurements.json",
wantMeasurementsSigURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/-/stream/stable/someImageVersion/image/csp/gcp/measurements.json.sig",
wantMeasurementsURL: ver.ArtifactURL() + "/image/csp/gcp/measurements.json",
wantMeasurementsSigURL: ver.ArtifactURL() + "/image/csp/gcp/measurements.json.sig",
},
"both set by user": {
conf: &config.Config{},

View File

@ -1,55 +0,0 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package shortname
import (
"fmt"
"strings"
)
// ToParts splits an config shortname into its parts.
// The shortname is expected to be in the format of one of:
// ref/<ref>/stream/<stream>/<version>
// stream/<stream>/<version>
// version/<version>.
func ToParts(shortname string) (string, string, string, error) {
parts := strings.Split(shortname, "/")
ref := "-"
stream := "stable"
var version string
switch len(parts) {
case 1:
version = parts[0]
case 3:
if parts[0] != "stream" {
return "", "", "", fmt.Errorf("invalid shortname: expected \"stream/<stream>/<version>\", got %q", shortname)
}
stream = parts[1]
version = parts[2]
case 5:
if parts[0] != "ref" || parts[2] != "stream" {
return "", "", "", fmt.Errorf("invalid shortname: expected \"ref/<ref>/stream/<stream>/<version>\", got %q", shortname)
}
ref = parts[1]
stream = parts[3]
version = parts[4]
default:
return "", "", "", fmt.Errorf("invalid shortname reference %q", shortname)
}
return ref, stream, version, nil
}
// FromParts joins the parts of a config shortname into a shortname.
func FromParts(ref, stream, version string) string {
switch {
case ref == "-" && stream == "stable":
return version
case ref == "-":
return "stream/" + stream + "/" + version
}
return "ref/" + ref + "/stream/" + stream + "/" + version
}

View File

@ -1,102 +0,0 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package shortname
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
)
func TestMain(m *testing.M) {
goleak.VerifyTestMain(m)
}
func TestToParts(t *testing.T) {
testCases := map[string]struct {
shortname string
wantParts [3]string
wantErr bool
}{
"only version": {
shortname: "v1.2.3",
wantParts: [3]string{"-", "stable", "v1.2.3"},
},
"stream and version": {
shortname: "stream/nightly/v1.2.3",
wantParts: [3]string{"-", "nightly", "v1.2.3"},
},
"full name": {
shortname: "ref/feat-xyz/stream/nightly/v1.2.3",
wantParts: [3]string{"feat-xyz", "nightly", "v1.2.3"},
},
"full name with extra slashes": {
shortname: "ref/feat-xyz//stream/nightly/v1.2.3",
wantErr: true,
},
"invalid three part path": {
shortname: "invalid/invalid/invalid",
wantErr: true,
},
"five part path": {
shortname: "invalid/invalid/invalid/invalid/invalid",
wantErr: true,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
ref, stream, version, err := ToParts(tc.shortname)
if tc.wantErr {
assert.Error(err)
return
}
require.NoError(err)
assert.Equal(tc.wantParts, [3]string{ref, stream, version})
})
}
}
func TestFromParts(t *testing.T) {
testCases := map[string]struct {
ref, stream, version string
wantShortname string
}{
"only version": {
ref: "-",
stream: "stable",
version: "v1.2.3",
wantShortname: "v1.2.3",
},
"stream and version": {
ref: "-",
stream: "nightly",
version: "v1.2.3",
wantShortname: "stream/nightly/v1.2.3",
},
"full name": {
ref: "feat-xyz",
stream: "nightly",
version: "v1.2.3",
wantShortname: "ref/feat-xyz/stream/nightly/v1.2.3",
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
gotShortname := FromParts(tc.ref, tc.stream, tc.version)
assert.Equal(tc.wantShortname, gotShortname)
})
}
}

View File

@ -143,8 +143,14 @@ func (v Version) ListPath(gran Granularity) string {
)
}
// ArtifactURL returns the URL to the artifacts stored for this version.
// The URL points to a directory.
func (v Version) ArtifactURL() string {
return constants.CDNRepositoryURL + "/" + v.ArtifactPath()
}
// ArtifactPath returns the path to the artifacts stored for this version.
// The path points to a directory and is intended to be used for deletion.
// The path points to a directory.
func (v Version) ArtifactPath() string {
return path.Join(
constants.CDNAPIPrefix,

View File

@ -373,7 +373,7 @@ func TestVersionListPathURL(t *testing.T) {
}
}
func TestVersionArtifactPath(t *testing.T) {
func TestVersionArtifactPathURL(t *testing.T) {
testCases := map[string]struct {
ver Version
wantPath string
@ -413,6 +413,8 @@ func TestVersionArtifactPath(t *testing.T) {
path := tc.ver.ArtifactPath()
assert.Equal(tc.wantPath, path)
url := tc.ver.ArtifactURL()
assert.Equal(constants.CDNRepositoryURL+"/"+tc.wantPath, url)
})
}
}