From afc816971bbe438f44592695f3a546f6295bfad2 Mon Sep 17 00:00:00 2001 From: Matthew Bates Date: Wed, 3 Sep 2025 15:04:12 +0100 Subject: [PATCH 1/6] add option to specify volume mount for the Workload API socket --- cmd/cofidectl/cmd/workload/workload.go | 14 ++++++++------ internal/pkg/workload/workload.go | 10 +++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/cmd/cofidectl/cmd/workload/workload.go b/cmd/cofidectl/cmd/workload/workload.go index 3a14e561..e6a8f442 100644 --- a/cmd/cofidectl/cmd/workload/workload.go +++ b/cmd/cofidectl/cmd/workload/workload.go @@ -119,9 +119,10 @@ This command will display the status of workloads in the Cofide configuration st ` type StatusOpts struct { - podName string - namespace string - trustZone string + podName string + namespace string + trustZone string + wlVolumeMount string } func (w *WorkloadCommand) GetStatusCommand() *cobra.Command { @@ -150,6 +151,7 @@ func (w *WorkloadCommand) GetStatusCommand() *cobra.Command { f.StringVar(&opts.podName, "pod-name", "", "Pod name for the workload") f.StringVar(&opts.namespace, "namespace", "", "Namespace for the workload") f.StringVar(&opts.trustZone, "trust-zone", "", "Trust zone for the workload") + f.StringVar(&opts.wlVolumeMount, "workload-api-volume-mount", "spiffe-workload-api", "The volume mount for the Workload API socket") cobra.CheckErr(cmd.MarkFlagRequired("pod-name")) cobra.CheckErr(cmd.MarkFlagRequired("namespace")) @@ -174,7 +176,7 @@ func (w *WorkloadCommand) status(ctx context.Context, ds datasource.DataSource, return err } - statusCh, dataCh := getWorkloadStatus(ctx, client, opts.podName, opts.namespace) + statusCh, dataCh := getWorkloadStatus(ctx, client, opts.podName, opts.namespace, opts.wlVolumeMount) // Create a spinner to display whilst the debug container is created and executed and logs retrieved if err := statusspinner.WatchProvisionStatus(ctx, statusCh, false); err != nil { @@ -239,14 +241,14 @@ func renderRegisteredWorkloads(ctx context.Context, ds datasource.DataSource, ku return nil } -func getWorkloadStatus(ctx context.Context, client *kubeutil.Client, podName string, namespace string) (<-chan *provisionpb.Status, chan string) { +func getWorkloadStatus(ctx context.Context, client *kubeutil.Client, podName, namespace, wlVolumeMount string) (<-chan *provisionpb.Status, chan string) { statusCh := make(chan *provisionpb.Status) dataCh := make(chan string, 1) go func() { defer close(statusCh) defer close(dataCh) - workload.GetStatus(ctx, statusCh, dataCh, client, podName, namespace) + workload.GetStatus(ctx, statusCh, dataCh, client, podName, namespace, wlVolumeMount) }() return statusCh, dataCh diff --git a/internal/pkg/workload/workload.go b/internal/pkg/workload/workload.go index 4c06b261..62449a1c 100644 --- a/internal/pkg/workload/workload.go +++ b/internal/pkg/workload/workload.go @@ -145,7 +145,7 @@ func GetUnregisteredWorkloads(ctx context.Context, kubeCfgFile string, kubeConte return unregisteredWorkloads, nil } -func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh chan string, client *kubeutil.Client, podName string, namespace string) { +func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh chan string, client *kubeutil.Client, podName, namespace, wlVolumeMount string) { debugContainerName := fmt.Sprintf("%s-%s", debugContainerNamePrefix, rand.String(5)) statusCh <- provision.StatusOk( @@ -153,7 +153,7 @@ func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh fmt.Sprintf("Waiting for ephemeral debug container to be created in %s", podName), ) - if err := createDebugContainer(ctx, client, podName, namespace, debugContainerName); err != nil { + if err := createDebugContainer(ctx, client, podName, namespace, wlVolumeMount, debugContainerName); err != nil { statusCh <- provision.StatusError( "Creating", fmt.Sprintf("Failed waiting for ephemeral debug container to be created in %s", podName), @@ -193,7 +193,7 @@ func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh ) } -func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName string, namespace string, debugContainerName string) error { +func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName string, namespace string, wlVolumeMount string, debugContainerName string) error { pod, err := client.Clientset.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{}) if err != nil { return err @@ -209,8 +209,8 @@ func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName VolumeMounts: []v1.VolumeMount{ { ReadOnly: true, - Name: "spiffe-workload-api", - MountPath: "/spiffe-workload-api", + Name: wlVolumeMount, + MountPath: fmt.Sprintf("/%s", wlVolumeMount), }}, }, TargetContainerName: pod.Spec.Containers[0].Name, From 8e4147f8506033870d925726442711ca4c2fe6e5 Mon Sep 17 00:00:00 2001 From: Matthew Bates Date: Wed, 3 Sep 2025 16:39:31 +0100 Subject: [PATCH 2/6] add config option for the SPIFFE socket path --- cmd/cofidectl/cmd/workload/workload.go | 18 ++++++++++-------- internal/pkg/workload/workload.go | 19 +++++++++++++------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/cmd/cofidectl/cmd/workload/workload.go b/cmd/cofidectl/cmd/workload/workload.go index e6a8f442..000434b2 100644 --- a/cmd/cofidectl/cmd/workload/workload.go +++ b/cmd/cofidectl/cmd/workload/workload.go @@ -119,10 +119,11 @@ This command will display the status of workloads in the Cofide configuration st ` type StatusOpts struct { - podName string - namespace string - trustZone string - wlVolumeMount string + podName string + namespace string + trustZone string + spiffeSocketVolumeMount string + spiffeSocketPath string } func (w *WorkloadCommand) GetStatusCommand() *cobra.Command { @@ -151,7 +152,8 @@ func (w *WorkloadCommand) GetStatusCommand() *cobra.Command { f.StringVar(&opts.podName, "pod-name", "", "Pod name for the workload") f.StringVar(&opts.namespace, "namespace", "", "Namespace for the workload") f.StringVar(&opts.trustZone, "trust-zone", "", "Trust zone for the workload") - f.StringVar(&opts.wlVolumeMount, "workload-api-volume-mount", "spiffe-workload-api", "The volume mount for the Workload API socket") + f.StringVar(&opts.spiffeSocketVolumeMount, "spiffe-socket-volume-mount", "spiffe-workload-api", "The volume mount for the SPIFFE socket (UDS)") + f.StringVar(&opts.spiffeSocketPath, "spiffe-socket-path", "spiffe-workload-api", "The path to the SPIFFE socket (UDS)") cobra.CheckErr(cmd.MarkFlagRequired("pod-name")) cobra.CheckErr(cmd.MarkFlagRequired("namespace")) @@ -176,7 +178,7 @@ func (w *WorkloadCommand) status(ctx context.Context, ds datasource.DataSource, return err } - statusCh, dataCh := getWorkloadStatus(ctx, client, opts.podName, opts.namespace, opts.wlVolumeMount) + statusCh, dataCh := getWorkloadStatus(ctx, client, opts.podName, opts.namespace, opts.spiffeSocketVolumeMount, opts.spiffeSocketPath) // Create a spinner to display whilst the debug container is created and executed and logs retrieved if err := statusspinner.WatchProvisionStatus(ctx, statusCh, false); err != nil { @@ -241,14 +243,14 @@ func renderRegisteredWorkloads(ctx context.Context, ds datasource.DataSource, ku return nil } -func getWorkloadStatus(ctx context.Context, client *kubeutil.Client, podName, namespace, wlVolumeMount string) (<-chan *provisionpb.Status, chan string) { +func getWorkloadStatus(ctx context.Context, client *kubeutil.Client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeMount string) (<-chan *provisionpb.Status, chan string) { statusCh := make(chan *provisionpb.Status) dataCh := make(chan string, 1) go func() { defer close(statusCh) defer close(dataCh) - workload.GetStatus(ctx, statusCh, dataCh, client, podName, namespace, wlVolumeMount) + workload.GetStatus(ctx, statusCh, dataCh, client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeMount) }() return statusCh, dataCh diff --git a/internal/pkg/workload/workload.go b/internal/pkg/workload/workload.go index 62449a1c..ecd491ba 100644 --- a/internal/pkg/workload/workload.go +++ b/internal/pkg/workload/workload.go @@ -20,7 +20,7 @@ import ( ) const debugContainerNamePrefix = "cofidectl-debug" -const debugContainerImage = "ghcr.io/cofide/cofidectl-debug-container:v0.2.1" +const debugContainerImage = "ghcr.io/cofide/cofidectl-debug-container:v0.2.2-dev" type Workload struct { Name string @@ -145,7 +145,7 @@ func GetUnregisteredWorkloads(ctx context.Context, kubeCfgFile string, kubeConte return unregisteredWorkloads, nil } -func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh chan string, client *kubeutil.Client, podName, namespace, wlVolumeMount string) { +func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh chan string, client *kubeutil.Client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeMount string) { debugContainerName := fmt.Sprintf("%s-%s", debugContainerNamePrefix, rand.String(5)) statusCh <- provision.StatusOk( @@ -153,7 +153,7 @@ func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh fmt.Sprintf("Waiting for ephemeral debug container to be created in %s", podName), ) - if err := createDebugContainer(ctx, client, podName, namespace, wlVolumeMount, debugContainerName); err != nil { + if err := createDebugContainer(ctx, client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeMount, debugContainerName); err != nil { statusCh <- provision.StatusError( "Creating", fmt.Sprintf("Failed waiting for ephemeral debug container to be created in %s", podName), @@ -193,7 +193,7 @@ func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh ) } -func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName string, namespace string, wlVolumeMount string, debugContainerName string) error { +func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeName, debugContainerName string) error { pod, err := client.Clientset.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{}) if err != nil { return err @@ -209,13 +209,20 @@ func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName VolumeMounts: []v1.VolumeMount{ { ReadOnly: true, - Name: wlVolumeMount, - MountPath: fmt.Sprintf("/%s", wlVolumeMount), + Name: spiffeSocketVolumeName, + MountPath: fmt.Sprintf("/%s", spiffeSocketVolumeName), }}, }, TargetContainerName: pod.Spec.Containers[0].Name, } + if spiffeSocketPath != "" { + debugContainer.Env = append(debugContainer.Env, v1.EnvVar{ + Name: "SPIFFE_ENDPOINT_SOCKET", + Value: spiffeSocketPath, + }) + } + pod.Spec.EphemeralContainers = append(pod.Spec.EphemeralContainers, debugContainer) _, err = client.Clientset.CoreV1().Pods(namespace).UpdateEphemeralContainers( From fc76d24992a81c1e6373e2fc920b4adbc5f1710c Mon Sep 17 00:00:00 2001 From: Matthew Bates Date: Wed, 3 Sep 2025 16:47:00 +0100 Subject: [PATCH 3/6] switch order of vars --- cmd/cofidectl/cmd/workload/workload.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/cofidectl/cmd/workload/workload.go b/cmd/cofidectl/cmd/workload/workload.go index 000434b2..69d8f846 100644 --- a/cmd/cofidectl/cmd/workload/workload.go +++ b/cmd/cofidectl/cmd/workload/workload.go @@ -178,7 +178,7 @@ func (w *WorkloadCommand) status(ctx context.Context, ds datasource.DataSource, return err } - statusCh, dataCh := getWorkloadStatus(ctx, client, opts.podName, opts.namespace, opts.spiffeSocketVolumeMount, opts.spiffeSocketPath) + statusCh, dataCh := getWorkloadStatus(ctx, client, opts.podName, opts.namespace, opts.spiffeSocketPath, opts.spiffeSocketVolumeMount) // Create a spinner to display whilst the debug container is created and executed and logs retrieved if err := statusspinner.WatchProvisionStatus(ctx, statusCh, false); err != nil { From fb6564fe8ce51549b83c88e5e96616d0006a305f Mon Sep 17 00:00:00 2001 From: Matthew Bates Date: Wed, 3 Sep 2025 17:04:12 +0100 Subject: [PATCH 4/6] use endpoint instead of path to be more precise --- cmd/cofidectl/cmd/workload/workload.go | 20 ++++++++++---------- internal/pkg/workload/workload.go | 12 ++++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cmd/cofidectl/cmd/workload/workload.go b/cmd/cofidectl/cmd/workload/workload.go index 69d8f846..897d56c5 100644 --- a/cmd/cofidectl/cmd/workload/workload.go +++ b/cmd/cofidectl/cmd/workload/workload.go @@ -119,11 +119,11 @@ This command will display the status of workloads in the Cofide configuration st ` type StatusOpts struct { - podName string - namespace string - trustZone string - spiffeSocketVolumeMount string - spiffeSocketPath string + podName string + namespace string + trustZone string + spiffeSocketVolume string + spiffeSocketEndpoint string } func (w *WorkloadCommand) GetStatusCommand() *cobra.Command { @@ -152,8 +152,8 @@ func (w *WorkloadCommand) GetStatusCommand() *cobra.Command { f.StringVar(&opts.podName, "pod-name", "", "Pod name for the workload") f.StringVar(&opts.namespace, "namespace", "", "Namespace for the workload") f.StringVar(&opts.trustZone, "trust-zone", "", "Trust zone for the workload") - f.StringVar(&opts.spiffeSocketVolumeMount, "spiffe-socket-volume-mount", "spiffe-workload-api", "The volume mount for the SPIFFE socket (UDS)") - f.StringVar(&opts.spiffeSocketPath, "spiffe-socket-path", "spiffe-workload-api", "The path to the SPIFFE socket (UDS)") + f.StringVar(&opts.spiffeSocketVolume, "spiffe-socket-volume", "spiffe-workload-api", "The volume for the SPIFFE socket (UDS)") + f.StringVar(&opts.spiffeSocketEndpoint, "spiffe-socket-endpoint", "", "The full SPIFFE socket (UDS) endpoint URI, which should be prefixed with the /spiffe-workload-api directory.") cobra.CheckErr(cmd.MarkFlagRequired("pod-name")) cobra.CheckErr(cmd.MarkFlagRequired("namespace")) @@ -178,7 +178,7 @@ func (w *WorkloadCommand) status(ctx context.Context, ds datasource.DataSource, return err } - statusCh, dataCh := getWorkloadStatus(ctx, client, opts.podName, opts.namespace, opts.spiffeSocketPath, opts.spiffeSocketVolumeMount) + statusCh, dataCh := getWorkloadStatus(ctx, client, opts.podName, opts.namespace, opts.spiffeSocketEndpoint, opts.spiffeSocketVolume) // Create a spinner to display whilst the debug container is created and executed and logs retrieved if err := statusspinner.WatchProvisionStatus(ctx, statusCh, false); err != nil { @@ -243,14 +243,14 @@ func renderRegisteredWorkloads(ctx context.Context, ds datasource.DataSource, ku return nil } -func getWorkloadStatus(ctx context.Context, client *kubeutil.Client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeMount string) (<-chan *provisionpb.Status, chan string) { +func getWorkloadStatus(ctx context.Context, client *kubeutil.Client, podName, namespace, spiffeSocketEndpoint, spiffeSocketVolume string) (<-chan *provisionpb.Status, chan string) { statusCh := make(chan *provisionpb.Status) dataCh := make(chan string, 1) go func() { defer close(statusCh) defer close(dataCh) - workload.GetStatus(ctx, statusCh, dataCh, client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeMount) + workload.GetStatus(ctx, statusCh, dataCh, client, podName, namespace, spiffeSocketEndpoint, spiffeSocketVolume) }() return statusCh, dataCh diff --git a/internal/pkg/workload/workload.go b/internal/pkg/workload/workload.go index ecd491ba..ff0057b9 100644 --- a/internal/pkg/workload/workload.go +++ b/internal/pkg/workload/workload.go @@ -145,7 +145,7 @@ func GetUnregisteredWorkloads(ctx context.Context, kubeCfgFile string, kubeConte return unregisteredWorkloads, nil } -func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh chan string, client *kubeutil.Client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeMount string) { +func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh chan string, client *kubeutil.Client, podName, namespace, spiffeSocketEndpoint, spiffeSocketVolumeMount string) { debugContainerName := fmt.Sprintf("%s-%s", debugContainerNamePrefix, rand.String(5)) statusCh <- provision.StatusOk( @@ -153,7 +153,7 @@ func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh fmt.Sprintf("Waiting for ephemeral debug container to be created in %s", podName), ) - if err := createDebugContainer(ctx, client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeMount, debugContainerName); err != nil { + if err := createDebugContainer(ctx, client, podName, namespace, spiffeSocketEndpoint, spiffeSocketVolumeMount, debugContainerName); err != nil { statusCh <- provision.StatusError( "Creating", fmt.Sprintf("Failed waiting for ephemeral debug container to be created in %s", podName), @@ -193,7 +193,7 @@ func GetStatus(ctx context.Context, statusCh chan<- *provisionpb.Status, dataCh ) } -func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName, namespace, spiffeSocketPath, spiffeSocketVolumeName, debugContainerName string) error { +func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName, namespace, spiffeSocketEndpoint, spiffeSocketVolumeName, debugContainerName string) error { pod, err := client.Clientset.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{}) if err != nil { return err @@ -209,17 +209,17 @@ func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName, VolumeMounts: []v1.VolumeMount{ { ReadOnly: true, - Name: spiffeSocketVolumeName, + Name: "/spiffe-workload-api", MountPath: fmt.Sprintf("/%s", spiffeSocketVolumeName), }}, }, TargetContainerName: pod.Spec.Containers[0].Name, } - if spiffeSocketPath != "" { + if spiffeSocketEndpoint != "" { debugContainer.Env = append(debugContainer.Env, v1.EnvVar{ Name: "SPIFFE_ENDPOINT_SOCKET", - Value: spiffeSocketPath, + Value: spiffeSocketEndpoint, }) } From 9fdb7a6d4d5a6024ff14de0de7f7c8af889c3b10 Mon Sep 17 00:00:00 2001 From: Matthew Bates Date: Wed, 3 Sep 2025 17:07:37 +0100 Subject: [PATCH 5/6] fix typo --- internal/pkg/workload/workload.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/pkg/workload/workload.go b/internal/pkg/workload/workload.go index ff0057b9..d1d93ea7 100644 --- a/internal/pkg/workload/workload.go +++ b/internal/pkg/workload/workload.go @@ -209,8 +209,8 @@ func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName, VolumeMounts: []v1.VolumeMount{ { ReadOnly: true, - Name: "/spiffe-workload-api", - MountPath: fmt.Sprintf("/%s", spiffeSocketVolumeName), + Name: fmt.Sprintf("/%s", spiffeSocketVolumeName), + MountPath: "/spiffe-workload-api", }}, }, TargetContainerName: pod.Spec.Containers[0].Name, From ec8968faf6e3fcb1e9b5bc8128a5a1f96d304b45 Mon Sep 17 00:00:00 2001 From: Matthew Bates Date: Wed, 3 Sep 2025 17:09:23 +0100 Subject: [PATCH 6/6] fix typo --- internal/pkg/workload/workload.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pkg/workload/workload.go b/internal/pkg/workload/workload.go index d1d93ea7..92a07f46 100644 --- a/internal/pkg/workload/workload.go +++ b/internal/pkg/workload/workload.go @@ -209,7 +209,7 @@ func createDebugContainer(ctx context.Context, client *kubeutil.Client, podName, VolumeMounts: []v1.VolumeMount{ { ReadOnly: true, - Name: fmt.Sprintf("/%s", spiffeSocketVolumeName), + Name: spiffeSocketVolumeName, MountPath: "/spiffe-workload-api", }}, },