Skip to content

Commit

Permalink
cli: refactor coordinator policy hash injection
Browse files Browse the repository at this point in the history
This change is refactoring only, without a functional change.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
  • Loading branch information
katexochen committed Mar 7, 2025
1 parent 6a0d9d7 commit bb1794b
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 16 deletions.
1 change: 0 additions & 1 deletion cli/cmd/assets/coordinator-policy-hash

This file was deleted.

1 change: 1 addition & 0 deletions cli/cmd/assets/coordinator-policy-hashes-fallback.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"THIS FILE IS REPLACED DURING RELEASE BUILD TO INCLUDE THE FALLBACK POLICY HASHES FOR ALL PLATFORMS"
24 changes: 22 additions & 2 deletions cli/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ package cmd
import (
"context"
_ "embed"
"encoding/json"
"fmt"
"os"
"path/filepath"
"time"

"github.com/edgelesssys/contrast/cli/telemetry"
"github.com/edgelesssys/contrast/internal/manifest"
"github.com/edgelesssys/contrast/internal/platforms"
"github.com/spf13/cobra"
)

Expand All @@ -33,12 +37,28 @@ var (
// ReleaseImageReplacements contains the image replacements used by contrast.
//go:embed assets/image-replacements.txt
ReleaseImageReplacements []byte
// DefaultCoordinatorPolicyHash is derived from the coordinator release candidate and injected at release build time.
// CoordinatorPolicyHashesFallback are derived from the coordinator release candidate and injected at release build time.
//
// It is intentionally left empty for dev builds.
DefaultCoordinatorPolicyHash = ""
//go:embed assets/coordinator-policy-hashes-fallback.json
CoordinatorPolicyHashesFallback []byte
)

type coordinatorPolicyHashes map[platforms.Platform]manifest.HexString

// defaultCoordinatorPolicyHash returns the default coordinator policy hash for the given platform.
func defaultCoordinatorPolicyHash(p platforms.Platform) (manifest.HexString, error) {
defaults := make(coordinatorPolicyHashes)
if err := json.Unmarshal(CoordinatorPolicyHashesFallback, &defaults); err != nil {
return "", fmt.Errorf("unmarshaling coordinator policy hashes fallback: %w", err)
}
defaultHash, ok := defaults[p]
if !ok {
return "", fmt.Errorf("no default coordinator policy hash for %s", p)
}
return defaultHash, nil
}

