Skip to content

Commit

Permalink
cli: derive workload secret ID from GVK, namespace and name
Browse files Browse the repository at this point in the history
  • Loading branch information
burgerdev committed Jan 9, 2025
1 parent 399ac4b commit 59cacc3
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 46 deletions.
31 changes: 24 additions & 7 deletions cli/cmd/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import (
"log/slog"
"os"
"slices"
"strings"

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

type k8sObject interface {
GetName() string
GetNamespace() string
GetObjectKind() schema.ObjectKind
}

func policiesFromKubeResources(yamlPaths []string) ([]deployment, error) {
Expand All @@ -38,6 +42,10 @@ func policiesFromKubeResources(yamlPaths []string) ([]deployment, error) {
continue
}
name := meta.GetName()
namespace := orDefault(meta.GetNamespace(), "default")

gvk := meta.GetObjectKind().GroupVersionKind()
workloadSecretID := strings.Join([]string{orDefault(gvk.Group, "core"), gvk.Version, gvk.Kind, namespace, name}, "/")

var annotation, role string
switch obj := objAny.(type) {
Expand Down Expand Up @@ -75,9 +83,10 @@ func policiesFromKubeResources(yamlPaths []string) ([]deployment, error) {
return nil, fmt.Errorf("failed to parse policy %s: %w", name, err)
}
deployments = append(deployments, deployment{
name: name,
policy: policy,
role: role,
name: name,
policy: policy,
role: role,
workloadSecretID: workloadSecretID,
})
}

Expand All @@ -94,7 +103,7 @@ func manifestPolicyMapFromPolicies(policies []deployment) (map[manifest.HexStrin
}
continue
}
entry := manifest.PolicyEntry{SANs: depl.DNSNames(), WorkloadSecretID: depl.name}
entry := manifest.PolicyEntry{SANs: depl.DNSNames(), WorkloadSecretID: depl.workloadSecretID}
policyHashes[depl.policy.Hash()] = entry
}
return policyHashes, nil
Expand Down Expand Up @@ -136,11 +145,19 @@ func getCoordinatorPolicyHash(policies []deployment, log *slog.Logger) string {
}

type deployment struct {
name string
policy manifest.Policy
role string
name string
policy manifest.Policy
role string
workloadSecretID string
}

func (d deployment) DNSNames() []string {
return []string{d.name, "*"}
}

func orDefault(s, d string) string {
if s == "" {
return d
}
return s
}
21 changes: 12 additions & 9 deletions cli/cmd/policies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ func TestPoliciesFromKubeResources(t *testing.T) {
},
expectedOutput: []deployment{
{
name: "test",
policy: manifest.Policy([]byte(`valid-agent-policy`)),
role: "coordinator",
name: "test",
policy: manifest.Policy([]byte(`valid-agent-policy`)),
role: "coordinator",
workloadSecretID: "apps/v1/Deployment/default/test",
},
},
},
Expand All @@ -101,14 +102,16 @@ func TestPoliciesFromKubeResources(t *testing.T) {
},
expectedOutput: []deployment{
{
name: "test",
policy: manifest.Policy([]byte(`valid-agent-policy`)),
role: "coordinator",
name: "test",
policy: manifest.Policy([]byte(`valid-agent-policy`)),
role: "coordinator",
workloadSecretID: "apps/v1/Deployment/default/test",
},
{
name: "another-pod",
policy: manifest.Policy([]byte(`valid-agent-policy`)),
role: "worker",
name: "another-pod",
policy: manifest.Policy([]byte(`valid-agent-policy`)),
role: "worker",
workloadSecretID: "core/v1/Pod/default/another-pod",
},
},
},
Expand Down
56 changes: 26 additions & 30 deletions e2e/workloadsecret/workloadsecret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ func TestWorkloadSecrets(t *testing.T) {
require.Equal(webWorkloadSecretBytes, otherWebWorkloadSecretBytes)
})

