mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-10-01 01:36:09 -04:00
Move upload/delete code to its own package
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
5654e76f7e
commit
52a65c20ac
@ -5,31 +5,23 @@ go_library(
|
||||
name = "attestationconfigapi",
|
||||
srcs = [
|
||||
"attestationconfigapi.go",
|
||||
"client.go",
|
||||
"fetcher.go",
|
||||
"reporter.go",
|
||||
"snp.go",
|
||||
],
|
||||
importpath = "github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/api/client",
|
||||
"//internal/api/fetcher",
|
||||
"//internal/attestation/variant",
|
||||
"//internal/constants",
|
||||
"//internal/sigstore",
|
||||
"//internal/staticupload",
|
||||
"@com_github_aws_aws_sdk_go//aws",
|
||||
"@com_github_aws_aws_sdk_go_v2_service_s3//:s3",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "attestationconfigapi_test",
|
||||
srcs = [
|
||||
"client_test.go",
|
||||
"fetcher_test.go",
|
||||
"reporter_test.go",
|
||||
"snp_test.go",
|
||||
],
|
||||
embed = [":attestationconfigapi"],
|
||||
|
@ -19,6 +19,7 @@ go_library(
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//internal/api/attestationconfigapi",
|
||||
"//internal/api/attestationconfigapi/cli/client",
|
||||
"//internal/attestation/variant",
|
||||
"//internal/cloud/cloudprovider",
|
||||
"//internal/constants",
|
||||
|
35
internal/api/attestationconfigapi/cli/client/BUILD.bazel
Normal file
35
internal/api/attestationconfigapi/cli/client/BUILD.bazel
Normal file
@ -0,0 +1,35 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("//bazel/go:go_test.bzl", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "client",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"reporter.go",
|
||||
],
|
||||
importpath = "github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi/cli/client",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/api/attestationconfigapi",
|
||||
"//internal/api/client",
|
||||
"//internal/attestation/variant",
|
||||
"//internal/sigstore",
|
||||
"//internal/staticupload",
|
||||
"@com_github_aws_aws_sdk_go//aws",
|
||||
"@com_github_aws_aws_sdk_go_v2_service_s3//:s3",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "client_test",
|
||||
srcs = [
|
||||
"client_test.go",
|
||||
"reporter_test.go",
|
||||
],
|
||||
embed = [":client"],
|
||||
deps = [
|
||||
"//internal/api/attestationconfigapi",
|
||||
"//internal/attestation/variant",
|
||||
"@com_github_stretchr_testify//assert",
|
||||
],
|
||||
)
|
@ -3,7 +3,12 @@ Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
package attestationconfigapi
|
||||
|
||||
/*
|
||||
package client contains code to manage CVM versions in Constellation's CDN API.
|
||||
It is used to upload and delete "latest" versions for AMD SEV-SNP and Intel TDX.
|
||||
*/
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -12,6 +17,7 @@ import (
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
apiclient "github.com/edgelesssys/constellation/v2/internal/api/client"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
||||
"github.com/edgelesssys/constellation/v2/internal/sigstore"
|
||||
@ -31,8 +37,8 @@ type Client struct {
|
||||
cacheWindowSize int
|
||||
}
|
||||
|
||||
// NewClient returns a new Client.
|
||||
func NewClient(ctx context.Context, cfg staticupload.Config, cosignPwd, privateKey []byte, dryRun bool, versionWindowSize int, log *slog.Logger) (*Client, apiclient.CloseFunc, error) {
|
||||
// New returns a new Client.
|
||||
func New(ctx context.Context, cfg staticupload.Config, cosignPwd, privateKey []byte, dryRun bool, versionWindowSize int, log *slog.Logger) (*Client, apiclient.CloseFunc, error) {
|
||||
s3Client, clientClose, err := apiclient.NewClient(ctx, cfg.Region, cfg.Bucket, cfg.DistributionID, dryRun, log)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to create s3 storage: %w", err)
|
||||
@ -49,7 +55,7 @@ func NewClient(ctx context.Context, cfg staticupload.Config, cosignPwd, privateK
|
||||
}
|
||||
|
||||
// uploadSEVSNPVersion uploads the latest version numbers of the SEVSNP. Then version name is the UTC timestamp of the date. The /list entry stores the version name + .json suffix.
|
||||
func (a Client) uploadSEVSNPVersion(ctx context.Context, attestation variant.Variant, version SEVSNPVersion, date time.Time) error {
|
||||
func (a Client) uploadSEVSNPVersion(ctx context.Context, attestation variant.Variant, version attestationconfigapi.SEVSNPVersion, date time.Time) error {
|
||||
versions, err := a.List(ctx, attestation)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fetch version list: %w", err)
|
||||
@ -74,32 +80,32 @@ func (a Client) DeleteSEVSNPVersion(ctx context.Context, attestation variant.Var
|
||||
}
|
||||
|
||||
// List returns the list of versions for the given attestation variant.
|
||||
func (a Client) List(ctx context.Context, attestation variant.Variant) (SEVSNPVersionList, error) {
|
||||
func (a Client) List(ctx context.Context, attestation variant.Variant) (attestationconfigapi.SEVSNPVersionList, error) {
|
||||
if !attestation.Equal(variant.AzureSEVSNP{}) &&
|
||||
!attestation.Equal(variant.AWSSEVSNP{}) &&
|
||||
!attestation.Equal(variant.GCPSEVSNP{}) {
|
||||
return SEVSNPVersionList{}, fmt.Errorf("unsupported attestation variant: %s", attestation)
|
||||
return attestationconfigapi.SEVSNPVersionList{}, fmt.Errorf("unsupported attestation variant: %s", attestation)
|
||||
}
|
||||
|
||||
versions, err := apiclient.Fetch(ctx, a.s3Client, SEVSNPVersionList{variant: attestation})
|
||||
versions, err := apiclient.Fetch(ctx, a.s3Client, attestationconfigapi.SEVSNPVersionList{Variant: attestation})
|
||||
if err != nil {
|
||||
var notFoundErr *apiclient.NotFoundError
|
||||
if errors.As(err, ¬FoundErr) {
|
||||
return SEVSNPVersionList{variant: attestation}, nil
|
||||
return attestationconfigapi.SEVSNPVersionList{Variant: attestation}, nil
|
||||
}
|
||||
return SEVSNPVersionList{}, err
|
||||
return attestationconfigapi.SEVSNPVersionList{}, err
|
||||
}
|
||||
|
||||
versions.variant = attestation
|
||||
versions.Variant = attestation
|
||||
|
||||
return versions, nil
|
||||
}
|
||||
|
||||
func (a Client) deleteSEVSNPVersion(versions SEVSNPVersionList, versionStr string) (ops []crudCmd, err error) {
|
||||
func (a Client) deleteSEVSNPVersion(versions attestationconfigapi.SEVSNPVersionList, versionStr string) (ops []crudCmd, err error) {
|
||||
versionStr = versionStr + ".json"
|
||||
ops = append(ops, deleteCmd{
|
||||
apiObject: SEVSNPVersionAPI{
|
||||
Variant: versions.variant,
|
||||
apiObject: attestationconfigapi.SEVSNPVersionAPI{
|
||||
Variant: versions.Variant,
|
||||
Version: versionStr,
|
||||
},
|
||||
})
|
||||
@ -115,8 +121,8 @@ func (a Client) deleteSEVSNPVersion(versions SEVSNPVersionList, versionStr strin
|
||||
return ops, nil
|
||||
}
|
||||
|
||||
func (a Client) constructUploadCmd(attestation variant.Variant, version SEVSNPVersion, versionNames SEVSNPVersionList, date time.Time) []crudCmd {
|
||||
if !attestation.Equal(versionNames.variant) {
|
||||
func (a Client) constructUploadCmd(attestation variant.Variant, version attestationconfigapi.SEVSNPVersion, versionNames attestationconfigapi.SEVSNPVersionList, date time.Time) []crudCmd {
|
||||
if !attestation.Equal(versionNames.Variant) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -124,11 +130,11 @@ func (a Client) constructUploadCmd(attestation variant.Variant, version SEVSNPVe
|
||||
var res []crudCmd
|
||||
|
||||
res = append(res, putCmd{
|
||||
apiObject: SEVSNPVersionAPI{Version: dateStr, Variant: attestation, SEVSNPVersion: version},
|
||||
apiObject: attestationconfigapi.SEVSNPVersionAPI{Version: dateStr, Variant: attestation, SEVSNPVersion: version},
|
||||
signer: a.signer,
|
||||
})
|
||||
|
||||
versionNames.addVersion(dateStr)
|
||||
versionNames.AddVersion(dateStr)
|
||||
|
||||
res = append(res, putCmd{
|
||||
apiObject: versionNames,
|
||||
@ -138,19 +144,19 @@ func (a Client) constructUploadCmd(attestation variant.Variant, version SEVSNPVe
|
||||
return res
|
||||
}
|
||||
|
||||
func removeVersion(list SEVSNPVersionList, versionStr string) (removedVersions SEVSNPVersionList, err error) {
|
||||
versions := list.List()
|
||||
func removeVersion(list attestationconfigapi.SEVSNPVersionList, versionStr string) (removedVersions attestationconfigapi.SEVSNPVersionList, err error) {
|
||||
versions := list.List
|
||||
for i, v := range versions {
|
||||
if v == versionStr {
|
||||
if i == len(versions)-1 {
|
||||
removedVersions = SEVSNPVersionList{list: versions[:i], variant: list.variant}
|
||||
removedVersions = attestationconfigapi.SEVSNPVersionList{List: versions[:i], Variant: list.Variant}
|
||||
} else {
|
||||
removedVersions = SEVSNPVersionList{list: append(versions[:i], versions[i+1:]...), variant: list.variant}
|
||||
removedVersions = attestationconfigapi.SEVSNPVersionList{List: append(versions[:i], versions[i+1:]...), Variant: list.Variant}
|
||||
}
|
||||
return removedVersions, nil
|
||||
}
|
||||
}
|
||||
return SEVSNPVersionList{}, fmt.Errorf("version %s not found in list %v", versionStr, versions)
|
||||
return attestationconfigapi.SEVSNPVersionList{}, fmt.Errorf("version %s not found in list %v", versionStr, versions)
|
||||
}
|
||||
|
||||
type crudCmd interface {
|
@ -3,12 +3,13 @@ Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
package attestationconfigapi
|
||||
package client
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@ -18,13 +19,13 @@ func TestUploadAzureSEVSNP(t *testing.T) {
|
||||
bucketID: "bucket",
|
||||
signer: fakeSigner{},
|
||||
}
|
||||
version := SEVSNPVersion{}
|
||||
version := attestationconfigapi.SEVSNPVersion{}
|
||||
date := time.Date(2023, 1, 1, 1, 1, 1, 1, time.UTC)
|
||||
ops := sut.constructUploadCmd(variant.AzureSEVSNP{}, version, SEVSNPVersionList{list: []string{"2021-01-01-01-01.json", "2019-01-01-01-01.json"}, variant: variant.AzureSEVSNP{}}, date)
|
||||
ops := sut.constructUploadCmd(variant.AzureSEVSNP{}, version, attestationconfigapi.SEVSNPVersionList{List: []string{"2021-01-01-01-01.json", "2019-01-01-01-01.json"}, Variant: variant.AzureSEVSNP{}}, date)
|
||||
dateStr := "2023-01-01-01-01.json"
|
||||
assert := assert.New(t)
|
||||
assert.Contains(ops, putCmd{
|
||||
apiObject: SEVSNPVersionAPI{
|
||||
apiObject: attestationconfigapi.SEVSNPVersionAPI{
|
||||
Variant: variant.AzureSEVSNP{},
|
||||
Version: dateStr,
|
||||
SEVSNPVersion: version,
|
||||
@ -32,7 +33,7 @@ func TestUploadAzureSEVSNP(t *testing.T) {
|
||||
signer: fakeSigner{},
|
||||
})
|
||||
assert.Contains(ops, putCmd{
|
||||
apiObject: SEVSNPVersionList{variant: variant.AzureSEVSNP{}, list: []string{"2023-01-01-01-01.json", "2021-01-01-01-01.json", "2019-01-01-01-01.json"}},
|
||||
apiObject: attestationconfigapi.SEVSNPVersionList{Variant: variant.AzureSEVSNP{}, List: []string{"2023-01-01-01-01.json", "2021-01-01-01-01.json", "2019-01-01-01-01.json"}},
|
||||
signer: fakeSigner{},
|
||||
})
|
||||
}
|
||||
@ -41,20 +42,20 @@ func TestDeleteAzureSEVSNPVersions(t *testing.T) {
|
||||
sut := Client{
|
||||
bucketID: "bucket",
|
||||
}
|
||||
versions := SEVSNPVersionList{list: []string{"2023-01-01.json", "2021-01-01.json", "2019-01-01.json"}}
|
||||
versions := attestationconfigapi.SEVSNPVersionList{List: []string{"2023-01-01.json", "2021-01-01.json", "2019-01-01.json"}}
|
||||
|
||||
ops, err := sut.deleteSEVSNPVersion(versions, "2021-01-01")
|
||||
|
||||
assert := assert.New(t)
|
||||
assert.NoError(err)
|
||||
assert.Contains(ops, deleteCmd{
|
||||
apiObject: SEVSNPVersionAPI{
|
||||
apiObject: attestationconfigapi.SEVSNPVersionAPI{
|
||||
Version: "2021-01-01.json",
|
||||
},
|
||||
})
|
||||
|
||||
assert.Contains(ops, putCmd{
|
||||
apiObject: SEVSNPVersionList{list: []string{"2023-01-01.json", "2019-01-01.json"}},
|
||||
apiObject: attestationconfigapi.SEVSNPVersionList{List: []string{"2023-01-01.json", "2019-01-01.json"}},
|
||||
})
|
||||
}
|
||||
|
@ -4,12 +4,7 @@ Copyright (c) Edgeless Systems GmbH
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
/*
|
||||
The reporter contains the logic to determine a latest version for SEVSNP based on cached version values observed on CVM instances.
|
||||
Some code in this file (e.g. listing cached files) does not rely on dedicated API objects and instead uses the AWS SDK directly,
|
||||
for no other reason than original development speed.
|
||||
*/
|
||||
package attestationconfigapi
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -23,6 +18,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/client"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
||||
)
|
||||
@ -34,7 +30,7 @@ const cachedVersionsSubDir = "cached-versions"
|
||||
var ErrNoNewerVersion = errors.New("input version is not newer than latest API version")
|
||||
|
||||
func reportVersionDir(attestation variant.Variant) string {
|
||||
return path.Join(AttestationURLPath, attestation.String(), cachedVersionsSubDir)
|
||||
return path.Join(attestationconfigapi.AttestationURLPath, attestation.String(), cachedVersionsSubDir)
|
||||
}
|
||||
|
||||
// UploadSEVSNPVersionLatest saves the given version to the cache, determines the smallest
|
||||
@ -42,7 +38,7 @@ func reportVersionDir(attestation variant.Variant) string {
|
||||
// the latest version in the API if there is an update.
|
||||
// force can be used to bypass the validation logic against the cached versions.
|
||||
func (c Client) UploadSEVSNPVersionLatest(ctx context.Context, attestation variant.Variant, inputVersion,
|
||||
latestAPIVersion SEVSNPVersion, now time.Time, force bool,
|
||||
latestAPIVersion attestationconfigapi.SEVSNPVersion, now time.Time, force bool,
|
||||
) error {
|
||||
if err := c.cacheSEVSNPVersion(ctx, attestation, inputVersion, now); err != nil {
|
||||
return fmt.Errorf("reporting version: %w", err)
|
||||
@ -84,7 +80,7 @@ func (c Client) UploadSEVSNPVersionLatest(ctx context.Context, attestation varia
|
||||
}
|
||||
|
||||
// cacheSEVSNPVersion uploads the latest observed version numbers of the SEVSNP. This version is used to later report the latest version numbers to the API.
|
||||
func (c Client) cacheSEVSNPVersion(ctx context.Context, attestation variant.Variant, version SEVSNPVersion, date time.Time) error {
|
||||
func (c Client) cacheSEVSNPVersion(ctx context.Context, attestation variant.Variant, version attestationconfigapi.SEVSNPVersion, date time.Time) error {
|
||||
dateStr := date.Format(VersionFormat) + ".json"
|
||||
res := putCmd{
|
||||
apiObject: reportedSEVSNPVersionAPI{Version: dateStr, variant: attestation, SEVSNPVersion: version},
|
||||
@ -112,8 +108,8 @@ func (c Client) listCachedVersions(ctx context.Context, attestation variant.Vari
|
||||
}
|
||||
|
||||
// findMinVersion finds the minimal version of the given version dates among the latest values in the version window size.
|
||||
func (c Client) findMinVersion(ctx context.Context, attesation variant.Variant, versionDates []string) (SEVSNPVersion, string, error) {
|
||||
var minimalVersion *SEVSNPVersion
|
||||
func (c Client) findMinVersion(ctx context.Context, attesation variant.Variant, versionDates []string) (attestationconfigapi.SEVSNPVersion, string, error) {
|
||||
var minimalVersion *attestationconfigapi.SEVSNPVersion
|
||||
var minimalDate string
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(versionDates))) // sort in reverse order to slice the latest versions
|
||||
versionDates = versionDates[:c.cacheWindowSize]
|
||||
@ -121,7 +117,7 @@ func (c Client) findMinVersion(ctx context.Context, attesation variant.Variant,
|
||||
for _, date := range versionDates {
|
||||
obj, err := client.Fetch(ctx, c.s3Client, reportedSEVSNPVersionAPI{Version: date + ".json", variant: attesation})
|
||||
if err != nil {
|
||||
return SEVSNPVersion{}, "", fmt.Errorf("get object: %w", err)
|
||||
return attestationconfigapi.SEVSNPVersion{}, "", fmt.Errorf("get object: %w", err)
|
||||
}
|
||||
// Need to set this explicitly as the variant is not part of the marshalled JSON.
|
||||
obj.variant = attesation
|
||||
@ -144,7 +140,7 @@ func (c Client) findMinVersion(ctx context.Context, attesation variant.Variant,
|
||||
}
|
||||
|
||||
// isInputNewerThanOtherVersion compares all version fields and returns true if any input field is newer.
|
||||
func isInputNewerThanOtherVersion(input, other SEVSNPVersion) (bool, error) {
|
||||
func isInputNewerThanOtherVersion(input, other attestationconfigapi.SEVSNPVersion) (bool, error) {
|
||||
if input == other {
|
||||
return false, nil
|
||||
}
|
||||
@ -167,7 +163,7 @@ func isInputNewerThanOtherVersion(input, other SEVSNPVersion) (bool, error) {
|
||||
type reportedSEVSNPVersionAPI struct {
|
||||
Version string `json:"-"`
|
||||
variant variant.Variant `json:"-"`
|
||||
SEVSNPVersion
|
||||
attestationconfigapi.SEVSNPVersion
|
||||
}
|
||||
|
||||
// JSONPath returns the path to the JSON file for the request to the config api.
|
@ -2,17 +2,18 @@
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
package attestationconfigapi
|
||||
package client
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsInputNewerThanLatestAPI(t *testing.T) {
|
||||
newTestCfg := func() SEVSNPVersion {
|
||||
return SEVSNPVersion{
|
||||
newTestCfg := func() attestationconfigapi.SEVSNPVersion {
|
||||
return attestationconfigapi.SEVSNPVersion{
|
||||
Microcode: 93,
|
||||
TEE: 0,
|
||||
SNP: 6,
|
||||
@ -21,13 +22,13 @@ func TestIsInputNewerThanLatestAPI(t *testing.T) {
|
||||
}
|
||||
|
||||
testCases := map[string]struct {
|
||||
latest SEVSNPVersion
|
||||
input SEVSNPVersion
|
||||
latest attestationconfigapi.SEVSNPVersion
|
||||
input attestationconfigapi.SEVSNPVersion
|
||||
expect bool
|
||||
errMsg string
|
||||
}{
|
||||
"input is older than latest": {
|
||||
input: func(c SEVSNPVersion) SEVSNPVersion {
|
||||
input: func(c attestationconfigapi.SEVSNPVersion) attestationconfigapi.SEVSNPVersion {
|
||||
c.Microcode--
|
||||
return c
|
||||
}(newTestCfg()),
|
||||
@ -36,7 +37,7 @@ func TestIsInputNewerThanLatestAPI(t *testing.T) {
|
||||
errMsg: "input Microcode version: 92 is older than latest API version: 93",
|
||||
},
|
||||
"input has greater and smaller version field than latest": {
|
||||
input: func(c SEVSNPVersion) SEVSNPVersion {
|
||||
input: func(c attestationconfigapi.SEVSNPVersion) attestationconfigapi.SEVSNPVersion {
|
||||
c.Microcode++
|
||||
c.Bootloader--
|
||||
return c
|
||||
@ -46,7 +47,7 @@ func TestIsInputNewerThanLatestAPI(t *testing.T) {
|
||||
errMsg: "input Bootloader version: 1 is older than latest API version: 2",
|
||||
},
|
||||
"input is newer than latest": {
|
||||
input: func(c SEVSNPVersion) SEVSNPVersion {
|
||||
input: func(c attestationconfigapi.SEVSNPVersion) attestationconfigapi.SEVSNPVersion {
|
||||
c.TEE++
|
||||
return c
|
||||
}(newTestCfg()),
|
@ -16,6 +16,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi/cli/client"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||
@ -62,7 +63,7 @@ func runDelete(cmd *cobra.Command, args []string) (retErr error) {
|
||||
Region: deleteCfg.region,
|
||||
DistributionID: deleteCfg.distribution,
|
||||
}
|
||||
client, clientClose, err := attestationconfigapi.NewClient(cmd.Context(), cfg,
|
||||
client, clientClose, err := client.New(cmd.Context(), cfg,
|
||||
[]byte(cosignPwd), []byte(privateKey), false, 1, log)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create attestation client: %w", err)
|
||||
@ -170,7 +171,7 @@ func newDeleteConfig(cmd *cobra.Command, args [3]string) (deleteConfig, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func deleteEntry(ctx context.Context, attvar variant.Variant, client *attestationconfigapi.Client, cfg deleteConfig) error {
|
||||
func deleteEntry(ctx context.Context, attvar variant.Variant, client *client.Client, cfg deleteConfig) error {
|
||||
if cfg.kind != snpReport {
|
||||
return fmt.Errorf("kind %s not supported", cfg.kind)
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi/cli/client"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||
@ -68,18 +69,15 @@ func runUpload(cmd *cobra.Command, args []string) (retErr error) {
|
||||
return fmt.Errorf("parsing cli flags: %w", err)
|
||||
}
|
||||
|
||||
client, clientClose, err := attestationconfigapi.NewClient(
|
||||
ctx,
|
||||
client, clientClose, err := client.New(ctx,
|
||||
staticupload.Config{
|
||||
Bucket: uploadCfg.bucket,
|
||||
Region: uploadCfg.region,
|
||||
DistributionID: uploadCfg.distribution,
|
||||
},
|
||||
[]byte(cosignPwd),
|
||||
[]byte(privateKey),
|
||||
false,
|
||||
uploadCfg.cacheWindowSize,
|
||||
log)
|
||||
[]byte(cosignPwd), []byte(privateKey),
|
||||
false, uploadCfg.cacheWindowSize, log,
|
||||
)
|
||||
|
||||
defer func() {
|
||||
err := clientClose(cmd.Context())
|
||||
@ -109,7 +107,7 @@ func runUpload(cmd *cobra.Command, args []string) (retErr error) {
|
||||
|
||||
func uploadReport(ctx context.Context,
|
||||
attestation variant.Variant,
|
||||
client *attestationconfigapi.Client,
|
||||
apiClient *client.Client,
|
||||
cfg uploadConfig,
|
||||
fs file.Handler,
|
||||
log *slog.Logger,
|
||||
@ -137,8 +135,8 @@ func uploadReport(ctx context.Context,
|
||||
}
|
||||
|
||||
latestAPIVersion := latestAPIVersionAPI.SEVSNPVersion
|
||||
if err := client.UploadSEVSNPVersionLatest(ctx, attestation, inputVersion, latestAPIVersion, cfg.uploadDate, cfg.force); err != nil {
|
||||
if errors.Is(err, attestationconfigapi.ErrNoNewerVersion) {
|
||||
if err := apiClient.UploadSEVSNPVersionLatest(ctx, attestation, inputVersion, latestAPIVersion, cfg.uploadDate, cfg.force); err != nil {
|
||||
if errors.Is(err, client.ErrNoNewerVersion) {
|
||||
log.Info(fmt.Sprintf("Input version: %+v is not newer than latest API version: %+v", inputVersion, latestAPIVersion))
|
||||
return nil
|
||||
}
|
||||
@ -178,7 +176,7 @@ func newConfig(cmd *cobra.Command, args [3]string) (uploadConfig, error) {
|
||||
}
|
||||
uploadDate := time.Now()
|
||||
if dateStr != "" {
|
||||
uploadDate, err = time.Parse(attestationconfigapi.VersionFormat, dateStr)
|
||||
uploadDate, err = time.Parse(client.VersionFormat, dateStr)
|
||||
if err != nil {
|
||||
return uploadConfig{}, fmt.Errorf("parsing date: %w", err)
|
||||
}
|
||||
|
@ -39,13 +39,14 @@ const (
|
||||
// unknown is the default objectKind and does nothing.
|
||||
unknown objectKind = "unknown-kind"
|
||||
snpReport objectKind = "snp-report"
|
||||
tdxReport objectKind = "tdx-report"
|
||||
guestFirmware objectKind = "guest-firmware"
|
||||
)
|
||||
|
||||
func kindFromString(s string) objectKind {
|
||||
lower := strings.ToLower(s)
|
||||
switch objectKind(lower) {
|
||||
case snpReport, guestFirmware:
|
||||
case snpReport, guestFirmware, tdxReport:
|
||||
return objectKind(lower)
|
||||
default:
|
||||
return unknown
|
||||
|
@ -74,7 +74,7 @@ func (f *fetcher) FetchSEVSNPVersionList(ctx context.Context, list SEVSNPVersion
|
||||
}
|
||||
|
||||
// Need to set this explicitly as the variant is not part of the marshalled JSON.
|
||||
fetchedList.variant = list.variant
|
||||
fetchedList.Variant = list.Variant
|
||||
|
||||
return fetchedList, nil
|
||||
}
|
||||
@ -94,13 +94,13 @@ func (f *fetcher) FetchSEVSNPVersion(ctx context.Context, version SEVSNPVersionA
|
||||
|
||||
// FetchSEVSNPVersionLatest returns the latest versions of the given type.
|
||||
func (f *fetcher) FetchSEVSNPVersionLatest(ctx context.Context, attesation variant.Variant) (res SEVSNPVersionAPI, err error) {
|
||||
list, err := f.FetchSEVSNPVersionList(ctx, SEVSNPVersionList{variant: attesation})
|
||||
list, err := f.FetchSEVSNPVersionList(ctx, SEVSNPVersionList{Variant: attesation})
|
||||
if err != nil {
|
||||
return res, ErrNoVersionsFound
|
||||
}
|
||||
|
||||
getVersionRequest := SEVSNPVersionAPI{
|
||||
Version: list.List()[0], // latest version is first in list
|
||||
Version: list.List[0], // latest version is first in list
|
||||
Variant: attesation,
|
||||
}
|
||||
res, err = f.FetchSEVSNPVersion(ctx, getVersionRequest)
|
||||
|
@ -64,26 +64,23 @@ func (i SEVSNPVersionAPI) Validate() error {
|
||||
// Once we switch to v2 of the API we could embed the variant in the object and remove some code from fetcher & client.
|
||||
// That would remove the possibility of some fetcher/client code forgetting to set the variant.
|
||||
type SEVSNPVersionList struct {
|
||||
variant variant.Variant
|
||||
list []string
|
||||
Variant variant.Variant
|
||||
List []string
|
||||
}
|
||||
|
||||
// MarshalJSON marshals the i's list property to JSON.
|
||||
func (i SEVSNPVersionList) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(i.list)
|
||||
return json.Marshal(i.List)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals a list of strings into i's list property.
|
||||
func (i *SEVSNPVersionList) UnmarshalJSON(data []byte) error {
|
||||
return json.Unmarshal(data, &i.list)
|
||||
return json.Unmarshal(data, &i.List)
|
||||
}
|
||||
|
||||
// List returns i's list property.
|
||||
func (i SEVSNPVersionList) List() []string { return i.list }
|
||||
|
||||
// JSONPath returns the path to the JSON file for the request to the config api.
|
||||
func (i SEVSNPVersionList) JSONPath() string {
|
||||
return path.Join(AttestationURLPath, i.variant.String(), "list")
|
||||
return path.Join(AttestationURLPath, i.Variant.String(), "list")
|
||||
}
|
||||
|
||||
// ValidateRequest is a NoOp as there is no input.
|
||||
@ -93,20 +90,20 @@ func (i SEVSNPVersionList) ValidateRequest() error {
|
||||
|
||||
// SortReverse sorts the list of versions in reverse order.
|
||||
func (i *SEVSNPVersionList) SortReverse() {
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(i.list)))
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(i.List)))
|
||||
}
|
||||
|
||||
// addVersion adds new to i's list and sorts the element in descending order.
|
||||
func (i *SEVSNPVersionList) addVersion(new string) {
|
||||
i.list = append(i.list, new)
|
||||
i.list = variant.RemoveDuplicate(i.list)
|
||||
// AddVersion adds new to i's list and sorts the element in descending order.
|
||||
func (i *SEVSNPVersionList) AddVersion(new string) {
|
||||
i.List = append(i.List, new)
|
||||
i.List = variant.RemoveDuplicate(i.List)
|
||||
|
||||
i.SortReverse()
|
||||
}
|
||||
|
||||
// Validate validates the response.
|
||||
func (i SEVSNPVersionList) Validate() error {
|
||||
if len(i.list) < 1 {
|
||||
if len(i.List) < 1 {
|
||||
return fmt.Errorf("no versions found in /list")
|
||||
}
|
||||
return nil
|
||||
|
@ -21,16 +21,16 @@ func TestSEVSNPVersionListMarshalUnmarshalJSON(t *testing.T) {
|
||||
wantDiff bool
|
||||
}{
|
||||
"success": {
|
||||
input: SEVSNPVersionList{list: []string{"v1", "v2"}},
|
||||
output: SEVSNPVersionList{list: []string{"v1", "v2"}},
|
||||
input: SEVSNPVersionList{List: []string{"v1", "v2"}},
|
||||
output: SEVSNPVersionList{List: []string{"v1", "v2"}},
|
||||
},
|
||||
"variant is lost": {
|
||||
input: SEVSNPVersionList{list: []string{"v1", "v2"}, variant: variant.AzureSEVSNP{}},
|
||||
output: SEVSNPVersionList{list: []string{"v1", "v2"}},
|
||||
input: SEVSNPVersionList{List: []string{"v1", "v2"}, Variant: variant.AzureSEVSNP{}},
|
||||
output: SEVSNPVersionList{List: []string{"v1", "v2"}},
|
||||
},
|
||||
"wrong order": {
|
||||
input: SEVSNPVersionList{list: []string{"v1", "v2"}},
|
||||
output: SEVSNPVersionList{list: []string{"v2", "v1"}},
|
||||
input: SEVSNPVersionList{List: []string{"v1", "v2"}},
|
||||
output: SEVSNPVersionList{List: []string{"v2", "v1"}},
|
||||
wantDiff: true,
|
||||
},
|
||||
}
|
||||
@ -68,10 +68,10 @@ func TestSEVSNPVersionListAddVersion(t *testing.T) {
|
||||
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
v := SEVSNPVersionList{list: tc.versions}
|
||||
v.addVersion(tc.new)
|
||||
v := SEVSNPVersionList{List: tc.versions}
|
||||
v.AddVersion(tc.new)
|
||||
|
||||
assert.Equal(t, tc.expected, v.list)
|
||||
assert.Equal(t, tc.expected, v.List)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user