Skip to content

Commit 2c259c4

Browse files
authored
[ws-manager-mk2] Support public SSH keys (#16413)
1 parent 82997ef commit 2c259c4

File tree

6 files changed

+56
-9
lines changed

6 files changed

+56
-9
lines changed

components/ws-manager-api/go/crd/v1/workspace_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ type WorkspaceSpec struct {
4545

4646
// +kubebuilder:validation:MinItems=0
4747
Ports []PortSpec `json:"ports"`
48+
49+
SshPublicKeys []string `json:"sshPublicKeys,omitempty"`
4850
}
4951

5052
type Ownership struct {

components/ws-manager-api/go/crd/v1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/ws-manager-mk2/config/crd/bases/workspace.gitpod.io_workspaces.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ spec:
151151
type: object
152152
minItems: 0
153153
type: array
154+
sshPublicKeys:
155+
items:
156+
type: string
157+
type: array
154158
sysEnvVars:
155159
items:
156160
description: EnvVar represents an environment variable present in

components/ws-manager-mk2/service/manager.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ func (wsm *WorkspaceManagerServer) StartWorkspace(ctx context.Context, req *wsma
246246
Admission: workspacev1.AdmissionSpec{
247247
Level: admissionLevel,
248248
},
249-
Ports: ports,
249+
Ports: ports,
250+
SshPublicKeys: req.Spec.SshPublicKeys,
250251
},
251252
}
252253
controllerutil.AddFinalizer(&ws, workspacev1.GitpodFinalizerName)
@@ -684,6 +685,23 @@ func (wsm *WorkspaceManagerServer) ControlAdmission(ctx context.Context, req *ws
684685
return &wsmanapi.ControlAdmissionResponse{}, nil
685686
}
686687

688+
func (wsm *WorkspaceManagerServer) UpdateSSHKey(ctx context.Context, req *wsmanapi.UpdateSSHKeyRequest) (res *wsmanapi.UpdateSSHKeyResponse, err error) {
689+
span, ctx := tracing.FromContext(ctx, "UpdateSSHKey")
690+
tracing.ApplyOWI(span, log.OWI("", "", req.Id))
691+
defer tracing.FinishSpan(span, &err)
692+
693+
if err = validateUpdateSSHKeyRequest(req); err != nil {
694+
return &wsmanapi.UpdateSSHKeyResponse{}, err
695+
}
696+
697+
err = wsm.modifyWorkspace(ctx, req.Id, false, func(ws *workspacev1.Workspace) error {
698+
ws.Spec.SshPublicKeys = req.Keys
699+
return nil
700+
})
701+
702+
return &wsmanapi.UpdateSSHKeyResponse{}, err
703+
}
704+
687705
// modifyWorkspace modifies a workspace object using the mod function. If the mod function returns a gRPC status error, that error
688706
// is returned directly. If mod returns a non-gRPC error it is turned into one.
689707
func (wsm *WorkspaceManagerServer) modifyWorkspace(ctx context.Context, id string, updateStatus bool, mod func(ws *workspacev1.Workspace) error) error {
@@ -747,6 +765,19 @@ func validateStartWorkspaceRequest(req *wsmanapi.StartWorkspaceRequest) error {
747765
return nil
748766
}
749767

768+
func validateUpdateSSHKeyRequest(req *wsmanapi.UpdateSSHKeyRequest) error {
769+
err := validation.ValidateStruct(req,
770+
validation.Field(&req.Id, validation.Required),
771+
validation.Field(&req.Keys, validation.Required),
772+
)
773+
774+
if err != nil {
775+
return status.Errorf(codes.InvalidArgument, "invalid request: %v", err)
776+
}
777+
778+
return nil
779+
}
780+
750781
func isValidWorkspaceType(value interface{}) error {
751782
s, ok := value.(wsmanapi.WorkspaceType)
752783
if !ok {

components/ws-proxy/cmd/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ var runCmd = &cobra.Command{
8080
infoprov = append(infoprov, podInfoProv)
8181

8282
if cfg.EnableWorkspaceCRD {
83-
crdInfoProv, err := proxy.NewCRDWorkspaceInfoProvider(context.TODO(), mgr.GetClient(), mgr.GetScheme())
83+
crdInfoProv, err := proxy.NewCRDWorkspaceInfoProvider(mgr.GetClient(), mgr.GetScheme())
8484
if err == nil {
8585
if err = crdInfoProv.SetupWithManager(mgr); err != nil {
8686
log.WithError(err).Warn(err, "unable to create CRD-based info provider", "controller", "Workspace")

components/ws-proxy/pkg/proxy/infoprovider.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ type CRDWorkspaceInfoProvider struct {
214214
}
215215

216216
// NewRemoteWorkspaceInfoProvider creates a fresh WorkspaceInfoProvider.
217-
func NewCRDWorkspaceInfoProvider(ctx context.Context, client client.Client, scheme *runtime.Scheme) (*CRDWorkspaceInfoProvider, error) {
217+
func NewCRDWorkspaceInfoProvider(client client.Client, scheme *runtime.Scheme) (*CRDWorkspaceInfoProvider, error) {
218218
// create custom indexer for searches
219219
indexers := cache.Indexers{
220220
workspaceIndex: func(obj interface{}) ([]string, error) {
@@ -291,6 +291,7 @@ func (r *CRDWorkspaceInfoProvider) Reconcile(ctx context.Context, req ctrl.Reque
291291
Ports: ports,
292292
Auth: &wsapi.WorkspaceAuthentication{Admission: admission, OwnerToken: ws.Status.OwnerToken},
293293
StartedAt: ws.CreationTimestamp.Time,
294+
SSHPublicKeys: ws.Spec.SshPublicKeys,
294295
}
295296

296297
r.store.Update(req.Name, wsinfo)
@@ -350,12 +351,16 @@ func extractUserSSHPublicKeys(pod *corev1.Pod) []string {
350351
if err != nil {
351352
return nil
352353
}
353-
var spec api.SSHPublicKeys
354-
err = proto.Unmarshal(specPB, &spec)
355-
if err != nil {
356-
return nil
357-
}
358-
return spec.Keys
354+
return unmarshalUserSSHPublicKey(specPB)
359355
}
360356
return nil
361357
}
358+
359+
func unmarshalUserSSHPublicKey(keys []byte) []string {
360+
var spec api.SSHPublicKeys
361+
err := proto.Unmarshal(keys, &spec)
362+
if err != nil {
363+
return nil
364+
}
365+
return spec.Keys
366+
}

0 commit comments

Comments
 (0)