var emojiWorkloadSecretBytes []byte
t.Run("workload secret seeds differ between deployments by default", func(t *testing.T) {
require := require.New(t)

Expand All @@ -125,7 +124,7 @@ func TestWorkloadSecrets(t *testing.T) {
stdout, stderr, err := ct.Kubeclient.Exec(ctx, ct.Namespace, emojiPods[0].Name, []string{"/bin/sh", "-c", "cat /contrast/secrets/workload-secret-seed"})
require.NoError(err, "stderr: %q", stderr)
require.NotEmpty(stdout)
emojiWorkloadSecretBytes, err = hex.DecodeString(stdout)
emojiWorkloadSecretBytes, err := hex.DecodeString(stdout)
require.NoError(err)
require.Len(emojiWorkloadSecretBytes, constants.SecretSeedSize)
require.NotEqual(webWorkloadSecretBytes, emojiWorkloadSecretBytes)
Expand All @@ -136,38 +135,35 @@ func TestWorkloadSecrets(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), ct.FactorPlatformTimeout(60*time.Second))
defer cancel()

ct.PatchManifest(t, patchWorkloadSecretID("web", "emoji"))
ct.PatchManifest(t, func(m manifest.Manifest) manifest.Manifest {
for key, policy := range m.Policies {
policy.WorkloadSecretID = "custom"
m.Policies[key] = policy
}
return m
})

t.Run("set", ct.Set)
require.NoError(ct.Kubeclient.Restart(ctx, kubeclient.Deployment{}, ct.Namespace, "web"))
require.NoError(ct.Kubeclient.WaitFor(ctx, kubeclient.Ready, kubeclient.Deployment{}, ct.Namespace, "web"))

webPods, err = ct.Kubeclient.PodsFromDeployment(ctx, ct.Namespace, "web")
require.NoError(err)
require.Len(webPods, 2, "pod not found: %s/%s", ct.Namespace, "web")

stdout, stderr, err := ct.Kubeclient.Exec(ctx, ct.Namespace, webPods[0].Name, []string{"/bin/sh", "-c", "cat /contrast/secrets/workload-secret-seed"})
require.NoError(err, "stderr: %q", stderr)
require.NotEmpty(stdout)
webWorkloadSecretBytes, err = hex.DecodeString(stdout)
require.NoError(err)
require.Len(webWorkloadSecretBytes, constants.SecretSeedSize)
require.Equal(webWorkloadSecretBytes, emojiWorkloadSecretBytes)
})
}

// patchWorkloadSecretID returns a PatchManifestFunc which overwrites the expectedWorkloadSecretID with the patchWorkloadSecretID
// in a manifest.
func patchWorkloadSecretID(expectedWorkloadSecretID string, patchWorkloadSecretID string) contrasttest.PatchManifestFunc {
return func(m manifest.Manifest) manifest.Manifest {
for key, policy := range m.Policies {
if policy.WorkloadSecretID == expectedWorkloadSecretID {
policy.WorkloadSecretID = patchWorkloadSecretID
m.Policies[key] = policy
}
var secrets [][]byte
for _, deploy := range []string{"web", "emoji"} {
require.NoError(ct.Kubeclient.Restart(ctx, kubeclient.Deployment{}, ct.Namespace, deploy))
require.NoError(ct.Kubeclient.WaitFor(ctx, kubeclient.Ready, kubeclient.Deployment{}, ct.Namespace, deploy))

pods, err := ct.Kubeclient.PodsFromDeployment(ctx, ct.Namespace, deploy)
require.NoError(err)
require.GreaterOrEqual(len(pods), 1, "pod not found: %s/%s", ct.Namespace, deploy)

stdout, stderr, err := ct.Kubeclient.Exec(ctx, ct.Namespace, pods[0].Name, []string{"/bin/sh", "-c", "cat /contrast/secrets/workload-secret-seed"})
require.NoError(err, "stderr: %q", stderr)
require.NotEmpty(stdout)
secretBytes, err := hex.DecodeString(stdout)
require.NoError(err)
secrets = append(secrets, secretBytes)
}
return m
}
require.Len(secrets, 2)
require.Equal(secrets[0], secrets[1])
})
}

func TestMain(m *testing.M) {
Expand Down

0 comments on commit 59cacc3

Please sign in to comment.