@@ -6,6 +6,7 @@ package service
6
6
7
7
import (
8
8
"context"
9
+ "encoding/base64"
9
10
"fmt"
10
11
"strconv"
11
12
"sync"
@@ -188,6 +189,11 @@ func (wsm *WorkspaceManagerServer) StartWorkspace(ctx context.Context, req *wsma
188
189
}
189
190
}
190
191
192
+ sshPublicKeys , err := setSshPublicKeys (req .Spec .SshPublicKeys )
193
+ if err != nil {
194
+ return nil , status .Errorf (codes .InvalidArgument , "invalid ssh public keys" )
195
+ }
196
+
191
197
ws := workspacev1.Workspace {
192
198
TypeMeta : metav1.TypeMeta {
193
199
APIVersion : workspacev1 .GroupVersion .String (),
@@ -230,7 +236,8 @@ func (wsm *WorkspaceManagerServer) StartWorkspace(ctx context.Context, req *wsma
230
236
Admission : workspacev1.AdmissionSpec {
231
237
Level : admissionLevel ,
232
238
},
233
- Ports : ports ,
239
+ Ports : ports ,
240
+ SshPublicKeys : sshPublicKeys ,
234
241
},
235
242
}
236
243
controllerutil .AddFinalizer (& ws , workspacev1 .GitpodFinalizerName )
@@ -523,6 +530,28 @@ func (wsm *WorkspaceManagerServer) ControlAdmission(ctx context.Context, req *ws
523
530
return & wsmanapi.ControlAdmissionResponse {}, nil
524
531
}
525
532
533
+ func (wsm * WorkspaceManagerServer ) UpdateSSHKey (ctx context.Context , req * api.UpdateSSHKeyRequest ) (res * api.UpdateSSHKeyResponse , err error ) {
534
+ span , ctx := tracing .FromContext (ctx , "UpdateSSHKey" )
535
+ tracing .ApplyOWI (span , log .OWI ("" , "" , req .Id ))
536
+ defer tracing .FinishSpan (span , & err )
537
+
538
+ if err = validateUpdateSSHKeyRequest (req ); err != nil {
539
+ return & api.UpdateSSHKeyResponse {}, err
540
+ }
541
+
542
+ err = wsm .modifyWorkspace (ctx , req .Id , false , func (ws * workspacev1.Workspace ) error {
543
+ sshKeys , err := setSshPublicKeys (req .Keys )
544
+ if err != nil {
545
+ return err
546
+ }
547
+
548
+ ws .Spec .SshPublicKeys = sshKeys
549
+ return nil
550
+ })
551
+
552
+ return & api.UpdateSSHKeyResponse {}, err
553
+ }
554
+
526
555
// modifyWorkspace modifies a workspace object using the mod function. If the mod function returns a gRPC status error, that error
527
556
// is returned directly. If mod returns a non-gRPC error it is turned into one.
528
557
func (wsm * WorkspaceManagerServer ) modifyWorkspace (ctx context.Context , id string , updateStatus bool , mod func (ws * workspacev1.Workspace ) error ) error {
@@ -586,6 +615,19 @@ func validateStartWorkspaceRequest(req *api.StartWorkspaceRequest) error {
586
615
return nil
587
616
}
588
617
618
+ func validateUpdateSSHKeyRequest (req * api.UpdateSSHKeyRequest ) error {
619
+ err := validation .ValidateStruct (req ,
620
+ validation .Field (& req .Id , validation .Required ),
621
+ validation .Field (& req .Keys , validation .Required ),
622
+ )
623
+
624
+ if err != nil {
625
+ return status .Errorf (codes .InvalidArgument , "invalid request: %v" , err )
626
+ }
627
+
628
+ return nil
629
+ }
630
+
589
631
func isValidWorkspaceType (value interface {}) error {
590
632
s , ok := value .(api.WorkspaceType )
591
633
if ! ok {
@@ -653,6 +695,21 @@ func setEnvironment(envs []*wsmanapi.EnvironmentVariable) []corev1.EnvVar {
653
695
return envVars
654
696
}
655
697
698
+ func setSshPublicKeys (keys []string ) (string , error ) {
699
+ if len (keys ) != 0 {
700
+ spec := & api.SSHPublicKeys {
701
+ Keys : keys ,
702
+ }
703
+ sshSpec , err := proto .Marshal (spec )
704
+ if err != nil {
705
+ return "" , xerrors .Errorf ("cannot create remarshal of ssh key spec: %w" , err )
706
+ }
707
+ return base64 .StdEncoding .EncodeToString (sshSpec ), nil
708
+ }
709
+
710
+ return "" , nil
711
+ }
712
+
656
713
func extractWorkspaceStatus (ws * workspacev1.Workspace ) * wsmanapi.WorkspaceStatus {
657
714
version , _ := strconv .ParseUint (ws .ResourceVersion , 10 , 64 )
658
715
0 commit comments