func cachedir(subdir string) (string, error) {
dir := os.Getenv(cacheDirEnv)
if dir == "" {
Expand Down
6 changes: 5 additions & 1 deletion cli/cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,11 @@ func runGenerate(cmd *cobra.Command, args []string) error {

fmt.Fprintf(cmd.OutOrStdout(), "✔️ Updated manifest %s\n", flags.manifestPath)

if hash := getCoordinatorPolicyHash(policies, log); hash != "" {
hash, err := getCoordinatorPolicyHash(policies, flags.referenceValuesPlatform, log)
if err != nil {
return err
}
if hash != "" {
coordHashPath := filepath.Join(flags.workspaceDir, coordHashFilename)
if err := os.WriteFile(coordHashPath, []byte(hash), 0o644); err != nil {
return fmt.Errorf("write coordinator policy hash: %w", err)
Expand Down
12 changes: 9 additions & 3 deletions cli/cmd/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/edgelesssys/contrast/internal/kubeapi"
"github.com/edgelesssys/contrast/internal/manifest"
"github.com/edgelesssys/contrast/internal/platforms"
"k8s.io/apimachinery/pkg/runtime/schema"
)

Expand Down Expand Up @@ -137,19 +138,24 @@ func checkPoliciesMatchManifest(policies []deployment, policyHashes map[manifest
// an empty string is returned.
//
// If there is more than one coordinator, it's unspecified which one will be used.
func getCoordinatorPolicyHash(policies []deployment, log *slog.Logger) string {
func getCoordinatorPolicyHash(policies []deployment, platform platforms.Platform, log *slog.Logger) (string, error) {
var hash string
defaultCoordHash, err := defaultCoordinatorPolicyHash(platform)
if err != nil {
return "", fmt.Errorf("getting default coordinator policy hash for platform %s: %w", platform, err)
}

for _, deployment := range policies {
if deployment.role != "coordinator" {
continue
}
if deployment.policy.Hash().String() != DefaultCoordinatorPolicyHash {
if deployment.policy.Hash().String() != defaultCoordHash.String() {
log.Warn("Found unexpected coordinator policy", "name", deployment.name, "hash", deployment.policy.Hash())
}
hash = deployment.policy.Hash().String()
// Keep going, in case we need to warn about another coordinator.
}
return hash
return hash, nil
}

type deployment struct {
Expand Down
5 changes: 4 additions & 1 deletion cli/cmd/recover.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/edgelesssys/contrast/internal/atls"
"github.com/edgelesssys/contrast/internal/grpc/dialer"
"github.com/edgelesssys/contrast/internal/manifest"
"github.com/edgelesssys/contrast/internal/platforms"
"github.com/edgelesssys/contrast/internal/userapi"
"github.com/edgelesssys/contrast/sdk"
"github.com/spf13/cobra"
Expand All @@ -37,7 +38,9 @@ The recover command is used to provide the seed to the Coordinator.`,
cmd.Flags().StringP("manifest", "m", manifestFilename, "path to manifest (.json) file")
cmd.Flags().StringP("coordinator", "c", "", "endpoint the coordinator can be reached at")
must(cobra.MarkFlagRequired(cmd.Flags(), "coordinator"))
cmd.Flags().String("coordinator-policy-hash", DefaultCoordinatorPolicyHash, "override the expected policy hash of the coordinator")
defaultCoordHash, err := defaultCoordinatorPolicyHash(platforms.AKSCloudHypervisorSNP)
must(err)
cmd.Flags().String("coordinator-policy-hash", defaultCoordHash.String(), "override the expected policy hash of the coordinator")
cmd.Flags().String("workload-owner-key", workloadOwnerPEM,
"path to workload owner key (.pem) file (can be passed more than once)")
cmd.Flags().String("seedshare-owner-key", seedshareOwnerPEM, "private key file to decrypt the seed share")
Expand Down
5 changes: 4 additions & 1 deletion cli/cmd/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/edgelesssys/contrast/internal/grpc/dialer"
grpcRetry "github.com/edgelesssys/contrast/internal/grpc/retry"
"github.com/edgelesssys/contrast/internal/manifest"
"github.com/edgelesssys/contrast/internal/platforms"
"github.com/edgelesssys/contrast/internal/retry"
"github.com/edgelesssys/contrast/internal/spinner"
"github.com/edgelesssys/contrast/internal/userapi"
Expand Down Expand Up @@ -52,7 +53,9 @@ issuer certificates.`,
cmd.Flags().StringP("manifest", "m", manifestFilename, "path to manifest (.json) file")
cmd.Flags().StringP("coordinator", "c", "", "endpoint the coordinator can be reached at")
must(cobra.MarkFlagRequired(cmd.Flags(), "coordinator"))
cmd.Flags().String("coordinator-policy-hash", DefaultCoordinatorPolicyHash, "override the expected policy hash of the coordinator")
defaultCoordHash, err := defaultCoordinatorPolicyHash(platforms.AKSCloudHypervisorSNP)
must(err)
cmd.Flags().String("coordinator-policy-hash", defaultCoordHash.String(), "override the expected policy hash of the coordinator")
cmd.Flags().String("workload-owner-key", workloadOwnerPEM, "path to workload owner key (.pem) file")

return cmd
Expand Down
5 changes: 4 additions & 1 deletion cli/cmd/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"path/filepath"

"github.com/edgelesssys/contrast/internal/manifest"
"github.com/edgelesssys/contrast/internal/platforms"
"github.com/edgelesssys/contrast/sdk"
"github.com/spf13/cobra"
)
Expand All @@ -34,7 +35,9 @@ all policies, and the certificates of the Coordinator certificate authority.`,
cmd.Flags().StringP("manifest", "m", manifestFilename, "path to manifest (.json) file")
cmd.Flags().StringP("coordinator", "c", "", "endpoint the coordinator can be reached at")
must(cobra.MarkFlagRequired(cmd.Flags(), "coordinator"))
cmd.Flags().String("coordinator-policy-hash", DefaultCoordinatorPolicyHash, "override the expected policy hash of the coordinator")
defaultCoordHash, err := defaultCoordinatorPolicyHash(platforms.AKSCloudHypervisorSNP)
must(err)
cmd.Flags().String("coordinator-policy-hash", defaultCoordHash.String(), "override the expected policy hash of the coordinator")

return cmd
}
Expand Down
32 changes: 32 additions & 0 deletions internal/platforms/platforms.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,38 @@ func (p Platform) String() string {
}
}

// MarshalJSON marshals a Platform type to a JSON string.
func (p Platform) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"%s"`, p.String())), nil
}

// UnmarshalJSON unmarshals a JSON string to a Platform type.
func (p *Platform) UnmarshalJSON(data []byte) error {
s := strings.Trim(string(data), `"`)
parsed, err := FromString(s)
if err != nil {
return err
}
*p = parsed
return nil
}

// MarshalText marshals a Platform type to a text string.
func (p Platform) MarshalText() ([]byte, error) {
return []byte(p.String()), nil
}

// UnmarshalText unmarshals a text string to a Platform type.
func (p *Platform) UnmarshalText(data []byte) error {
s := string(data)
parsed, err := FromString(s)
if err != nil {
return err
}
*p = parsed
return nil
}

// FromString returns the Platform type corresponding to the given string.
func FromString(s string) (Platform, error) {
switch strings.ToLower(s) {
Expand Down
23 changes: 18 additions & 5 deletions packages/by-name/cli-release/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,33 @@
# SPDX-License-Identifier: AGPL-3.0-only

{
lib,
contrast,
kata,
microsoft,
}:

let
coordinatorPolicyHashesFallback = builtins.toFile "coordinator-policy-hashes-fallback.json" (
builtins.toJSON {
AKS-CLH-SNP = lib.trim (builtins.readFile ../../../cli/cmd/assets/coordinator-policy-hash);
K3s-QEMU-TDX = "";
K3s-QEMU-SNP = "";
K3s-QEMU-SNP-GPU = "";
RKE2-QEMU-TDX = "";
Metal-QEMU-SNP = "";
Metal-QEMU-SNP-GPU = "";
Metal-QEMU-TDX = "";
}
);
in

(contrast.overrideAttrs (
_finalAttrs: previousAttrs: {
_finalAttrs: _previousAttrs: {
postPatch = ''
install -D ${microsoft.genpolicy.settings}/genpolicy-settings.json cli/genpolicy/assets/genpolicy-settings-microsoft.json
install -D ${kata.genpolicy.settings}/genpolicy-settings.json cli/genpolicy/assets/genpolicy-settings-kata.json
install -D ${coordinatorPolicyHashesFallback} cli/cmd/assets/coordinator-policy-hashes-fallback.json
'';

ldflags = previousAttrs.ldflags ++ [
"-X github.com/edgelesssys/contrast/cli/cmd.DefaultCoordinatorPolicyHash=${builtins.readFile ../../../cli/cmd/assets/coordinator-policy-hash}"
];
}
)).cli
16 changes: 15 additions & 1 deletion packages/by-name/contrast/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,19 @@ let
}
);

coordinatorPolicyHashesFallback = builtins.toFile "coordinator-policy-hashes-fallback.json" (
builtins.toJSON {
AKS-CLH-SNP = "";
K3s-QEMU-TDX = "";
K3s-QEMU-SNP = "";
K3s-QEMU-SNP-GPU = "";
RKE2-QEMU-TDX = "";
Metal-QEMU-SNP = "";
Metal-QEMU-SNP-GPU = "";
Metal-QEMU-TDX = "";
}
);

packageOutputs = [
"coordinator"
"initializer"
Expand Down Expand Up @@ -230,10 +243,11 @@ buildGoModule rec {
install -D ${snpIdBlocks} nodeinstaller/internal/constants/snp-id-blocks.json
'';

# postPatch will be overwritten by the release-cli derivation, prePatch
# postPatch will be overwritten by the release-cli derivation, prePatch won't.
postPatch = ''
install -D ${microsoft.genpolicy.settings-dev}/genpolicy-settings.json cli/genpolicy/assets/genpolicy-settings-microsoft.json
install -D ${kata.genpolicy.settings-dev}/genpolicy-settings.json cli/genpolicy/assets/genpolicy-settings-kata.json
install -D ${coordinatorPolicyHashesFallback} cli/cmd/assets/coordinator-policy-hashes-fallback.json
'';

env.CGO_ENABLED = 0;
Expand Down

0 comments on commit bb1794b

Please sign in to comment.