Skip to content

Commit 8864d06

Browse files
committed
WIP: fix: conditionally add SSH agent postStart event
Only add the SSH agent initialization postStart event if an SSH key with a passphrase is being used. fix #1340 Signed-off-by: Andrew Obuchowicz <[email protected]>
1 parent ff72383 commit 8864d06

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

controllers/workspace/devworkspace_controller.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,15 @@ func (r *DevWorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request
281281
}
282282
workspace.Spec.Template = *flattenedWorkspace
283283

284-
err = ssh.AddSshAgentPostStartEvent(&workspace.Spec.Template)
285-
if err != nil {
286-
return r.failWorkspace(workspace, "Failed to add ssh-agent post start event", metrics.ReasonWorkspaceEngineFailure, reqLogger, &reconcileStatus), nil
284+
if needsSSHAgentPostStartEvent, err := ssh.NeedsSSHPostStartEvent(clusterAPI, workspace.Namespace); err != nil {
285+
// Something's wrong with the ssh secret in the user's namespace
286+
// TODO: Should we fail the workspace? Or log the error and continue on?
287+
return r.failWorkspace(workspace, fmt.Sprintf("Error retrieving SSH secret: %s", err), metrics.ReasonInfrastructureFailure, reqLogger, &reconcileStatus), nil
288+
} else if needsSSHAgentPostStartEvent {
289+
if err = ssh.AddSshAgentPostStartEvent(&workspace.Spec.Template); err != nil {
290+
// TODO: Is this the right metric reason?
291+
return r.failWorkspace(workspace, "Failed to add ssh-agent post start event", metrics.ReasonWorkspaceEngineFailure, reqLogger, &reconcileStatus), nil
292+
}
287293
}
288294

289295
reconcileStatus.setConditionTrue(conditions.DevWorkspaceResolved, "Resolved plugins and parents from DevWorkspace")

pkg/constants/metadata.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ const (
8787
// in a given namespace. It is used when e.g. adding Git credentials via secret
8888
GitCredentialsConfigMapName = "devworkspace-gitconfig"
8989

90+
// SSHSecretName is the name used for the secret that stores the SSH key data for workspaces in a given namespace.
91+
// TODO: This is a workaround for https://github.com/devfile/devworkspace-operator/issues/1340.
92+
// We do not enforce the SSH secret to have this name, but it is used by the Che Dashboard and this allows us
93+
// to detect if the user has provided an SSH key with a passhprase.
94+
SSHSecretName = "git-ssh-key"
95+
96+
// SSHSecretPassphraseKey is the key used to retrieve the optional passphrase stored inside the SSH secret.
97+
SSHSecretPassphraseKey = "passphrase"
98+
9099
SshAskPassConfigMapName = "devworkspace-ssh-askpass"
91100

92101
// GitCredentialsMergedSecretName is the name for the merged Git credentials secret that is mounted to workspaces

pkg/library/ssh/event.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import (
1919
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
2020
"github.com/devfile/devworkspace-operator/pkg/constants"
2121
"github.com/devfile/devworkspace-operator/pkg/library/lifecycle"
22+
"github.com/devfile/devworkspace-operator/pkg/provision/sync"
23+
corev1 "k8s.io/api/core/v1"
24+
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
25+
"k8s.io/apimachinery/pkg/types"
2226
)
2327

2428
const commandLine = `SSH_ENV_PATH=$HOME/ssh-environment \
@@ -58,3 +62,30 @@ func AddSshAgentPostStartEvent(spec *v1alpha2.DevWorkspaceTemplateSpec) error {
5862
}
5963
return err
6064
}
65+
66+
// TODO: Is this the best place for this function?
67+
// Determines whether an SSH key with a passphrase is provided for the namespace where the workspace exists.
68+
// If an SSH key with a passphrase is used, then the SSH Agent Post Start event is needed for it to automatically
69+
// be used by the workspace's SSH agent.
70+
// If no SSH key is provided, or the SSH key does not provide a passphrase, then the SSH Agent Post Start event is not required.
71+
func NeedsSSHPostStartEvent(api sync.ClusterAPI, namespace string) (bool, error) {
72+
secretNN := types.NamespacedName{
73+
Name: constants.SSHSecretName,
74+
Namespace: namespace,
75+
}
76+
sshSecret := &corev1.Secret{}
77+
if err := api.Client.Get(api.Ctx, secretNN, sshSecret); err != nil {
78+
if k8sErrors.IsNotFound(err) {
79+
// No SSH secret found
80+
return false, nil
81+
}
82+
return false, fmt.Errorf("failed to get SSH secret: %s", err)
83+
}
84+
85+
if _, ok := sshSecret.Data[constants.SSHSecretPassphraseKey]; ok {
86+
// SSH secret exists and has a passphrase set
87+
return true, nil
88+
}
89+
90+
return false, nil
91+
}

0 commit comments

Comments
 (0)