mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-06-21 12:44:20 -04:00
config: dynamic attestation configuration through S3 backed API (#1808)
This commit is contained in:
parent
25211dc154
commit
0a6e5ec02e
92 changed files with 1020 additions and 302 deletions
4
.github/actions/versionsapi/Dockerfile
vendored
4
.github/actions/versionsapi/Dockerfile
vendored
|
@ -13,11 +13,11 @@ RUN go mod download
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
WORKDIR /workspace/internal/versionsapi/cli
|
WORKDIR /workspace/internal/api/versionsapi/cli
|
||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o versionsapi .
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o versionsapi .
|
||||||
|
|
||||||
FROM scratch as release
|
FROM scratch as release
|
||||||
|
|
||||||
COPY --from=builder /workspace/internal/versionsapi/cli/versionsapi .
|
COPY --from=builder /workspace/internal/api/versionsapi/cli/versionsapi .
|
||||||
|
|
||||||
CMD ["/notIntendedToBeExecuted"]
|
CMD ["/notIntendedToBeExecuted"]
|
||||||
|
|
|
@ -6,7 +6,7 @@ on:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- "internal/versionsapi/**"
|
- "internal/api/versionsapi/**"
|
||||||
- ".github/workflows/build-versionsapi-ci-image.yml"
|
- ".github/workflows/build-versionsapi-ci-image.yml"
|
||||||
- ".github/actions/versionsapi/**"
|
- ".github/actions/versionsapi/**"
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
/internal/retry @katexochen
|
/internal/retry @katexochen
|
||||||
/internal/sigstore @malt3
|
/internal/sigstore @malt3
|
||||||
/internal/versions @katexochen
|
/internal/versions @katexochen
|
||||||
/internal/versionsapi @katexochen
|
/internal/api/versionsapi @katexochen
|
||||||
/joinservice @daniel-weisse
|
/joinservice @daniel-weisse
|
||||||
/keyservice @daniel-weisse
|
/keyservice @daniel-weisse
|
||||||
/operators @malt3
|
/operators @malt3
|
||||||
|
|
|
@ -46,6 +46,8 @@ go_library(
|
||||||
"//cli/internal/terraform",
|
"//cli/internal/terraform",
|
||||||
"//cli/internal/upgrade",
|
"//cli/internal/upgrade",
|
||||||
"//disk-mapper/recoverproto",
|
"//disk-mapper/recoverproto",
|
||||||
|
"//internal/api/fetcher",
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/atls",
|
"//internal/atls",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
"//internal/cloud/azureshared",
|
"//internal/cloud/azureshared",
|
||||||
|
@ -71,8 +73,6 @@ go_library(
|
||||||
"//internal/sigstore",
|
"//internal/sigstore",
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versions",
|
"//internal/versions",
|
||||||
"//internal/versionsapi",
|
|
||||||
"//internal/versionsapi/fetcher",
|
|
||||||
"//operators/constellation-node-operator/api/v1alpha1",
|
"//operators/constellation-node-operator/api/v1alpha1",
|
||||||
"//verify/verifyproto",
|
"//verify/verifyproto",
|
||||||
"@com_github_mattn_go_isatty//:go-isatty",
|
"@com_github_mattn_go_isatty//:go-isatty",
|
||||||
|
@ -126,6 +126,7 @@ go_test(
|
||||||
"//cli/internal/terraform",
|
"//cli/internal/terraform",
|
||||||
"//cli/internal/upgrade",
|
"//cli/internal/upgrade",
|
||||||
"//disk-mapper/recoverproto",
|
"//disk-mapper/recoverproto",
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/atls",
|
"//internal/atls",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
|
@ -142,7 +143,6 @@ go_test(
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versions",
|
"//internal/versions",
|
||||||
"//internal/versionsapi",
|
|
||||||
"//operators/constellation-node-operator/api/v1alpha1",
|
"//operators/constellation-node-operator/api/v1alpha1",
|
||||||
"//verify/verifyproto",
|
"//verify/verifyproto",
|
||||||
"@com_github_spf13_afero//:afero",
|
"@com_github_spf13_afero//:afero",
|
||||||
|
|
|
@ -14,12 +14,12 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/sigstore"
|
"github.com/edgelesssys/constellation/v2/internal/sigstore"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -77,7 +77,7 @@ func (cfm *configFetchMeasurementsCmd) configFetchMeasurements(
|
||||||
cfm.log.Debugf("Using flags %v", flags)
|
cfm.log.Debugf("Using flags %v", flags)
|
||||||
|
|
||||||
cfm.log.Debugf("Loading configuration file from %q", flags.configPath)
|
cfm.log.Debugf("Loading configuration file from %q", flags.configPath)
|
||||||
conf, err := config.New(fileHandler, flags.configPath, flags.force)
|
conf, err := config.NewWithClient(fileHandler, flags.configPath, client, flags.force)
|
||||||
var configValidationErr *config.ValidationError
|
var configValidationErr *config.ValidationError
|
||||||
if errors.As(err, &configValidationErr) {
|
if errors.As(err, &configValidationErr) {
|
||||||
cmd.PrintErrln(configValidationErr.LongMessage())
|
cmd.PrintErrln(configValidationErr.LongMessage())
|
||||||
|
|
|
@ -15,12 +15,12 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
|
@ -17,6 +17,8 @@ import (
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/kubernetes"
|
"github.com/edgelesssys/constellation/v2/cli/internal/kubernetes"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/fetcher"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
||||||
|
@ -28,8 +30,6 @@ import (
|
||||||
"github.com/edgelesssys/constellation/v2/internal/sigstore"
|
"github.com/edgelesssys/constellation/v2/internal/sigstore"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versions"
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi/fetcher"
|
|
||||||
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -67,7 +67,7 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
versionListFetcher := fetcher.NewFetcher()
|
versionListFetcher := fetcher.NewVersionAPIFetcher()
|
||||||
rekor, err := sigstore.NewRekor()
|
rekor, err := sigstore.NewRekor()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("constructing Rekor client: %w", err)
|
return fmt.Errorf("constructing Rekor client: %w", err)
|
||||||
|
@ -83,7 +83,7 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
||||||
flags: flags,
|
flags: flags,
|
||||||
cliVersion: compatibility.EnsurePrefixV(constants.VersionInfo()),
|
cliVersion: compatibility.EnsurePrefixV(constants.VersionInfo()),
|
||||||
log: log,
|
log: log,
|
||||||
versionsapi: fetcher.NewFetcher(),
|
versionsapi: fetcher.NewVersionAPIFetcher(),
|
||||||
},
|
},
|
||||||
log: log,
|
log: log,
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||||
|
@ -22,7 +23,6 @@ import (
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
|
@ -14,6 +14,7 @@ go_library(
|
||||||
"//cli/internal/helm",
|
"//cli/internal/helm",
|
||||||
"//cli/internal/terraform",
|
"//cli/internal/terraform",
|
||||||
"//cli/internal/upgrade",
|
"//cli/internal/upgrade",
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/compatibility",
|
"//internal/compatibility",
|
||||||
|
@ -26,7 +27,6 @@ go_library(
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versions",
|
"//internal/versions",
|
||||||
"//internal/versions/components",
|
"//internal/versions/components",
|
||||||
"//internal/versionsapi",
|
|
||||||
"//operators/constellation-node-operator/api/v1alpha1",
|
"//operators/constellation-node-operator/api/v1alpha1",
|
||||||
"@io_k8s_api//core/v1:core",
|
"@io_k8s_api//core/v1:core",
|
||||||
"@io_k8s_apimachinery//pkg/api/errors",
|
"@io_k8s_apimachinery//pkg/api/errors",
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/upgrade"
|
"github.com/edgelesssys/constellation/v2/cli/internal/upgrade"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
||||||
|
@ -30,7 +31,6 @@ import (
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versions"
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versions/components"
|
"github.com/edgelesssys/constellation/v2/internal/versions/components"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1"
|
updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
|
|
@ -22,7 +22,7 @@ With `cdbg` and `yq` installed in your path:
|
||||||
|
|
||||||
1. Run `constellation config generate` to create a new default configuration
|
1. Run `constellation config generate` to create a new default configuration
|
||||||
|
|
||||||
2. Locate the latest debugd images by running `(cd internal/versionsapi/cli && go build -o versionsapi . && ./versionsapi latest --ref main --stream debug)`
|
2. Locate the latest debugd images by running `(cd internal/api/versionsapi/cli && go build -o versionsapi . && ./versionsapi latest --ref main --stream debug)`
|
||||||
|
|
||||||
3. Modify the `constellation-conf.yaml` to use an image with the debugd already included and add required firewall rules:
|
3. Modify the `constellation-conf.yaml` to use an image with the debugd already included and add required firewall rules:
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,13 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/e2e/internal/upgrade",
|
importpath = "github.com/edgelesssys/constellation/v2/e2e/internal/upgrade",
|
||||||
visibility = ["//e2e:__subpackages__"],
|
visibility = ["//e2e:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
"//internal/imagefetcher",
|
"//internal/imagefetcher",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@sh_helm_helm_v3//pkg/action",
|
"@sh_helm_helm_v3//pkg/action",
|
||||||
"@sh_helm_helm_v3//pkg/cli",
|
"@sh_helm_helm_v3//pkg/cli",
|
||||||
],
|
],
|
||||||
|
|
|
@ -12,11 +12,11 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/imagefetcher"
|
"github.com/edgelesssys/constellation/v2/internal/imagefetcher"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type upgradeInfo struct {
|
type upgradeInfo struct {
|
||||||
|
|
|
@ -6,10 +6,10 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/hack/cli-k8s-compatibility",
|
importpath = "github.com/edgelesssys/constellation/v2/hack/cli-k8s-compatibility",
|
||||||
visibility = ["//visibility:private"],
|
visibility = ["//visibility:private"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
|
"//internal/api/versionsapi/client",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/versions",
|
"//internal/versions",
|
||||||
"//internal/versionsapi",
|
|
||||||
"//internal/versionsapi/client",
|
|
||||||
"@org_uber_go_zap//zapcore",
|
"@org_uber_go_zap//zapcore",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,10 +11,10 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi/client"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versions"
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi/client"
|
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
19
hack/configapi/BUILD.bazel
Normal file
19
hack/configapi/BUILD.bazel
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "configapi_lib",
|
||||||
|
srcs = ["main.go"],
|
||||||
|
importpath = "github.com/edgelesssys/constellation/v2/hack/configapi",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = [
|
||||||
|
"//internal/api/configapi",
|
||||||
|
"//internal/kms/uri",
|
||||||
|
"@com_github_spf13_cobra//:cobra",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_binary(
|
||||||
|
name = "upload",
|
||||||
|
embed = [":configapi_lib"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
91
hack/configapi/main.go
Normal file
91
hack/configapi/main.go
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/configapi"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
awsRegion = "eu-central-1"
|
||||||
|
awsBucket = "cdn-constellation-backend"
|
||||||
|
invalidDefault = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// AWS S3 credentials.
|
||||||
|
awsAccessKeyID string
|
||||||
|
awsAccessKey string
|
||||||
|
|
||||||
|
// Azure SEV-SNP version numbers.
|
||||||
|
bootloaderVersion uint8
|
||||||
|
teeVersion uint8
|
||||||
|
snpVersion uint8
|
||||||
|
microcodeVersion uint8
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleError(err error) {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
myCmd := &cobra.Command{
|
||||||
|
Use: "upload a set of versions specific to the azure-sev-snp attestation variant to the config api",
|
||||||
|
Short: "upload a set of versions specific to the azure-sev-snp attestation variant to the config api",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
ctx := context.Background()
|
||||||
|
cfg := uri.AWSS3Config{
|
||||||
|
Bucket: awsBucket,
|
||||||
|
AccessKeyID: awsAccessKeyID,
|
||||||
|
AccessKey: awsAccessKey,
|
||||||
|
Region: awsRegion,
|
||||||
|
}
|
||||||
|
sut, err := configapi.NewAttestationVersionRepo(ctx, cfg)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
versions := configapi.AzureSEVSNPVersion{
|
||||||
|
Bootloader: bootloaderVersion,
|
||||||
|
TEE: teeVersion,
|
||||||
|
SNP: snpVersion,
|
||||||
|
Microcode: microcodeVersion,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := sut.UploadAzureSEVSNP(ctx, versions, time.Now()); err != nil {
|
||||||
|
panic(err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("Successfully uploaded version numbers", versions)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
myCmd.PersistentFlags().Uint8VarP(&bootloaderVersion, "bootloader-version", "b", invalidDefault, "Bootloader version number")
|
||||||
|
handleError(myCmd.MarkPersistentFlagRequired("bootloader-version"))
|
||||||
|
|
||||||
|
myCmd.PersistentFlags().Uint8VarP(&teeVersion, "tee-version", "t", invalidDefault, "TEE version number")
|
||||||
|
handleError(myCmd.MarkPersistentFlagRequired("tee-version"))
|
||||||
|
|
||||||
|
myCmd.PersistentFlags().Uint8VarP(&snpVersion, "snp-version", "s", invalidDefault, "SNP version number")
|
||||||
|
handleError(myCmd.MarkPersistentFlagRequired("snp-version"))
|
||||||
|
|
||||||
|
myCmd.PersistentFlags().Uint8VarP(µcodeVersion, "microcode-version", "m", invalidDefault, "Microcode version number")
|
||||||
|
handleError(myCmd.MarkPersistentFlagRequired("microcode-version"))
|
||||||
|
|
||||||
|
myCmd.PersistentFlags().StringVar(&awsAccessKeyID, "key-id", "", "ID of the Access key to use for AWS tests. Required for AWS KMS and storage test.")
|
||||||
|
handleError(myCmd.MarkPersistentFlagRequired("key-id"))
|
||||||
|
|
||||||
|
myCmd.PersistentFlags().StringVar(&awsAccessKey, "key", "", "Access key to use for AWS tests. Required for AWS KMS and storage test.")
|
||||||
|
handleError(myCmd.MarkPersistentFlagRequired("key"))
|
||||||
|
handleError(myCmd.Execute())
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/image/upload/internal/cmd",
|
importpath = "github.com/edgelesssys/constellation/v2/image/upload/internal/cmd",
|
||||||
visibility = ["//image/upload:__subpackages__"],
|
visibility = ["//image/upload:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
|
@ -36,7 +37,6 @@ go_library(
|
||||||
"//internal/osimage/measurementsuploader",
|
"//internal/osimage/measurementsuploader",
|
||||||
"//internal/osimage/nop",
|
"//internal/osimage/nop",
|
||||||
"//internal/osimage/secureboot",
|
"//internal/osimage/secureboot",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_spf13_afero//:afero",
|
"@com_github_spf13_afero//:afero",
|
||||||
"@com_github_spf13_cobra//:cobra",
|
"@com_github_spf13_cobra//:cobra",
|
||||||
"@org_uber_go_zap//zapcore",
|
"@org_uber_go_zap//zapcore",
|
||||||
|
|
|
@ -10,8 +10,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type archivist interface {
|
type archivist interface {
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,9 +11,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
infoupload "github.com/edgelesssys/constellation/v2/internal/osimage/imageinfo"
|
infoupload "github.com/edgelesssys/constellation/v2/internal/osimage/imageinfo"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func uploadImage(ctx context.Context, archiveC archivist, uploadC uploader, req *osimage.UploadRequest, out io.Writer) error {
|
func uploadImage(ctx context.Context, archiveC archivist, uploadC uploader, req *osimage.UploadRequest, out io.Writer) error {
|
||||||
|
|
36
internal/api/configapi/BUILD.bazel
Normal file
36
internal/api/configapi/BUILD.bazel
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
load("//bazel/go:go_test.bzl", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "configapi",
|
||||||
|
srcs = [
|
||||||
|
"attestation.go",
|
||||||
|
"attestationversion.go",
|
||||||
|
"configapi.go",
|
||||||
|
"repo.go",
|
||||||
|
],
|
||||||
|
importpath = "github.com/edgelesssys/constellation/v2/internal/api/configapi",
|
||||||
|
visibility = ["//:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
"//internal/constants",
|
||||||
|
"//internal/kms/storage",
|
||||||
|
"//internal/kms/storage/awss3",
|
||||||
|
"//internal/kms/uri",
|
||||||
|
"//internal/variant",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "configapi_test",
|
||||||
|
srcs = [
|
||||||
|
"attestationversion_test.go",
|
||||||
|
"repo_test.go",
|
||||||
|
],
|
||||||
|
embed = [":configapi"],
|
||||||
|
deps = [
|
||||||
|
"//internal/kms/uri",
|
||||||
|
"//internal/variant",
|
||||||
|
"@com_github_stretchr_testify//require",
|
||||||
|
"@in_gopkg_yaml_v3//:yaml_v3",
|
||||||
|
],
|
||||||
|
)
|
99
internal/api/configapi/attestation.go
Normal file
99
internal/api/configapi/attestation.go
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
package configapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
|
)
|
||||||
|
|
||||||
|
// attestationURLPath is the URL path to the attestation versions.
|
||||||
|
const attestationURLPath = "constellation/v1/attestation"
|
||||||
|
|
||||||
|
// AzureSEVSNPVersionType is the type of the version to be requested.
|
||||||
|
type AzureSEVSNPVersionType string
|
||||||
|
|
||||||
|
// AzureSEVSNPVersion tracks the latest version of each component of the Azure SEVSNP.
|
||||||
|
type AzureSEVSNPVersion struct {
|
||||||
|
// Bootloader is the latest version of the Azure SEVSNP bootloader.
|
||||||
|
Bootloader uint8 `json:"bootloader"`
|
||||||
|
// TEE is the latest version of the Azure SEVSNP TEE.
|
||||||
|
TEE uint8 `json:"tee"`
|
||||||
|
// SNP is the latest version of the Azure SEVSNP SNP.
|
||||||
|
SNP uint8 `json:"snp"`
|
||||||
|
// Microcode is the latest version of the Azure SEVSNP microcode.
|
||||||
|
Microcode uint8 `json:"microcode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AzureSEVSNPVersionGet is the request to get the version information of the specific version in the config api.
|
||||||
|
type AzureSEVSNPVersionGet struct {
|
||||||
|
Version string `json:"-"`
|
||||||
|
AzureSEVSNPVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL returns the URL for the request to the config api.
|
||||||
|
func (i AzureSEVSNPVersionGet) URL() (string, error) {
|
||||||
|
url, err := url.Parse(constants.CDNRepositoryURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("parsing CDN URL: %w", err)
|
||||||
|
}
|
||||||
|
url.Path = i.JSONPath()
|
||||||
|
return url.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSONPath returns the path to the JSON file for the request to the config api.
|
||||||
|
func (i AzureSEVSNPVersionGet) JSONPath() string {
|
||||||
|
return path.Join(attestationURLPath, variant.AzureSEVSNP{}.String(), i.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateRequest validates the request.
|
||||||
|
func (i AzureSEVSNPVersionGet) ValidateRequest() error {
|
||||||
|
if !strings.HasSuffix(i.Version, ".json") {
|
||||||
|
return fmt.Errorf("version has no .json suffix")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate is a No-Op at the moment.
|
||||||
|
func (i AzureSEVSNPVersionGet) Validate() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AzureSEVSNPVersionList is the request to list all versions in the config api.
|
||||||
|
type AzureSEVSNPVersionList []string
|
||||||
|
|
||||||
|
// URL returns the URL for the request to the config api.
|
||||||
|
func (i AzureSEVSNPVersionList) URL() (string, error) {
|
||||||
|
url, err := url.Parse(constants.CDNRepositoryURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("parsing CDN URL: %w", err)
|
||||||
|
}
|
||||||
|
url.Path = i.JSONPath()
|
||||||
|
return url.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSONPath returns the path to the JSON file for the request to the config api.
|
||||||
|
func (i AzureSEVSNPVersionList) JSONPath() string {
|
||||||
|
return path.Join(attestationURLPath, variant.AzureSEVSNP{}.String(), "list")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateRequest is a NoOp as there is no input.
|
||||||
|
func (i AzureSEVSNPVersionList) ValidateRequest() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates the response.
|
||||||
|
func (i AzureSEVSNPVersionList) Validate() error {
|
||||||
|
if len(i) < 1 {
|
||||||
|
return fmt.Errorf("no versions found in /list")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
81
internal/api/configapi/attestationversion.go
Normal file
81
internal/api/configapi/attestationversion.go
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package configapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const placeholderVersionValue = 0
|
||||||
|
|
||||||
|
// NewLatestPlaceholderVersion returns the latest version with a placeholder version value.
|
||||||
|
func NewLatestPlaceholderVersion() AttestationVersion {
|
||||||
|
return AttestationVersion{
|
||||||
|
Value: placeholderVersionValue,
|
||||||
|
IsLatest: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AttestationVersion is a type that represents a version of a SNP.
|
||||||
|
type AttestationVersion struct {
|
||||||
|
Value uint8
|
||||||
|
IsLatest bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalYAML implements a custom marshaller to resolve "latest" values.
|
||||||
|
func (v AttestationVersion) MarshalYAML() (any, error) {
|
||||||
|
if v.IsLatest {
|
||||||
|
return "latest", nil
|
||||||
|
}
|
||||||
|
return v.Value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalYAML implements a custom unmarshaller to resolve "atest" values.
|
||||||
|
func (v *AttestationVersion) UnmarshalYAML(unmarshal func(any) error) error {
|
||||||
|
var rawUnmarshal any
|
||||||
|
if err := unmarshal(&rawUnmarshal); err != nil {
|
||||||
|
return fmt.Errorf("raw unmarshal: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.parseRawUnmarshal(rawUnmarshal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements a custom marshaller to resolve "latest" values.
|
||||||
|
func (v AttestationVersion) MarshalJSON() ([]byte, error) {
|
||||||
|
if v.IsLatest {
|
||||||
|
return json.Marshal("latest")
|
||||||
|
}
|
||||||
|
return json.Marshal(v.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements a custom unmarshaller to resolve "latest" values.
|
||||||
|
func (v *AttestationVersion) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
var rawUnmarshal any
|
||||||
|
if err := json.Unmarshal(data, &rawUnmarshal); err != nil {
|
||||||
|
return fmt.Errorf("raw unmarshal: %w", err)
|
||||||
|
}
|
||||||
|
return v.parseRawUnmarshal(rawUnmarshal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *AttestationVersion) parseRawUnmarshal(rawUnmarshal any) error {
|
||||||
|
switch s := rawUnmarshal.(type) {
|
||||||
|
case string:
|
||||||
|
if strings.ToLower(s) == "latest" {
|
||||||
|
v.IsLatest = true
|
||||||
|
v.Value = placeholderVersionValue
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("invalid version value: %s", s)
|
||||||
|
}
|
||||||
|
case int:
|
||||||
|
v.Value = uint8(s)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid version value type: %s", s)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
46
internal/api/configapi/attestationversion_test.go
Normal file
46
internal/api/configapi/attestationversion_test.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package configapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestVersionMarshalYAML(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
sut AttestationVersion
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "isLatest resolves to latest",
|
||||||
|
sut: AttestationVersion{
|
||||||
|
Value: 1,
|
||||||
|
IsLatest: true,
|
||||||
|
},
|
||||||
|
want: "latest\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "value 5 resolves to 5",
|
||||||
|
sut: AttestationVersion{
|
||||||
|
Value: 5,
|
||||||
|
IsLatest: false,
|
||||||
|
},
|
||||||
|
want: "5\n",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
bt, err := yaml.Marshal(tt.sut)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tt.want, string(bt))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
20
internal/api/configapi/configapi.go
Normal file
20
internal/api/configapi/configapi.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
# Config API
|
||||||
|
|
||||||
|
The Config API provides information about versions of Constellation components.
|
||||||
|
|
||||||
|
This package defines API types that represents objects of the config API.
|
||||||
|
The types provide helper methods for validation and commonly used operations on the
|
||||||
|
information contained in the objects. Especially the paths used for the API are defined
|
||||||
|
in these helper methods.
|
||||||
|
|
||||||
|
The package also provides helper functions that can be used in context of the config API,
|
||||||
|
e.g. to validate versions.
|
||||||
|
*/
|
||||||
|
package configapi
|
96
internal/api/configapi/repo.go
Normal file
96
internal/api/configapi/repo.go
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
package configapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/kms/storage"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/kms/storage/awss3"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AttestationVersionRepo manages (modifies) the version information for the attestation variants.
|
||||||
|
type AttestationVersionRepo struct {
|
||||||
|
*awss3.Storage
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAttestationVersionRepo returns a new AttestationVersionRepo.
|
||||||
|
func NewAttestationVersionRepo(ctx context.Context, cfg uri.AWSS3Config) (*AttestationVersionRepo, error) {
|
||||||
|
s3, err := awss3.New(ctx, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create s3 storage: %w", err)
|
||||||
|
}
|
||||||
|
return &AttestationVersionRepo{s3}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadAzureSEVSNP uploads the latest version numbers of the Azure SEVSNP.
|
||||||
|
func (a AttestationVersionRepo) UploadAzureSEVSNP(ctx context.Context, versions AzureSEVSNPVersion, date time.Time) error {
|
||||||
|
bt, err := json.Marshal(versions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
variant := variant.AzureSEVSNP{}
|
||||||
|
fname := date.Format("2006-01-02-15-04") + ".json"
|
||||||
|
|
||||||
|
err = a.Put(ctx, fmt.Sprintf("%s/%s/%s", attestationURLPath, variant.String(), fname), bt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return a.addVersionToList(ctx, variant, fname)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns the list of versions for the given attestation type.
|
||||||
|
func (a AttestationVersionRepo) List(ctx context.Context, attestation variant.Variant) ([]string, error) {
|
||||||
|
key := path.Join(attestationURLPath, attestation.String(), "list")
|
||||||
|
bt, err := a.Get(ctx, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var versions []string
|
||||||
|
if err := json.Unmarshal(bt, &versions); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return versions, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteList empties the list of versions for the given attestation type.
|
||||||
|
func (a AttestationVersionRepo) DeleteList(ctx context.Context, attestation variant.Variant) error {
|
||||||
|
versions := []string{}
|
||||||
|
bt, err := json.Marshal(&versions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return a.Put(ctx, path.Join(attestationURLPath, attestation.String(), "list"), bt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AttestationVersionRepo) addVersionToList(ctx context.Context, attestation variant.Variant, fname string) error {
|
||||||
|
versions := []string{}
|
||||||
|
key := path.Join(attestationURLPath, attestation.String(), "list")
|
||||||
|
bt, err := a.Get(ctx, key)
|
||||||
|
if err == nil {
|
||||||
|
if err := json.Unmarshal(bt, &versions); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if !errors.Is(err, storage.ErrDEKUnset) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
versions = append(versions, fname)
|
||||||
|
versions = variant.RemoveDuplicate(versions)
|
||||||
|
sort.Sort(sort.Reverse(sort.StringSlice(versions)))
|
||||||
|
json, err := json.Marshal(versions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return a.Put(ctx, key, json)
|
||||||
|
}
|
85
internal/api/configapi/repo_test.go
Normal file
85
internal/api/configapi/repo_test.go
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
//go:build e2e
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
package configapi_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/configapi"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
awsRegion = flag.String("aws-region", "us-east-1", "Region to use for AWS tests. Required for AWS KMS test.")
|
||||||
|
awsAccessKeyID = flag.String("aws-access-key-id", "", "ID of the Access key to use for AWS tests. Required for AWS KMS and storage test.")
|
||||||
|
awsAccessKey = flag.String("aws-access-key", "", "Access key to use for AWS tests. Required for AWS KMS and storage test.")
|
||||||
|
awsBucket = flag.String("aws-bucket", "", "Name of the S3 bucket to use for AWS storage test. Required for AWS storage test.")
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
flag.Parse()
|
||||||
|
if *awsAccessKey == "" || *awsAccessKeyID == "" || *awsBucket == "" || *awsRegion == "" {
|
||||||
|
flag.Usage()
|
||||||
|
fmt.Println("Required flags not set: --aws-access-key, --aws-access-key-id, --aws-bucket, --aws-region. Skipping tests.")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
os.Exit(m.Run())
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfg = uri.AWSS3Config{
|
||||||
|
Bucket: *awsBucket,
|
||||||
|
AccessKeyID: *awsAccessKeyID,
|
||||||
|
AccessKey: *awsAccessKey,
|
||||||
|
Region: *awsRegion,
|
||||||
|
}
|
||||||
|
|
||||||
|
var versionValues = configapi.AzureSEVSNPVersion{
|
||||||
|
Bootloader: 2,
|
||||||
|
TEE: 0,
|
||||||
|
SNP: 6,
|
||||||
|
Microcode: 93,
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUploadAzureSEVSNPVersions(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
sut, err := configapi.NewAttestationVersionRepo(ctx, cfg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
d := time.Date(2021, 1, 1, 1, 1, 1, 1, time.UTC)
|
||||||
|
require.NoError(t, sut.UploadAzureSEVSNP(ctx, versionValues, d))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListVersions(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
sut, err := configapi.NewAttestationVersionRepo(ctx, cfg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = sut.DeleteList(ctx, variant.AzureSEVSNP{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
res, err := sut.List(ctx, variant.AzureSEVSNP{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, []string{}, res)
|
||||||
|
|
||||||
|
d := time.Date(2021, 1, 1, 1, 1, 1, 1, time.UTC)
|
||||||
|
err = sut.UploadAzureSEVSNP(ctx, versionValues, d)
|
||||||
|
require.NoError(t, err)
|
||||||
|
res, err = sut.List(ctx, variant.AzureSEVSNP{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, []string{"2021-01-01-01-01.json"}, res)
|
||||||
|
|
||||||
|
err = sut.DeleteList(ctx, variant.AzureSEVSNP{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
|
@ -3,18 +3,29 @@ load("//bazel/go:go_test.bzl", "go_test")
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "fetcher",
|
name = "fetcher",
|
||||||
srcs = ["fetcher.go"],
|
srcs = [
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/versionsapi/fetcher",
|
"configapi.go",
|
||||||
|
"fetcher.go",
|
||||||
|
"versionapi.go",
|
||||||
|
],
|
||||||
|
importpath = "github.com/edgelesssys/constellation/v2/internal/api/fetcher",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = ["//internal/versionsapi"],
|
deps = [
|
||||||
|
"//internal/api/configapi",
|
||||||
|
"//internal/api/versionsapi",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_test(
|
go_test(
|
||||||
name = "fetcher_test",
|
name = "fetcher_test",
|
||||||
srcs = ["fetcher_test.go"],
|
srcs = [
|
||||||
|
"configapi_test.go",
|
||||||
|
"versionapi_test.go",
|
||||||
|
],
|
||||||
embed = [":fetcher"],
|
embed = [":fetcher"],
|
||||||
deps = [
|
deps = [
|
||||||
"//internal/versionsapi",
|
"//internal/api/configapi",
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"@com_github_stretchr_testify//assert",
|
"@com_github_stretchr_testify//assert",
|
||||||
"@com_github_stretchr_testify//require",
|
"@com_github_stretchr_testify//require",
|
||||||
"@org_uber_go_goleak//:goleak",
|
"@org_uber_go_goleak//:goleak",
|
55
internal/api/fetcher/configapi.go
Normal file
55
internal/api/fetcher/configapi.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package fetcher
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/configapi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ConfigAPIFetcher fetches config API resources without authentication.
|
||||||
|
type ConfigAPIFetcher struct {
|
||||||
|
*fetcher
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConfigAPIFetcher returns a new Fetcher.
|
||||||
|
func NewConfigAPIFetcher() *ConfigAPIFetcher {
|
||||||
|
return &ConfigAPIFetcher{newFetcher()}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConfigAPIFetcherWithClient returns a new Fetcher with custom http client.
|
||||||
|
func NewConfigAPIFetcherWithClient(client HTTPClient) *ConfigAPIFetcher {
|
||||||
|
return &ConfigAPIFetcher{newFetcherWith(client)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchAzureSEVSNPVersionList fetches the version list information from the config API.
|
||||||
|
func (f *ConfigAPIFetcher) FetchAzureSEVSNPVersionList(ctx context.Context, attestation configapi.AzureSEVSNPVersionList) (configapi.AzureSEVSNPVersionList, error) {
|
||||||
|
return fetch(ctx, f.httpc, attestation)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchAzureSEVSNPVersion fetches the version information from the config API.
|
||||||
|
func (f *ConfigAPIFetcher) FetchAzureSEVSNPVersion(ctx context.Context, attestation configapi.AzureSEVSNPVersionGet) (configapi.AzureSEVSNPVersionGet, error) {
|
||||||
|
// TODO(elchead): follow-up PR for AB#3045 to check signature (sigstore.VerifySignature)
|
||||||
|
return fetch(ctx, f.httpc, attestation)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchLatestAzureSEVSNPVersion returns the latest versions of the given type.
|
||||||
|
func (f *ConfigAPIFetcher) FetchLatestAzureSEVSNPVersion(ctx context.Context) (res configapi.AzureSEVSNPVersion, err error) {
|
||||||
|
var versions configapi.AzureSEVSNPVersionList
|
||||||
|
versions, err = f.FetchAzureSEVSNPVersionList(ctx, versions)
|
||||||
|
if err != nil {
|
||||||
|
return res, fmt.Errorf("fetching versions list: %w", err)
|
||||||
|
}
|
||||||
|
get := configapi.AzureSEVSNPVersionGet{Version: versions[0]} // get latest version (as sorted reversely alphanumerically)
|
||||||
|
get, err = f.FetchAzureSEVSNPVersion(ctx, get)
|
||||||
|
if err != nil {
|
||||||
|
return res, fmt.Errorf("failed fetching version: %w", err)
|
||||||
|
}
|
||||||
|
return get.AzureSEVSNPVersion, nil
|
||||||
|
}
|
65
internal/api/fetcher/configapi_test.go
Normal file
65
internal/api/fetcher/configapi_test.go
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
package fetcher
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/configapi"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetVersion(t *testing.T) {
|
||||||
|
client := &http.Client{
|
||||||
|
Transport: &fakeConfigAPIHandler{},
|
||||||
|
}
|
||||||
|
fetcher := NewConfigAPIFetcherWithClient(client)
|
||||||
|
res, err := fetcher.FetchLatestAzureSEVSNPVersion(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, uint8(2), res.Bootloader)
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakeConfigAPIHandler struct{}
|
||||||
|
|
||||||
|
// RoundTrip resolves the request and returns a dummy response.
|
||||||
|
func (f *fakeConfigAPIHandler) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
if req.URL.Path == "/constellation/v1/attestation/azure-sev-snp/list" {
|
||||||
|
res := &http.Response{}
|
||||||
|
data := []string{"2021-01-01-01-01.json"}
|
||||||
|
bt, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res.Body = io.NopCloser(bytes.NewReader(bt))
|
||||||
|
res.Header = http.Header{}
|
||||||
|
res.Header.Set("Content-Type", "application/json")
|
||||||
|
res.StatusCode = http.StatusOK
|
||||||
|
return res, nil
|
||||||
|
} else if req.URL.Path == "/constellation/v1/attestation/azure-sev-snp/2021-01-01-01-01.json" {
|
||||||
|
res := &http.Response{}
|
||||||
|
bt, err := json.Marshal(configapi.AzureSEVSNPVersion{
|
||||||
|
Microcode: 93,
|
||||||
|
TEE: 0,
|
||||||
|
SNP: 6,
|
||||||
|
Bootloader: 2,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res.Body = io.NopCloser(bytes.NewReader(bt))
|
||||||
|
res.StatusCode = http.StatusOK
|
||||||
|
return res, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil, errors.New("no endpoint found")
|
||||||
|
}
|
|
@ -18,40 +18,26 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Fetcher fetches versions API resources without authentication.
|
// fetcher fetches versions API resources without authentication.
|
||||||
type Fetcher struct {
|
type fetcher struct {
|
||||||
httpc httpc
|
httpc HTTPClient
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFetcher returns a new Fetcher.
|
// NewHTTPClient returns a new http client.
|
||||||
func NewFetcher() *Fetcher {
|
func NewHTTPClient() HTTPClient {
|
||||||
return &Fetcher{
|
return &http.Client{Transport: &http.Transport{DisableKeepAlives: true}} // DisableKeepAlives fixes concurrency issue see https://stackoverflow.com/a/75816347
|
||||||
httpc: http.DefaultClient,
|
}
|
||||||
|
|
||||||
|
func newFetcherWith(client HTTPClient) *fetcher {
|
||||||
|
return &fetcher{
|
||||||
|
httpc: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchVersionList fetches the given version list from the versions API.
|
func newFetcher() *fetcher {
|
||||||
func (f *Fetcher) FetchVersionList(ctx context.Context, list versionsapi.List) (versionsapi.List, error) {
|
return newFetcherWith(NewHTTPClient()) // DisableKeepAlives fixes concurrency issue see https://stackoverflow.com/a/75816347
|
||||||
return fetch(ctx, f.httpc, list)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchVersionLatest fetches the latest version from the versions API.
|
|
||||||
func (f *Fetcher) FetchVersionLatest(ctx context.Context, latest versionsapi.Latest) (versionsapi.Latest, error) {
|
|
||||||
return fetch(ctx, f.httpc, latest)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchImageInfo fetches the given image info from the versions API.
|
|
||||||
func (f *Fetcher) FetchImageInfo(ctx context.Context, imageInfo versionsapi.ImageInfo) (versionsapi.ImageInfo, error) {
|
|
||||||
return fetch(ctx, f.httpc, imageInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchCLIInfo fetches the given cli info from the versions API.
|
|
||||||
func (f *Fetcher) FetchCLIInfo(ctx context.Context, cliInfo versionsapi.CLIInfo) (versionsapi.CLIInfo, error) {
|
|
||||||
return fetch(ctx, f.httpc, cliInfo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiObject interface {
|
type apiObject interface {
|
||||||
|
@ -60,7 +46,7 @@ type apiObject interface {
|
||||||
URL() (string, error)
|
URL() (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetch[T apiObject](ctx context.Context, c httpc, obj T) (T, error) {
|
func fetch[T apiObject](ctx context.Context, c HTTPClient, obj T) (T, error) {
|
||||||
if err := obj.ValidateRequest(); err != nil {
|
if err := obj.ValidateRequest(); err != nil {
|
||||||
return *new(T), fmt.Errorf("validating request for %T: %w", obj, err)
|
return *new(T), fmt.Errorf("validating request for %T: %w", obj, err)
|
||||||
}
|
}
|
||||||
|
@ -113,6 +99,7 @@ func (e *NotFoundError) Unwrap() error {
|
||||||
return e.err
|
return e.err
|
||||||
}
|
}
|
||||||
|
|
||||||
type httpc interface {
|
// HTTPClient is an interface for http clients.
|
||||||
|
type HTTPClient interface {
|
||||||
Do(req *http.Request) (*http.Response, error)
|
Do(req *http.Request) (*http.Response, error)
|
||||||
}
|
}
|
43
internal/api/fetcher/versionapi.go
Normal file
43
internal/api/fetcher/versionapi.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package fetcher
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// VersionAPIFetcher fetches version API resources without authentication.
|
||||||
|
type VersionAPIFetcher struct {
|
||||||
|
*fetcher
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVersionAPIFetcher returns a new Fetcher.
|
||||||
|
func NewVersionAPIFetcher() *VersionAPIFetcher {
|
||||||
|
return &VersionAPIFetcher{newFetcher()}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchVersionList fetches the given version list from the versions API.
|
||||||
|
func (f *VersionAPIFetcher) FetchVersionList(ctx context.Context, list versionsapi.List) (versionsapi.List, error) {
|
||||||
|
return fetch(ctx, f.httpc, list)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchVersionLatest fetches the latest version from the versions API.
|
||||||
|
func (f *VersionAPIFetcher) FetchVersionLatest(ctx context.Context, latest versionsapi.Latest) (versionsapi.Latest, error) {
|
||||||
|
return fetch(ctx, f.httpc, latest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchImageInfo fetches the given image info from the versions API.
|
||||||
|
func (f *VersionAPIFetcher) FetchImageInfo(ctx context.Context, imageInfo versionsapi.ImageInfo) (versionsapi.ImageInfo, error) {
|
||||||
|
return fetch(ctx, f.httpc, imageInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchCLIInfo fetches the given cli info from the versions API.
|
||||||
|
func (f *VersionAPIFetcher) FetchCLIInfo(ctx context.Context, cliInfo versionsapi.CLIInfo) (versionsapi.CLIInfo, error) {
|
||||||
|
return fetch(ctx, f.httpc, cliInfo)
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"go.uber.org/goleak"
|
"go.uber.org/goleak"
|
||||||
|
@ -190,7 +190,7 @@ func TestFetchVersionList(t *testing.T) {
|
||||||
return tc.serverResp
|
return tc.serverResp
|
||||||
})
|
})
|
||||||
|
|
||||||
fetcher := &Fetcher{httpc: client}
|
fetcher := VersionAPIFetcher{&fetcher{httpc: client}}
|
||||||
|
|
||||||
list, err := fetcher.FetchVersionList(context.Background(), tc.list)
|
list, err := fetcher.FetchVersionList(context.Background(), tc.list)
|
||||||
|
|
|
@ -12,7 +12,7 @@ go_library(
|
||||||
"version.go",
|
"version.go",
|
||||||
"versionsapi.go",
|
"versionsapi.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/versionsapi",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/api/versionsapi",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
"//internal/constants",
|
"//internal/constants",
|
|
@ -9,12 +9,12 @@ go_library(
|
||||||
"main.go",
|
"main.go",
|
||||||
"rm.go",
|
"rm.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/versionsapi/cli",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/api/versionsapi/cli",
|
||||||
visibility = ["//visibility:private"],
|
visibility = ["//visibility:private"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
|
"//internal/api/versionsapi/client",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/versionsapi",
|
|
||||||
"//internal/versionsapi/client",
|
|
||||||
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
||||||
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
|
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
|
||||||
"@com_github_aws_smithy_go//:smithy-go",
|
"@com_github_aws_smithy_go//:smithy-go",
|
|
@ -11,9 +11,9 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
|
verclient "github.com/edgelesssys/constellation/v2/internal/api/versionsapi/client"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
verclient "github.com/edgelesssys/constellation/v2/internal/versionsapi/client"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
"golang.org/x/mod/semver"
|
"golang.org/x/mod/semver"
|
|
@ -10,9 +10,9 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
|
verclient "github.com/edgelesssys/constellation/v2/internal/api/versionsapi/client"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
verclient "github.com/edgelesssys/constellation/v2/internal/versionsapi/client"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
)
|
)
|
|
@ -16,9 +16,9 @@ import (
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
"golang.org/x/mod/semver"
|
"golang.org/x/mod/semver"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
|
verclient "github.com/edgelesssys/constellation/v2/internal/api/versionsapi/client"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
verclient "github.com/edgelesssys/constellation/v2/internal/versionsapi/client"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newListCmd() *cobra.Command {
|
func newListCmd() *cobra.Command {
|
|
@ -24,9 +24,9 @@ import (
|
||||||
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/ec2"
|
"github.com/aws/aws-sdk-go-v2/service/ec2"
|
||||||
"github.com/aws/smithy-go"
|
"github.com/aws/smithy-go"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
|
verclient "github.com/edgelesssys/constellation/v2/internal/api/versionsapi/client"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
verclient "github.com/edgelesssys/constellation/v2/internal/versionsapi/client"
|
|
||||||
gaxv2 "github.com/googleapis/gax-go/v2"
|
gaxv2 "github.com/googleapis/gax-go/v2"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
|
@ -3,12 +3,12 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
go_library(
|
go_library(
|
||||||
name = "client",
|
name = "client",
|
||||||
srcs = ["client.go"],
|
srcs = ["client.go"],
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/versionsapi/client",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/api/versionsapi/client",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_aws_aws_sdk_go_v2//aws",
|
"@com_github_aws_aws_sdk_go_v2//aws",
|
||||||
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
||||||
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
|
@ -42,9 +42,9 @@ import (
|
||||||
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||||
"golang.org/x/mod/semver"
|
"golang.org/x/mod/semver"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client is the client for the versions API.
|
// Client is the client for the versions API.
|
|
@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
/*
|
/*
|
||||||
# Versions API
|
# Versions API
|
||||||
|
|
||||||
The Versions API is a provides information about versions of Constellation components.
|
The Versions API provides information about versions of Constellation components.
|
||||||
|
|
||||||
This package defines API types that represents objects of the versions API.
|
This package defines API types that represents objects of the versions API.
|
||||||
The types provide helper methods for validation and commonly used operations on the
|
The types provide helper methods for validation and commonly used operations on the
|
|
@ -148,7 +148,7 @@ func (v *Validator) validateSNPReport(
|
||||||
return errDebugEnabled
|
return errDebugEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
if !report.CommittedTCB.isVersion(v.config.BootloaderVersion, v.config.TEEVersion, v.config.SNPVersion, v.config.MicrocodeVersion) {
|
if !report.CommittedTCB.isVersion(v.config.BootloaderVersion.Value, v.config.TEEVersion.Value, v.config.SNPVersion.Value, v.config.MicrocodeVersion.Value) {
|
||||||
return &versionError{"COMMITTED_TCB", report.CommittedTCB}
|
return &versionError{"COMMITTED_TCB", report.CommittedTCB}
|
||||||
}
|
}
|
||||||
if report.LaunchTCB != report.CommittedTCB {
|
if report.LaunchTCB != report.CommittedTCB {
|
||||||
|
|
|
@ -348,7 +348,7 @@ func TestNewSNPReportFromBytes(t *testing.T) {
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
cfg := config.DefaultForAzureSEVSNP()
|
||||||
for name, tc := range testCases {
|
for name, tc := range testCases {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
@ -363,8 +363,7 @@ func TestNewSNPReportFromBytes(t *testing.T) {
|
||||||
assert.NotNil(report)
|
assert.NotNil(report)
|
||||||
assert.Equal(hex.EncodeToString(report.IDKeyDigest[:]), "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1")
|
assert.Equal(hex.EncodeToString(report.IDKeyDigest[:]), "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1")
|
||||||
// This is a canary for us: If this fails in the future we possibly downgraded a SVN.
|
// This is a canary for us: If this fails in the future we possibly downgraded a SVN.
|
||||||
cfg := config.DefaultForAzureSEVSNP()
|
assert.True(report.LaunchTCB.isVersion(cfg.BootloaderVersion.Value, cfg.TEEVersion.Value, cfg.SNPVersion.Value, cfg.MicrocodeVersion.Value))
|
||||||
assert.True(report.LaunchTCB.isVersion(cfg.BootloaderVersion, cfg.TEEVersion, cfg.SNPVersion, cfg.MicrocodeVersion))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/measurements",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/measurements",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/sigstore",
|
"//internal/sigstore",
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_google_go_tpm//tpmutil",
|
"@com_github_google_go_tpm//tpmutil",
|
||||||
"@com_github_siderolabs_talos_pkg_machinery//config/encoder",
|
"@com_github_siderolabs_talos_pkg_machinery//config/encoder",
|
||||||
"@in_gopkg_yaml_v3//:yaml_v3",
|
"@in_gopkg_yaml_v3//:yaml_v3",
|
||||||
|
@ -28,9 +28,9 @@ go_test(
|
||||||
srcs = ["measurements_test.go"],
|
srcs = ["measurements_test.go"],
|
||||||
embed = [":measurements"],
|
embed = [":measurements"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_siderolabs_talos_pkg_machinery//config/encoder",
|
"@com_github_siderolabs_talos_pkg_machinery//config/encoder",
|
||||||
"@com_github_stretchr_testify//assert",
|
"@com_github_stretchr_testify//assert",
|
||||||
"@com_github_stretchr_testify//require",
|
"@com_github_stretchr_testify//require",
|
||||||
|
|
|
@ -7,13 +7,13 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/measurements/measurement-generator",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/measurements/measurement-generator",
|
||||||
visibility = ["//visibility:private"],
|
visibility = ["//visibility:private"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/config",
|
"//internal/config",
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
"//internal/sigstore",
|
"//internal/sigstore",
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@org_golang_x_tools//go/ast/astutil",
|
"@org_golang_x_tools//go/ast/astutil",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,13 +23,13 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/sigstore"
|
"github.com/edgelesssys/constellation/v2/internal/sigstore"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
"golang.org/x/tools/go/ast/astutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,10 @@ import (
|
||||||
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/sigstore"
|
"github.com/edgelesssys/constellation/v2/internal/sigstore"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -20,9 +20,9 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMarshal(t *testing.T) {
|
func TestMarshal(t *testing.T) {
|
||||||
|
|
|
@ -18,18 +18,19 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/config",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/config",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/configapi",
|
||||||
|
"//internal/api/fetcher",
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/attestation/idkeydigest",
|
"//internal/attestation/idkeydigest",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/compatibility",
|
"//internal/compatibility",
|
||||||
"//internal/config/imageversion",
|
"//internal/config/imageversion",
|
||||||
"//internal/config/instancetypes",
|
"//internal/config/instancetypes",
|
||||||
"//internal/config/snpversion",
|
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
"//internal/file",
|
"//internal/file",
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versions",
|
"//internal/versions",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_go_playground_locales//en",
|
"@com_github_go_playground_locales//en",
|
||||||
"@com_github_go_playground_universal_translator//:universal-translator",
|
"@com_github_go_playground_universal_translator//:universal-translator",
|
||||||
"@com_github_go_playground_validator_v10//:validator",
|
"@com_github_go_playground_validator_v10//:validator",
|
||||||
|
@ -49,6 +50,7 @@ go_test(
|
||||||
data = glob(["testdata/**"]),
|
data = glob(["testdata/**"]),
|
||||||
embed = [":config"],
|
embed = [":config"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/configapi",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/config/instancetypes",
|
"//internal/config/instancetypes",
|
||||||
|
|
|
@ -8,14 +8,14 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/configapi"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/fetcher"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config/snpversion"
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,16 +26,16 @@ type AzureSEVSNP struct {
|
||||||
Measurements measurements.M `json:"measurements" yaml:"measurements" validate:"required,no_placeholders"`
|
Measurements measurements.M `json:"measurements" yaml:"measurements" validate:"required,no_placeholders"`
|
||||||
// description: |
|
// description: |
|
||||||
// Lowest acceptable bootloader version.
|
// Lowest acceptable bootloader version.
|
||||||
BootloaderVersion uint8 `json:"bootloaderVersion" yaml:"bootloaderVersion"`
|
BootloaderVersion configapi.AttestationVersion `json:"bootloaderVersion" yaml:"bootloaderVersion"`
|
||||||
// description: |
|
// description: |
|
||||||
// Lowest acceptable TEE version.
|
// Lowest acceptable TEE version.
|
||||||
TEEVersion uint8 `json:"teeVersion" yaml:"teeVersion"`
|
TEEVersion configapi.AttestationVersion `json:"teeVersion" yaml:"teeVersion"`
|
||||||
// description: |
|
// description: |
|
||||||
// Lowest acceptable SEV-SNP version.
|
// Lowest acceptable SEV-SNP version.
|
||||||
SNPVersion uint8 `json:"snpVersion" yaml:"snpVersion"`
|
SNPVersion configapi.AttestationVersion `json:"snpVersion" yaml:"snpVersion"`
|
||||||
// description: |
|
// description: |
|
||||||
// Lowest acceptable microcode version.
|
// Lowest acceptable microcode version.
|
||||||
MicrocodeVersion uint8 `json:"microcodeVersion" yaml:"microcodeVersion"`
|
MicrocodeVersion configapi.AttestationVersion `json:"microcodeVersion" yaml:"microcodeVersion"`
|
||||||
// description: |
|
// description: |
|
||||||
// Configuration for validating the firmware signature.
|
// Configuration for validating the firmware signature.
|
||||||
FirmwareSignerConfig SNPFirmwareSignerConfig `json:"firmwareSignerConfig" yaml:"firmwareSignerConfig"`
|
FirmwareSignerConfig SNPFirmwareSignerConfig `json:"firmwareSignerConfig" yaml:"firmwareSignerConfig"`
|
||||||
|
@ -45,14 +45,14 @@ type AzureSEVSNP struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultForAzureSEVSNP returns the default configuration for Azure SEV-SNP attestation.
|
// DefaultForAzureSEVSNP returns the default configuration for Azure SEV-SNP attestation.
|
||||||
// Version numbers are hard coded and should be updated with each new release.
|
// Version numbers have placeholder values and the latest available values can be fetched using [AzureSEVSNP.FetchAndSetLatestVersionNumbers].
|
||||||
func DefaultForAzureSEVSNP() *AzureSEVSNP {
|
func DefaultForAzureSEVSNP() *AzureSEVSNP {
|
||||||
return &AzureSEVSNP{
|
return &AzureSEVSNP{
|
||||||
Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureSEVSNP{}),
|
Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureSEVSNP{}),
|
||||||
BootloaderVersion: snpversion.GetLatest(snpversion.Bootloader),
|
BootloaderVersion: configapi.NewLatestPlaceholderVersion(),
|
||||||
TEEVersion: snpversion.GetLatest(snpversion.TEE),
|
TEEVersion: configapi.NewLatestPlaceholderVersion(),
|
||||||
SNPVersion: snpversion.GetLatest(snpversion.SNP),
|
SNPVersion: configapi.NewLatestPlaceholderVersion(),
|
||||||
MicrocodeVersion: snpversion.GetLatest(snpversion.Microcode),
|
MicrocodeVersion: configapi.NewLatestPlaceholderVersion(),
|
||||||
FirmwareSignerConfig: SNPFirmwareSignerConfig{
|
FirmwareSignerConfig: SNPFirmwareSignerConfig{
|
||||||
AcceptedKeyDigests: idkeydigest.DefaultList(),
|
AcceptedKeyDigests: idkeydigest.DefaultList(),
|
||||||
EnforcementPolicy: idkeydigest.MAAFallback,
|
EnforcementPolicy: idkeydigest.MAAFallback,
|
||||||
|
@ -95,26 +95,25 @@ func (c AzureSEVSNP) EqualTo(old AttestationCfg) (bool, error) {
|
||||||
return firmwareSignerCfgEqual && measurementsEqual && bootloaderEqual && teeEqual && snpEqual && microcodeEqual && rootKeyEqual, nil
|
return firmwareSignerCfgEqual && measurementsEqual && bootloaderEqual && teeEqual && snpEqual && microcodeEqual && rootKeyEqual, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalYAML implements a custom unmarshaler to support setting "latest" as version.
|
// FetchAndSetLatestVersionNumbers fetches the latest version numbers from the configapi and sets them.
|
||||||
func (c *AzureSEVSNP) UnmarshalYAML(unmarshal func(any) error) error {
|
func (c *AzureSEVSNP) FetchAndSetLatestVersionNumbers(client fetcher.HTTPClient) error {
|
||||||
aux := &fusedAzureSEVSNP{
|
fetcher := fetcher.NewConfigAPIFetcherWithClient(client)
|
||||||
auxAzureSEVSNP: (*auxAzureSEVSNP)(c),
|
versions, err := fetcher.FetchLatestAzureSEVSNPVersion(context.Background())
|
||||||
}
|
if err != nil {
|
||||||
if err := unmarshal(aux); err != nil {
|
return err
|
||||||
return fmt.Errorf("unmarshal AzureSEVSNP: %w", err)
|
|
||||||
}
|
|
||||||
c = (*AzureSEVSNP)(aux.auxAzureSEVSNP)
|
|
||||||
|
|
||||||
for _, versionType := range []snpversion.Type{snpversion.Bootloader, snpversion.TEE, snpversion.SNP, snpversion.Microcode} {
|
|
||||||
if !convertLatestToNumber(c, versionType, aux) {
|
|
||||||
if err := convertStringToUint(c, versionType, aux); err != nil {
|
|
||||||
return fmt.Errorf("convert %s version to number: %w", versionType, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// set number and keep isLatest flag
|
||||||
|
c.mergeVersionNumbers(versions)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *AzureSEVSNP) mergeVersionNumbers(versions configapi.AzureSEVSNPVersion) {
|
||||||
|
c.BootloaderVersion.Value = versions.Bootloader
|
||||||
|
c.TEEVersion.Value = versions.TEE
|
||||||
|
c.SNPVersion.Value = versions.SNP
|
||||||
|
c.MicrocodeVersion.Value = versions.Microcode
|
||||||
|
}
|
||||||
|
|
||||||
// AzureTrustedLaunch is the configuration for Azure Trusted Launch attestation.
|
// AzureTrustedLaunch is the configuration for Azure Trusted Launch attestation.
|
||||||
type AzureTrustedLaunch struct {
|
type AzureTrustedLaunch struct {
|
||||||
// description: |
|
// description: |
|
||||||
|
@ -145,84 +144,3 @@ func (c AzureTrustedLaunch) EqualTo(other AttestationCfg) (bool, error) {
|
||||||
}
|
}
|
||||||
return c.Measurements.EqualTo(otherCfg.Measurements), nil
|
return c.Measurements.EqualTo(otherCfg.Measurements), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// auxAzureSEVSNP is a helper struct for unmarshaling the config from YAML for handling the version parsing.
|
|
||||||
// The version fields are kept to make it convertable to the native AzureSEVSNP struct.
|
|
||||||
type auxAzureSEVSNP struct {
|
|
||||||
// description: |
|
|
||||||
// Expected TPM measurements.
|
|
||||||
Measurements measurements.M `json:"measurements" yaml:"measurements" validate:"required,no_placeholders"`
|
|
||||||
// description: |
|
|
||||||
// Lowest acceptable bootloader version.
|
|
||||||
BootloaderVersion uint8 `yaml:"-"`
|
|
||||||
// description: |
|
|
||||||
// Lowest acceptable TEE version.
|
|
||||||
TEEVersion uint8 `json:"teeVersion" yaml:"-"`
|
|
||||||
// description: |
|
|
||||||
// Lowest acceptable SEV-SNP version.
|
|
||||||
SNPVersion uint8 `json:"snpVersion" yaml:"-"`
|
|
||||||
// description: |
|
|
||||||
// Lowest acceptable microcode version.
|
|
||||||
MicrocodeVersion uint8 `json:"microcodeVersion" yaml:"-"`
|
|
||||||
// description: |
|
|
||||||
// Configuration for validating the firmware signature.
|
|
||||||
FirmwareSignerConfig SNPFirmwareSignerConfig `json:"firmwareSignerConfig" yaml:"firmwareSignerConfig"`
|
|
||||||
// description: |
|
|
||||||
// AMD Root Key certificate used to verify the SEV-SNP certificate chain.
|
|
||||||
AMDRootKey Certificate `json:"amdRootKey" yaml:"amdRootKey"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// fusedAzureSEVSNP is a helper struct for unmarshaling the config from YAML for handling the version parsing.
|
|
||||||
type fusedAzureSEVSNP struct {
|
|
||||||
*auxAzureSEVSNP `yaml:",inline"`
|
|
||||||
// description: |
|
|
||||||
// Lowest acceptable bootloader version.
|
|
||||||
BootloaderVersion string `yaml:"bootloaderVersion"`
|
|
||||||
// description: |
|
|
||||||
// Lowest acceptable bootloader version.
|
|
||||||
TEEVersion string `yaml:"teeVersion"`
|
|
||||||
// description: |
|
|
||||||
// Lowest acceptable bootloader version.
|
|
||||||
SNPVersion string `yaml:"snpVersion"`
|
|
||||||
// description: |
|
|
||||||
// Lowest acceptable bootloader version.
|
|
||||||
MicrocodeVersion string `yaml:"microcodeVersion"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertStringToUint(c *AzureSEVSNP, versionType snpversion.Type, aux *fusedAzureSEVSNP) error {
|
|
||||||
v, stringV := getUintAndStringPtrToVersion(c, versionType, aux)
|
|
||||||
|
|
||||||
bvInt, err := strconv.ParseInt(*stringV, 10, 8)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*v = uint8(bvInt)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertLatestToNumber(c *AzureSEVSNP, versionType snpversion.Type, aux *fusedAzureSEVSNP) bool {
|
|
||||||
v, stringV := getUintAndStringPtrToVersion(c, versionType, aux)
|
|
||||||
if strings.ToLower(*stringV) == "latest" {
|
|
||||||
*v = snpversion.GetLatest(versionType)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUintAndStringPtrToVersion(c *AzureSEVSNP, versionType snpversion.Type, aux *fusedAzureSEVSNP) (versionUint *uint8, versionString *string) {
|
|
||||||
switch versionType {
|
|
||||||
case snpversion.Bootloader:
|
|
||||||
versionUint = &c.BootloaderVersion
|
|
||||||
versionString = &aux.BootloaderVersion
|
|
||||||
case snpversion.TEE:
|
|
||||||
versionUint = &c.TEEVersion
|
|
||||||
versionString = &aux.TEEVersion
|
|
||||||
case snpversion.SNP:
|
|
||||||
versionUint = &c.SNPVersion
|
|
||||||
versionString = &aux.SNPVersion
|
|
||||||
case snpversion.Microcode:
|
|
||||||
versionUint = &c.MicrocodeVersion
|
|
||||||
versionString = &aux.MicrocodeVersion
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import (
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
en_translations "github.com/go-playground/validator/v10/translations/en"
|
en_translations "github.com/go-playground/validator/v10/translations/en"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/fetcher"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
|
@ -381,14 +382,25 @@ func fromFile(fileHandler file.Handler, name string) (*Config, error) {
|
||||||
|
|
||||||
// New creates a new config by:
|
// New creates a new config by:
|
||||||
// 1. Reading config file via provided fileHandler from file with name.
|
// 1. Reading config file via provided fileHandler from file with name.
|
||||||
// 2. Read secrets from environment variables.
|
// 2. For "latest" version values of the attestation variants fetch the version numbers.
|
||||||
// 3. Validate config. If `--force` is set the version validation will be disabled and any version combination is allowed.
|
// 3. Read secrets from environment variables.
|
||||||
|
// 4. Validate config. If `--force` is set the version validation will be disabled and any version combination is allowed.
|
||||||
func New(fileHandler file.Handler, name string, force bool) (*Config, error) {
|
func New(fileHandler file.Handler, name string, force bool) (*Config, error) {
|
||||||
|
return NewWithClient(fileHandler, name, fetcher.NewHTTPClient(), force)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWithClient is New with a custom HTTP client.
|
||||||
|
func NewWithClient(fileHandler file.Handler, name string, client fetcher.HTTPClient, force bool) (*Config, error) {
|
||||||
// Read config file
|
// Read config file
|
||||||
c, err := fromFile(fileHandler, name)
|
c, err := fromFile(fileHandler, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if azure := c.Attestation.AzureSEVSNP; azure != nil {
|
||||||
|
if err := azure.FetchAndSetLatestVersionNumbers(client); err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read secrets from env-vars.
|
// Read secrets from env-vars.
|
||||||
clientSecretValue := os.Getenv(constants.EnvVarAzureClientSecretValue)
|
clientSecretValue := os.Getenv(constants.EnvVarAzureClientSecretValue)
|
||||||
|
|
|
@ -7,7 +7,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -20,6 +24,7 @@ import (
|
||||||
"go.uber.org/goleak"
|
"go.uber.org/goleak"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/configapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config/instancetypes"
|
"github.com/edgelesssys/constellation/v2/internal/config/instancetypes"
|
||||||
|
@ -37,37 +42,57 @@ func TestDefaultConfig(t *testing.T) {
|
||||||
assert.NotNil(def)
|
assert.NotNil(def)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSettingLatestAsVersion(t *testing.T) {
|
func TestDefaultConfigWritesLatestVersion(t *testing.T) {
|
||||||
|
conf := Default()
|
||||||
|
bt, err := yaml.Marshal(conf)
|
||||||
|
require := require.New(t)
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
var mp configMap
|
||||||
|
require.NoError(yaml.Unmarshal(bt, &mp))
|
||||||
|
assert := assert.New(t)
|
||||||
|
assert.Equal("latest", mp.getAzureSEVSNPVersion("microcodeVersion"))
|
||||||
|
assert.Equal("latest", mp.getAzureSEVSNPVersion("teeVersion"))
|
||||||
|
assert.Equal("latest", mp.getAzureSEVSNPVersion("snpVersion"))
|
||||||
|
assert.Equal("latest", mp.getAzureSEVSNPVersion("bootloaderVersion"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadConfigFile(t *testing.T) {
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
config map[string]interface{}
|
config configMap
|
||||||
configName string
|
configName string
|
||||||
wantResult *Config
|
wantResult *Config
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"mix of latest and uint as version value": {
|
"mix of Latest and uint as version value": {
|
||||||
config: func() map[string]interface{} {
|
config: func() configMap {
|
||||||
conf := Default()
|
conf := Default()
|
||||||
// modify versions as string
|
|
||||||
m := getConfigAsMap(conf, t)
|
m := getConfigAsMap(conf, t)
|
||||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["microcodeVersion"] = "latest"
|
m.setAzureSEVSNPVersion("microcodeVersion", "Latest") // check uppercase also works
|
||||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["teeVersion"] = "latest"
|
m.setAzureSEVSNPVersion("teeVersion", 2)
|
||||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["snpVersion"] = "latest"
|
m.setAzureSEVSNPVersion("bootloaderVersion", 1)
|
||||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["bootloaderVersion"] = 1
|
|
||||||
return m
|
return m
|
||||||
}(),
|
}(),
|
||||||
|
|
||||||
configName: constants.ConfigFilename,
|
configName: constants.ConfigFilename,
|
||||||
wantResult: func() *Config {
|
wantResult: func() *Config {
|
||||||
conf := Default()
|
conf := Default()
|
||||||
conf.Attestation.AzureSEVSNP.BootloaderVersion = 1
|
conf.Attestation.AzureSEVSNP.BootloaderVersion = configapi.AttestationVersion{
|
||||||
|
Value: 1,
|
||||||
|
IsLatest: false,
|
||||||
|
}
|
||||||
|
conf.Attestation.AzureSEVSNP.TEEVersion = configapi.AttestationVersion{
|
||||||
|
Value: 2,
|
||||||
|
IsLatest: false,
|
||||||
|
}
|
||||||
return conf
|
return conf
|
||||||
}(),
|
}(),
|
||||||
},
|
},
|
||||||
"refuse invalid version value": {
|
"refuse invalid version value": {
|
||||||
config: func() map[string]interface{} {
|
config: func() configMap {
|
||||||
conf := Default()
|
conf := Default()
|
||||||
m := getConfigAsMap(conf, t)
|
m := getConfigAsMap(conf, t)
|
||||||
m["attestation"].(map[string]interface{})["azureSEVSNP"].(map[string]interface{})["microcodeVersion"] = "1a"
|
m.setAzureSEVSNPVersion("microcodeVersion", "1a")
|
||||||
return m
|
return m
|
||||||
}(),
|
}(),
|
||||||
configName: constants.ConfigFilename,
|
configName: constants.ConfigFilename,
|
||||||
|
@ -84,29 +109,16 @@ func TestSettingLatestAsVersion(t *testing.T) {
|
||||||
require.NoError(fileHandler.WriteYAML(tc.configName, tc.config, file.OptNone))
|
require.NoError(fileHandler.WriteYAML(tc.configName, tc.config, file.OptNone))
|
||||||
}
|
}
|
||||||
result, err := fromFile(fileHandler, tc.configName)
|
result, err := fromFile(fileHandler, tc.configName)
|
||||||
|
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
} else {
|
} else {
|
||||||
require.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal(tc.wantResult, result)
|
assert.Equal(tc.wantResult, result)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getConfigAsMap returns a map of the config.
|
|
||||||
func getConfigAsMap(conf *Config, t *testing.T) (res map[string]interface{}) {
|
|
||||||
bytes, err := yaml.Marshal(&conf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := yaml.Unmarshal(bytes, &res); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFromFile(t *testing.T) {
|
func TestFromFile(t *testing.T) {
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
config *Config
|
config *Config
|
||||||
|
@ -233,7 +245,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
|
||||||
wantClientSecretValue: "some-secret",
|
wantClientSecretValue: "some-secret",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
client := newTestClient(&fakeConfigAPIHandler{})
|
||||||
for name, tc := range testCases {
|
for name, tc := range testCases {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
@ -248,8 +260,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
c, err := New(fileHandler, constants.ConfigFilename, false)
|
c, err := NewWithClient(fileHandler, constants.ConfigFilename, client, false)
|
||||||
|
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
return
|
return
|
||||||
|
@ -846,3 +857,68 @@ func TestConfigVersionCompatibility(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// configMap is used to un-/marshal the config as an unstructured map.
|
||||||
|
type configMap map[string]interface{}
|
||||||
|
|
||||||
|
func (c configMap) setAzureSEVSNPVersion(versionType string, value interface{}) {
|
||||||
|
c["attestation"].(configMap)["azureSEVSNP"].(configMap)[versionType] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c configMap) getAzureSEVSNPVersion(versionType string) interface{} {
|
||||||
|
return c["attestation"].(configMap)["azureSEVSNP"].(configMap)[versionType]
|
||||||
|
}
|
||||||
|
|
||||||
|
// getConfigAsMap returns a map of the config.
|
||||||
|
func getConfigAsMap(conf *Config, t *testing.T) (res configMap) {
|
||||||
|
bytes, err := yaml.Marshal(&conf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := yaml.Unmarshal(bytes, &res); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakeConfigAPIHandler struct{}
|
||||||
|
|
||||||
|
// RoundTrip resolves the request and returns a dummy response.
|
||||||
|
func (f *fakeConfigAPIHandler) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
if req.URL.Path == "/constellation/v1/attestation/azure-sev-snp/list" {
|
||||||
|
res := &http.Response{}
|
||||||
|
data := []string{"2021-01-01-01-01.json"}
|
||||||
|
bt, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res.Body = io.NopCloser(bytes.NewReader(bt))
|
||||||
|
res.Header = http.Header{}
|
||||||
|
res.Header.Set("Content-Type", "application/json")
|
||||||
|
res.StatusCode = http.StatusOK
|
||||||
|
return res, nil
|
||||||
|
} else if req.URL.Path == "/constellation/v1/attestation/azure-sev-snp/2021-01-01-01-01.json" {
|
||||||
|
res := &http.Response{}
|
||||||
|
bt, err := json.Marshal(configapi.AzureSEVSNPVersion{
|
||||||
|
Microcode: 93,
|
||||||
|
TEE: 0,
|
||||||
|
SNP: 6,
|
||||||
|
Bootloader: 2,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res.Body = io.NopCloser(bytes.NewReader(bt))
|
||||||
|
res.StatusCode = http.StatusOK
|
||||||
|
return res, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil, errors.New("no endpoint found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// newTestClient returns *http.Client with Transport replaced to avoid making real calls.
|
||||||
|
func newTestClient(fn *fakeConfigAPIHandler) *http.Client {
|
||||||
|
return &http.Client{
|
||||||
|
Transport: fn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "snpversion",
|
|
||||||
srcs = ["snpversion.go"],
|
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/config/snpversion",
|
|
||||||
visibility = ["//:__subpackages__"],
|
|
||||||
)
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) Edgeless Systems GmbH
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package snpversion
|
|
||||||
|
|
||||||
const (
|
|
||||||
Bootloader Type = "bootloader" // Bootloader is the version of the Azure SEVSNP bootloader.
|
|
||||||
TEE Type = "tee" // TEE is the version of the Azure SEVSNP TEE.
|
|
||||||
SNP Type = "snp" // SNP is the version of the Azure SEVSNP SNP.
|
|
||||||
Microcode Type = "microcode" // Microcode is the version of the Azure SEVSNP microcode.
|
|
||||||
)
|
|
||||||
|
|
||||||
// Type is the type of the version to be requested.
|
|
||||||
type Type string
|
|
||||||
|
|
||||||
// GetLatest returns the version of the given type.
|
|
||||||
func GetLatest(t Type) uint8 {
|
|
||||||
switch t {
|
|
||||||
case Bootloader:
|
|
||||||
return 2
|
|
||||||
case TEE:
|
|
||||||
return 0
|
|
||||||
case SNP:
|
|
||||||
return 6
|
|
||||||
case Microcode:
|
|
||||||
return 93
|
|
||||||
default:
|
|
||||||
panic("invalid version type")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"golang.org/x/mod/semver"
|
"golang.org/x/mod/semver"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
||||||
|
@ -26,7 +27,6 @@ import (
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versions"
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ValidationError occurs when the validation of a config fails.
|
// ValidationError occurs when the validation of a config fails.
|
||||||
|
|
|
@ -10,10 +10,10 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/imagefetcher",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/imagefetcher",
|
||||||
visibility = ["//cli:__subpackages__"],
|
visibility = ["//cli:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/fetcher",
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versionsapi",
|
|
||||||
"//internal/versionsapi/fetcher",
|
|
||||||
"@com_github_schollz_progressbar_v3//:progressbar",
|
"@com_github_schollz_progressbar_v3//:progressbar",
|
||||||
"@com_github_spf13_afero//:afero",
|
"@com_github_spf13_afero//:afero",
|
||||||
],
|
],
|
||||||
|
@ -27,10 +27,10 @@ go_test(
|
||||||
],
|
],
|
||||||
embed = [":imagefetcher"],
|
embed = [":imagefetcher"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/file",
|
"//internal/file",
|
||||||
"//internal/variant",
|
"//internal/variant",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_spf13_afero//:afero",
|
"@com_github_spf13_afero//:afero",
|
||||||
"@com_github_stretchr_testify//assert",
|
"@com_github_stretchr_testify//assert",
|
||||||
"@com_github_stretchr_testify//require",
|
"@com_github_stretchr_testify//require",
|
||||||
|
|
|
@ -19,10 +19,10 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/fetcher"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi/fetcher"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ type Fetcher struct {
|
||||||
// New returns a new image fetcher.
|
// New returns a new image fetcher.
|
||||||
func New() *Fetcher {
|
func New() *Fetcher {
|
||||||
return &Fetcher{
|
return &Fetcher{
|
||||||
fetcher: fetcher.NewFetcher(),
|
fetcher: fetcher.NewVersionAPIFetcher(),
|
||||||
fs: &afero.Afero{Fs: afero.NewOsFs()},
|
fs: &afero.Afero{Fs: afero.NewOsFs()},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/variant"
|
"github.com/edgelesssys/constellation/v2/internal/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
|
@ -27,6 +27,7 @@ type awsS3ClientAPI interface {
|
||||||
GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error)
|
GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error)
|
||||||
PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error)
|
PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error)
|
||||||
CreateBucket(ctx context.Context, params *s3.CreateBucketInput, optFns ...func(*s3.Options)) (*s3.CreateBucketOutput, error)
|
CreateBucket(ctx context.Context, params *s3.CreateBucketInput, optFns ...func(*s3.Options)) (*s3.CreateBucketOutput, error)
|
||||||
|
DeleteObject(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Storage is an implementation of the Storage interface, storing keys in AWS S3 buckets.
|
// Storage is an implementation of the Storage interface, storing keys in AWS S3 buckets.
|
||||||
|
@ -76,6 +77,18 @@ func (s *Storage) Get(ctx context.Context, keyID string) ([]byte, error) {
|
||||||
return io.ReadAll(output.Body)
|
return io.ReadAll(output.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete removes a DEK from AWS S3 Storage by key ID.
|
||||||
|
func (s *Storage) Delete(ctx context.Context, keyID string) error {
|
||||||
|
deleteObjectInput := &s3.DeleteObjectInput{
|
||||||
|
Bucket: &s.bucketID,
|
||||||
|
Key: &keyID,
|
||||||
|
}
|
||||||
|
if _, err := s.client.DeleteObject(ctx, deleteObjectInput); err != nil {
|
||||||
|
return fmt.Errorf("deleting DEK from storage: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Put saves a DEK to AWS S3 Storage by key ID.
|
// Put saves a DEK to AWS S3 Storage by key ID.
|
||||||
func (s *Storage) Put(ctx context.Context, keyID string, data []byte) error {
|
func (s *Storage) Put(ctx context.Context, keyID string, data []byte) error {
|
||||||
putObjectInput := &s3.PutObjectInput{
|
putObjectInput := &s3.PutObjectInput{
|
||||||
|
|
|
@ -43,6 +43,10 @@ func (s *stubAWSS3StorageClient) PutObject(_ context.Context, params *s3.PutObje
|
||||||
return &s3.PutObjectOutput{}, s.putObjectErr
|
return &s3.PutObjectOutput{}, s.putObjectErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *stubAWSS3StorageClient) DeleteObject(_ context.Context, _ *s3.DeleteObjectInput, _ ...func(*s3.Options)) (*s3.DeleteObjectOutput, error) {
|
||||||
|
return &s3.DeleteObjectOutput{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *stubAWSS3StorageClient) CreateBucket(_ context.Context, _ *s3.CreateBucketInput, _ ...func(*s3.Options)) (*s3.CreateBucketOutput, error) {
|
func (s *stubAWSS3StorageClient) CreateBucket(_ context.Context, _ *s3.CreateBucketInput, _ ...func(*s3.Options)) (*s3.CreateBucketOutput, error) {
|
||||||
s.createBucketCalled = true
|
s.createBucketCalled = true
|
||||||
return &s3.CreateBucketOutput{}, s.createBucketErr
|
return &s3.CreateBucketOutput{}, s.createBucketErr
|
||||||
|
|
|
@ -6,8 +6,8 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/osimage/secureboot",
|
"//internal/osimage/secureboot",
|
||||||
"//internal/versionsapi",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,9 +6,9 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/archive",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/archive",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
||||||
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
||||||
"@com_github_aws_aws_sdk_go_v2_service_s3//:s3",
|
"@com_github_aws_aws_sdk_go_v2_service_s3//:s3",
|
||||||
|
|
|
@ -16,9 +16,9 @@ import (
|
||||||
s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Archivist uploads OS images to S3.
|
// Archivist uploads OS images to S3.
|
||||||
|
|
|
@ -6,10 +6,10 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/aws",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/aws",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/osimage",
|
"//internal/osimage",
|
||||||
"//internal/osimage/secureboot",
|
"//internal/osimage/secureboot",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
||||||
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
||||||
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
|
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
|
||||||
|
|
|
@ -23,10 +23,10 @@ import (
|
||||||
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||||
"github.com/aws/smithy-go"
|
"github.com/aws/smithy-go"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/osimage/secureboot"
|
"github.com/edgelesssys/constellation/v2/internal/osimage/secureboot"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Uploader can upload and remove os images on GCP.
|
// Uploader can upload and remove os images on GCP.
|
||||||
|
|
|
@ -9,9 +9,9 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/azure",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/azure",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/osimage",
|
"//internal/osimage",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_azure_azure_sdk_for_go_sdk_azcore//runtime",
|
"@com_github_azure_azure_sdk_for_go_sdk_azcore//runtime",
|
||||||
"@com_github_azure_azure_sdk_for_go_sdk_azidentity//:azidentity",
|
"@com_github_azure_azure_sdk_for_go_sdk_azidentity//:azidentity",
|
||||||
"@com_github_azure_azure_sdk_for_go_sdk_resourcemanager_compute_armcompute_v4//:armcompute",
|
"@com_github_azure_azure_sdk_for_go_sdk_resourcemanager_compute_armcompute_v4//:armcompute",
|
||||||
|
|
|
@ -21,9 +21,9 @@ import (
|
||||||
armcomputev4 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4"
|
armcomputev4 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4"
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
|
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/pageblob"
|
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/pageblob"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Uploader can upload and remove os images on Azure.
|
// Uploader can upload and remove os images on Azure.
|
||||||
|
|
|
@ -6,10 +6,10 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/gcp",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/gcp",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/osimage",
|
"//internal/osimage",
|
||||||
"//internal/osimage/secureboot",
|
"//internal/osimage/secureboot",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_googleapis_gax_go_v2//:gax-go",
|
"@com_github_googleapis_gax_go_v2//:gax-go",
|
||||||
"@com_google_cloud_go_compute//apiv1",
|
"@com_google_cloud_go_compute//apiv1",
|
||||||
"@com_google_cloud_go_compute//apiv1/computepb",
|
"@com_google_cloud_go_compute//apiv1/computepb",
|
||||||
|
|
|
@ -19,10 +19,10 @@ import (
|
||||||
compute "cloud.google.com/go/compute/apiv1"
|
compute "cloud.google.com/go/compute/apiv1"
|
||||||
"cloud.google.com/go/compute/apiv1/computepb"
|
"cloud.google.com/go/compute/apiv1/computepb"
|
||||||
"cloud.google.com/go/storage"
|
"cloud.google.com/go/storage"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/osimage/secureboot"
|
"github.com/edgelesssys/constellation/v2/internal/osimage/secureboot"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
gaxv2 "github.com/googleapis/gax-go/v2"
|
gaxv2 "github.com/googleapis/gax-go/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/imageinfo",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/imageinfo",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
||||||
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
||||||
"@com_github_aws_aws_sdk_go_v2_service_s3//:s3",
|
"@com_github_aws_aws_sdk_go_v2_service_s3//:s3",
|
||||||
|
|
|
@ -17,9 +17,9 @@ import (
|
||||||
s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Uploader uploads image info to S3.
|
// Uploader uploads image info to S3.
|
||||||
|
|
|
@ -6,10 +6,10 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/measurementsuploader",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/measurementsuploader",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/attestation/measurements",
|
"//internal/attestation/measurements",
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/versionsapi",
|
|
||||||
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
||||||
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
"@com_github_aws_aws_sdk_go_v2_feature_s3_manager//:manager",
|
||||||
"@com_github_aws_aws_sdk_go_v2_service_s3//:s3",
|
"@com_github_aws_aws_sdk_go_v2_service_s3//:s3",
|
||||||
|
|
|
@ -18,10 +18,10 @@ import (
|
||||||
s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Uploader uploads image info to S3.
|
// Uploader uploads image info to S3.
|
||||||
|
|
|
@ -6,8 +6,8 @@ go_library(
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/nop",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/nop",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//internal/api/versionsapi",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/osimage",
|
"//internal/osimage",
|
||||||
"//internal/versionsapi",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,9 +10,9 @@ package nop
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
"github.com/edgelesssys/constellation/v2/internal/osimage"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Uploader is a no-op uploader.
|
// Uploader is a no-op uploader.
|
||||||
|
|
|
@ -11,9 +11,9 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/osimage/secureboot"
|
"github.com/edgelesssys/constellation/v2/internal/osimage/secureboot"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// UploadRequest is a request to upload an os image.
|
// UploadRequest is a request to upload an os image.
|
||||||
|
|
|
@ -82,7 +82,7 @@ func GetAvailableAttestationTypes() []Variant {
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
res = append(res, providerAttestationMapping[k]...)
|
res = append(res, providerAttestationMapping[k]...)
|
||||||
}
|
}
|
||||||
return removeDuplicate(res)
|
return RemoveDuplicate(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getter returns an ASN.1 Object Identifier.
|
// Getter returns an ASN.1 Object Identifier.
|
||||||
|
@ -259,9 +259,10 @@ func (QEMUTDX) Equal(other Getter) bool {
|
||||||
return other.OID().Equal(QEMUTDX{}.OID())
|
return other.OID().Equal(QEMUTDX{}.OID())
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeDuplicate(sliceList []Variant) []Variant {
|
// RemoveDuplicate removes duplicate elements from a slice.
|
||||||
allKeys := make(map[Variant]bool)
|
func RemoveDuplicate[T comparable](sliceList []T) []T {
|
||||||
list := []Variant{}
|
allKeys := make(map[T]bool)
|
||||||
|
list := []T{}
|
||||||
for _, item := range sliceList {
|
for _, item := range sliceList {
|
||||||
if _, value := allKeys[item]; !value {
|
if _, value := allKeys[item]; !value {
|
||||||
allKeys[item] = true
|
allKeys[item] = true
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue