mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-08-02 03:56:07 -04:00
Configapi: pipeline to run e2e test for CLI
Co-authored-by: Paul Meyer <pm@edgeless.systems>
This commit is contained in:
parent
d2071e945a
commit
7ffa1344e3
9 changed files with 214 additions and 120 deletions
|
@ -1,5 +1,6 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
|
||||
load("//bazel/go:go_test.bzl", "go_test")
|
||||
load("//bazel/sh:def.bzl", "sh_template")
|
||||
|
||||
go_library(
|
||||
name = "configapi_lib",
|
||||
|
@ -11,6 +12,7 @@ go_library(
|
|||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//internal/api/attestationconfigapi",
|
||||
"//internal/constants",
|
||||
"//internal/logger",
|
||||
"//internal/staticupload",
|
||||
"@com_github_spf13_cobra//:cobra",
|
||||
|
@ -37,3 +39,12 @@ go_test(
|
|||
"@com_github_stretchr_testify//require",
|
||||
],
|
||||
)
|
||||
|
||||
sh_template(
|
||||
name = "configapi_e2e_test",
|
||||
data = [":configapi"],
|
||||
substitutions = {
|
||||
"@@CONFIGAPI_CLI@@": "$(rootpath :configapi)",
|
||||
},
|
||||
template = "e2e/test.sh.in",
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
|
@ -44,7 +45,7 @@ func (d deleteCmd) delete(cmd *cobra.Command) error {
|
|||
return d.attestationClient.DeleteAzureSEVSNPVersion(cmd.Context(), version)
|
||||
}
|
||||
|
||||
func runDelete(cmd *cobra.Command, _ []string) error {
|
||||
func runDelete(cmd *cobra.Command, _ []string) (retErr error) {
|
||||
log := logger.New(logger.PlainLog, zap.DebugLevel).Named("attestationconfigapi")
|
||||
|
||||
region, err := cmd.Flags().GetString("region")
|
||||
|
@ -57,19 +58,27 @@ func runDelete(cmd *cobra.Command, _ []string) error {
|
|||
return fmt.Errorf("getting bucket: %w", err)
|
||||
}
|
||||
|
||||
cfg := staticupload.Config{
|
||||
Bucket: bucket,
|
||||
Region: region,
|
||||
distribution, err := cmd.Flags().GetString("distribution")
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting distribution: %w", err)
|
||||
}
|
||||
client, stop, err := attestationconfigapi.NewClient(cmd.Context(), cfg, []byte(cosignPwd), []byte(privateKey), false, log)
|
||||
|
||||
cfg := staticupload.Config{
|
||||
Bucket: bucket,
|
||||
Region: region,
|
||||
DistributionID: distribution,
|
||||
}
|
||||
client, clientClose, err := attestationconfigapi.NewClient(cmd.Context(), cfg, []byte(cosignPwd), []byte(privateKey), false, log)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create attestation client: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := stop(cmd.Context()); err != nil {
|
||||
cmd.Printf("stopping client: %s\n", err.Error())
|
||||
err := clientClose(cmd.Context())
|
||||
if err != nil {
|
||||
retErr = errors.Join(retErr, fmt.Errorf("failed to invalidate cache: %w", err))
|
||||
}
|
||||
}()
|
||||
|
||||
deleteCmd := deleteCmd{
|
||||
attestationClient: client,
|
||||
}
|
||||
|
|
74
hack/configapi/e2e/test.sh.in
Executable file
74
hack/configapi/e2e/test.sh.in
Executable file
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Try to upload a file to S3 and then delete it using the configapi cli.
|
||||
# Check the file exists after uploading it.
|
||||
# Check the file does not exist after deleting it.
|
||||
|
||||
###### script header ######
|
||||
|
||||
lib=$(realpath @@BASE_LIB@@) || exit 1
|
||||
stat "${lib}" >> /dev/null || exit 1
|
||||
|
||||
# shellcheck source=../../../bazel/sh/lib.bash
|
||||
if ! source "${lib}"; then
|
||||
echo "Error: could not find import"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
configapi_cli=$(realpath @@CONFIGAPI_CLI@@)
|
||||
stat "${configapi_cli}" >> /dev/null
|
||||
|
||||
###### script body ######
|
||||
|
||||
readonly region="eu-west-1"
|
||||
readonly bucket="resource-api-testing"
|
||||
readonly distribution="ETZGUP1CWRC2P"
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
readonly tmpdir
|
||||
registerExitHandler "rm -rf $tmpdir"
|
||||
|
||||
readonly claim_path="'$tmpdir'/maaClaim.json"
|
||||
cat << EOF > "$claim_path"
|
||||
{
|
||||
"x-ms-isolation-tee": {
|
||||
"x-ms-sevsnpvm-tee-svn": 1,
|
||||
"x-ms-sevsnpvm-snpfw-svn": 9,
|
||||
"x-ms-sevsnpvm-microcode-svn": 116,
|
||||
"x-ms-sevsnpvm-bootloader-svn": 4
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
readonly date="2023-02-02-03-04"
|
||||
${configapi_cli} --maa-claims-path "$claim_path" --upload-date "$date" --region "$region" --bucket "$bucket" --distribution "$distribution"
|
||||
|
||||
baseurl="https://d33dzgxuwsgbpw.cloudfront.net/constellation/v1/attestation/azure-sev-snp"
|
||||
if ! curl -fsSL ${baseurl}/${date}.json > /dev/null; then
|
||||
echo "Checking for uploaded version file constellation/v1/attestation/azure-sev-snp/${date}.json: request returned ${?}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! curl -fsSL ${baseurl}/${date}.json.sig > /dev/null; then
|
||||
echo "Checking for uploaded version signature file constellation/v1/attestation/azure-sev-snp/${date}.json.sig: request returned ${?}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! curl -fsSL ${baseurl}/list > /dev/null; then
|
||||
echo "Checking for uploaded list file constellation/v1/attestation/azure-sev-snp/list: request returned ${?}"
|
||||
exit 1
|
||||
fi
|
||||
${configapi_cli} delete --version "$date" --region "$region" --bucket "$bucket" --distribution "$distribution"
|
||||
|
||||
# Omit -f to check for 404. We want to check that a file was deleted, therefore we expect the query to fail.
|
||||
http_code=$(curl -sSL -w '%{http_code}\n' -o /dev/null ${baseurl}/${date}.json)
|
||||
if [[ $http_code -ne 404 ]]; then
|
||||
echo "Expected HTTP code 404 for: constellation/v1/attestation/azure-sev-snp/${date}.json, but got ${http_code}"
|
||||
exit 1
|
||||
fi
|
||||
# Omit -f to check for 404. We want to check that a file was deleted, therefore we expect the query to fail.
|
||||
http_code=$(curl -sSL -w '%{http_code}\n' -o /dev/null ${baseurl}/${date}.json.sig)
|
||||
if [[ $http_code -ne 404 ]]; then
|
||||
echo "Expected HTTP code 404 for: constellation/v1/attestation/azure-sev-snp/${date}.json, but got ${http_code}"
|
||||
exit 1
|
||||
fi
|
|
@ -4,6 +4,12 @@ Copyright (c) Edgeless Systems GmbH
|
|||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
/*
|
||||
# configapi CLI
|
||||
|
||||
A CLI to interact with the Attestationconfig API, a sub API of the Resource API.
|
||||
You can execute an e2e test by running: `bazel run //hack/configapi:configapi_e2e_test`.
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
|
@ -13,6 +19,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||
"go.uber.org/zap"
|
||||
|
||||
|
@ -23,6 +30,7 @@ import (
|
|||
const (
|
||||
awsRegion = "eu-central-1"
|
||||
awsBucket = "cdn-constellation-backend"
|
||||
distributionID = constants.CDNDefaultDistributionID
|
||||
envCosignPwd = "COSIGN_PASSWORD"
|
||||
envCosignPrivateKey = "COSIGN_PRIVATE_KEY"
|
||||
)
|
||||
|
@ -58,6 +66,7 @@ func newRootCmd() *cobra.Command {
|
|||
rootCmd.Flags().StringP("upload-date", "d", "", "upload a version with this date as version name.")
|
||||
rootCmd.PersistentFlags().StringP("region", "r", awsRegion, "region of the targeted bucket.")
|
||||
rootCmd.PersistentFlags().StringP("bucket", "b", awsBucket, "bucket targeted by all operations.")
|
||||
rootCmd.PersistentFlags().StringP("distribution", "i", distributionID, "cloudflare distribution used.")
|
||||
must(rootCmd.MarkFlagRequired("maa-claims-path"))
|
||||
rootCmd.AddCommand(newDeleteCmd())
|
||||
return rootCmd
|
||||
|
@ -72,7 +81,7 @@ func envCheck(_ *cobra.Command, _ []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func runCmd(cmd *cobra.Command, _ []string) error {
|
||||
func runCmd(cmd *cobra.Command, _ []string) (retErr error) {
|
||||
ctx := cmd.Context()
|
||||
log := logger.New(logger.PlainLog, zap.DebugLevel).Named("attestationconfigapi")
|
||||
|
||||
|
@ -82,8 +91,9 @@ func runCmd(cmd *cobra.Command, _ []string) error {
|
|||
}
|
||||
|
||||
cfg := staticupload.Config{
|
||||
Bucket: flags.bucket,
|
||||
Region: flags.region,
|
||||
Bucket: flags.bucket,
|
||||
Region: flags.region,
|
||||
DistributionID: flags.distribution,
|
||||
}
|
||||
|
||||
log.Infof("Reading MAA claims from file: %s", flags.maaFilePath)
|
||||
|
@ -114,17 +124,19 @@ func runCmd(cmd *cobra.Command, _ []string) error {
|
|||
}
|
||||
log.Infof("Input version: %+v is newer than latest API version: %+v", inputVersion, latestAPIVersion)
|
||||
|
||||
client, stop, err := attestationconfigapi.NewClient(ctx, cfg, []byte(cosignPwd), []byte(privateKey), false, log)
|
||||
defer func() {
|
||||
if err := stop(ctx); err != nil {
|
||||
cmd.Printf("stopping client: %v\n", err)
|
||||
client, clientClose, err := attestationconfigapi.NewClient(ctx, cfg, []byte(cosignPwd), []byte(privateKey), false, log)
|
||||
defer func(retErr *error) {
|
||||
log.Infof("Invalidating cache. This may take some time")
|
||||
if err := clientClose(cmd.Context()); err != nil && retErr == nil {
|
||||
*retErr = fmt.Errorf("invalidating cache: %w", err)
|
||||
}
|
||||
}()
|
||||
}(&retErr)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating client: %w", err)
|
||||
}
|
||||
|
||||
if err := client.UploadAzureSEVSNP(ctx, inputVersion, flags.uploadDate); err != nil {
|
||||
if err := client.UploadAzureSEVSNPVersion(ctx, inputVersion, flags.uploadDate); err != nil {
|
||||
return fmt.Errorf("uploading version: %w", err)
|
||||
}
|
||||
|
||||
|
@ -133,10 +145,11 @@ func runCmd(cmd *cobra.Command, _ []string) error {
|
|||
}
|
||||
|
||||
type cliFlags struct {
|
||||
maaFilePath string
|
||||
uploadDate time.Time
|
||||
region string
|
||||
bucket string
|
||||
maaFilePath string
|
||||
uploadDate time.Time
|
||||
region string
|
||||
bucket string
|
||||
distribution string
|
||||
}
|
||||
|
||||
func parseCliFlags(cmd *cobra.Command) (cliFlags, error) {
|
||||
|
@ -167,11 +180,17 @@ func parseCliFlags(cmd *cobra.Command) (cliFlags, error) {
|
|||
return cliFlags{}, fmt.Errorf("getting bucket: %w", err)
|
||||
}
|
||||
|
||||
distribution, err := cmd.Flags().GetString("distribution")
|
||||
if err != nil {
|
||||
return cliFlags{}, fmt.Errorf("getting distribution: %w", err)
|
||||
}
|
||||
|
||||
return cliFlags{
|
||||
maaFilePath: maaFilePath,
|
||||
uploadDate: uploadDate,
|
||||
region: region,
|
||||
bucket: bucket,
|
||||
maaFilePath: maaFilePath,
|
||||
uploadDate: uploadDate,
|
||||
region: region,
|
||||
bucket: bucket,
|
||||
distribution: distribution,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue