mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-11-12 08:36:36 -05:00
image: add go code to upload image info and measurements
This commit is contained in:
parent
b8751f35f9
commit
217a744606
14 changed files with 745 additions and 3 deletions
|
|
@ -6,6 +6,7 @@ go_library(
|
|||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/archive",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/constants",
|
||||
"//internal/logger",
|
||||
"//internal/versionsapi",
|
||||
"@com_github_aws_aws_sdk_go_v2_config//:config",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
||||
)
|
||||
|
|
@ -58,11 +59,9 @@ func (a *Archivist) Archive(ctx context.Context, version versionsapi.Version, cs
|
|||
Body: img,
|
||||
ChecksumAlgorithm: s3types.ChecksumAlgorithmSha256,
|
||||
})
|
||||
return baseURL + key, err
|
||||
return constants.CDNRepositoryURL + "/" + key, err
|
||||
}
|
||||
|
||||
type uploadClient interface {
|
||||
Upload(ctx context.Context, input *s3.PutObjectInput, opts ...func(*s3manager.Uploader)) (*s3manager.UploadOutput, error)
|
||||
}
|
||||
|
||||
const baseURL = "https://cdn.confidential.cloud/"
|
||||
|
|
|
|||
17
internal/osimage/imageinfo/BUILD.bazel
Normal file
17
internal/osimage/imageinfo/BUILD.bazel
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "imageinfo",
|
||||
srcs = ["imageinfo.go"],
|
||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/imageinfo",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/constants",
|
||||
"//internal/logger",
|
||||
"//internal/versionsapi",
|
||||
"@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_service_s3//:s3",
|
||||
"@com_github_aws_aws_sdk_go_v2_service_s3//types",
|
||||
],
|
||||
)
|
||||
78
internal/osimage/imageinfo/imageinfo.go
Normal file
78
internal/osimage/imageinfo/imageinfo.go
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
// package imageinfo is used to upload image info JSON files to S3.
|
||||
package imageinfo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
||||
s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
||||
)
|
||||
|
||||
// Uploader uploads image info to S3.
|
||||
type Uploader struct {
|
||||
uploadClient uploadClient
|
||||
// bucket is the name of the S3 bucket to use.
|
||||
bucket string
|
||||
|
||||
log *logger.Logger
|
||||
}
|
||||
|
||||
// New creates a new Uploader.
|
||||
func New(ctx context.Context, region, bucket string, log *logger.Logger) (*Uploader, error) {
|
||||
cfg, err := awsconfig.LoadDefaultConfig(ctx, awsconfig.WithRegion(region))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s3client := s3.NewFromConfig(cfg)
|
||||
uploadClient := s3manager.NewUploader(s3client)
|
||||
|
||||
return &Uploader{
|
||||
uploadClient: uploadClient,
|
||||
bucket: bucket,
|
||||
log: log,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Upload marshals the image info to JSON and uploads it to S3.
|
||||
func (a *Uploader) Upload(ctx context.Context, imageInfo versionsapi.ImageInfo) (string, error) {
|
||||
ver := versionsapi.Version{
|
||||
Ref: imageInfo.Ref,
|
||||
Stream: imageInfo.Stream,
|
||||
Version: imageInfo.Version,
|
||||
Kind: versionsapi.VersionKindImage,
|
||||
}
|
||||
key, err := url.JoinPath(ver.ArtifactPath(versionsapi.APIV2), ver.Kind.String(), "info.json")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
a.log.Debugf("Archiving image info to s3://%v/%v", a.bucket, key)
|
||||
buf := &bytes.Buffer{}
|
||||
if err := json.NewEncoder(buf).Encode(imageInfo); err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = a.uploadClient.Upload(ctx, &s3.PutObjectInput{
|
||||
Bucket: &a.bucket,
|
||||
Key: &key,
|
||||
Body: buf,
|
||||
ChecksumAlgorithm: s3types.ChecksumAlgorithmSha256,
|
||||
})
|
||||
return constants.CDNRepositoryURL + "/" + key, err
|
||||
}
|
||||
|
||||
type uploadClient interface {
|
||||
Upload(ctx context.Context, input *s3.PutObjectInput, opts ...func(*s3manager.Uploader)) (*s3manager.UploadOutput, error)
|
||||
}
|
||||
18
internal/osimage/measurementsuploader/BUILD.bazel
Normal file
18
internal/osimage/measurementsuploader/BUILD.bazel
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "measurementsuploader",
|
||||
srcs = ["measurementsuploader.go"],
|
||||
importpath = "github.com/edgelesssys/constellation/v2/internal/osimage/measurementsuploader",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/attestation/measurements",
|
||||
"//internal/constants",
|
||||
"//internal/logger",
|
||||
"//internal/versionsapi",
|
||||
"@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_service_s3//:s3",
|
||||
"@com_github_aws_aws_sdk_go_v2_service_s3//types",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
// package measurementsuploader is used to upload measurements (v2) JSON files (and signatures) to S3.
|
||||
package measurementsuploader
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
|
||||
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
||||
s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
||||
)
|
||||
|
||||
// Uploader uploads image info to S3.
|
||||
type Uploader struct {
|
||||
uploadClient uploadClient
|
||||
// bucket is the name of the S3 bucket to use.
|
||||
bucket string
|
||||
|
||||
log *logger.Logger
|
||||
}
|
||||
|
||||
// New creates a new Uploader.
|
||||
func New(ctx context.Context, region, bucket string, log *logger.Logger) (*Uploader, error) {
|
||||
cfg, err := awsconfig.LoadDefaultConfig(ctx, awsconfig.WithRegion(region))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s3client := s3.NewFromConfig(cfg)
|
||||
uploadClient := s3manager.NewUploader(s3client)
|
||||
|
||||
return &Uploader{
|
||||
uploadClient: uploadClient,
|
||||
bucket: bucket,
|
||||
log: log,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Upload uploads the measurements v2 JSON file and its signature to S3.
|
||||
func (a *Uploader) Upload(ctx context.Context, rawMeasurement, signature io.ReadSeeker) (string, string, error) {
|
||||
// parse the measurements to get the ref, stream, and version
|
||||
var measurements measurements.ImageMeasurementsV2
|
||||
if err := json.NewDecoder(rawMeasurement).Decode(&measurements); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if _, err := rawMeasurement.Seek(0, io.SeekStart); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
ver := versionsapi.Version{
|
||||
Ref: measurements.Ref,
|
||||
Stream: measurements.Stream,
|
||||
Version: measurements.Version,
|
||||
Kind: versionsapi.VersionKindImage,
|
||||
}
|
||||
key, err := url.JoinPath(ver.ArtifactPath(versionsapi.APIV2), ver.Kind.String(), "measurements.json")
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
sigKey, err := url.JoinPath(ver.ArtifactPath(versionsapi.APIV2), ver.Kind.String(), "measurements.json.sig")
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
a.log.Debugf("Archiving image measurements to s3://%v/%v and s3://%v/%v", a.bucket, key, a.bucket, sigKey)
|
||||
if _, err = a.uploadClient.Upload(ctx, &s3.PutObjectInput{
|
||||
Bucket: &a.bucket,
|
||||
Key: &key,
|
||||
Body: rawMeasurement,
|
||||
ChecksumAlgorithm: s3types.ChecksumAlgorithmSha256,
|
||||
}); err != nil {
|
||||
return "", "", fmt.Errorf("uploading measurements: %w", err)
|
||||
}
|
||||
if _, err = a.uploadClient.Upload(ctx, &s3.PutObjectInput{
|
||||
Bucket: &a.bucket,
|
||||
Key: &sigKey,
|
||||
Body: signature,
|
||||
ChecksumAlgorithm: s3types.ChecksumAlgorithmSha256,
|
||||
}); err != nil {
|
||||
return "", "", fmt.Errorf("uploading measurements signature: %w", err)
|
||||
}
|
||||
return constants.CDNRepositoryURL + "/" + key, constants.CDNRepositoryURL + "/" + sigKey, nil
|
||||
}
|
||||
|
||||
type uploadClient interface {
|
||||
Upload(ctx context.Context, input *s3.PutObjectInput, opts ...func(*s3manager.Uploader)) (*s3manager.UploadOutput, error)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue