diff --git a/debugd/internal/cdbg/cmd/deploy.go b/debugd/internal/cdbg/cmd/deploy.go index c89b1587f..9b15770e1 100644 --- a/debugd/internal/cdbg/cmd/deploy.go +++ b/debugd/internal/cdbg/cmd/deploy.go @@ -117,20 +117,24 @@ func deployOnEndpoint(ctx context.Context, in deployOnEndpointInput) error { defer conn.Close() client := pb.NewDebugdClient(conn) - log.Println("Uploading authorized keys") - pbKeys := []*pb.AuthorizedKey{} - for _, key := range in.authorizedKeys { - pbKeys = append(pbKeys, &pb.AuthorizedKey{ - Username: key.Username, - KeyValue: key.PublicKey, - }) - } - authorizedKeysResponse, err := client.UploadAuthorizedKeys(ctx, &pb.UploadAuthorizedKeysRequest{Keys: pbKeys}, grpc.WaitForReady(true)) - if err != nil || authorizedKeysResponse.Status != pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_SUCCESS { - return fmt.Errorf("uploading authorized keys to instance %v failed: %v / %w", in.debugdEndpoint, authorizedKeysResponse, err) + if len(in.authorizedKeys) > 0 { + log.Println("Warning: Uploading authorized keys is currently disabled.") } + // TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs. + // log.Println("Uploading authorized keys") + // pbKeys := []*pb.AuthorizedKey{} + // for _, key := range in.authorizedKeys { + // pbKeys = append(pbKeys, &pb.AuthorizedKey{ + // Username: key.Username, + // KeyValue: key.PublicKey, + // }) + // } + // authorizedKeysResponse, err := client.UploadAuthorizedKeys(ctx, &pb.UploadAuthorizedKeysRequest{Keys: pbKeys}, grpc.WaitForReady(true)) + // if err != nil || authorizedKeysResponse.Status != pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_SUCCESS { + // return fmt.Errorf("uploading authorized keys to instance %v failed: %v / %w", in.debugdEndpoint, authorizedKeysResponse, err) + // } - stream, err := client.UploadBootstrapper(ctx) + stream, err := client.UploadBootstrapper(ctx, grpc.WaitForReady(true)) if err != nil { return fmt.Errorf("starting bootstrapper upload to instance %v: %w", in.debugdEndpoint, err) } diff --git a/debugd/internal/debugd/metadata/scheduler.go b/debugd/internal/debugd/metadata/scheduler.go index 209be776d..bb4a63284 100644 --- a/debugd/internal/debugd/metadata/scheduler.go +++ b/debugd/internal/debugd/metadata/scheduler.go @@ -50,9 +50,11 @@ func NewScheduler(log *logger.Logger, fetcher Fetcher, ssh sshDeployer, download func (s *Scheduler) Start(ctx context.Context, wg *sync.WaitGroup) { defer wg.Done() - wg.Add(2) + wg.Add(1) go s.discoveryLoop(ctx, wg) - go s.sshLoop(ctx, wg) + // TODO (stateless-ssh): re-enable once + // ssh keys can be deployed on readonly rootfs + // go s.sshLoop(ctx, wg) } // discoveryLoop discovers new debugd endpoints from cloud-provider metadata periodically. @@ -90,33 +92,35 @@ func (s *Scheduler) discoveryLoop(ctx context.Context, wg *sync.WaitGroup) { } // sshLoop discovers new ssh keys from cloud provider metadata periodically. -func (s *Scheduler) sshLoop(ctx context.Context, wg *sync.WaitGroup) { - defer wg.Done() +// TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs +// func (s *Scheduler) sshLoop(ctx context.Context, wg *sync.WaitGroup) { +// defer wg.Done() - ticker := time.NewTicker(debugd.SSHCheckInterval) - defer ticker.Stop() - for { - keys, err := s.fetcher.FetchSSHKeys(ctx) - if err != nil { - s.log.With(zap.Error(err)).Errorf("Fetching SSH keys failed") - } else { - s.deploySSHKeys(ctx, keys) - } +// ticker := time.NewTicker(debugd.SSHCheckInterval) +// defer ticker.Stop() +// for { +// keys, err := s.fetcher.FetchSSHKeys(ctx) +// if err != nil { +// s.log.With(zap.Error(err)).Errorf("Fetching SSH keys failed") +// } else { +// s.deploySSHKeys(ctx, keys) +// } - select { - case <-ticker.C: - case <-ctx.Done(): - return - } - } -} +// select { +// case <-ticker.C: +// case <-ctx.Done(): +// return +// } +// } +// } // downloadDeployment tries to download deployment from a list of ips and logs errors encountered. func (s *Scheduler) downloadDeployment(ctx context.Context, ips []string) (success bool) { for _, ip := range ips { - keys, err := s.downloader.DownloadDeployment(ctx, ip) + _, err := s.downloader.DownloadDeployment(ctx, ip) if err == nil { - s.deploySSHKeys(ctx, keys) + // TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs + // s.deploySSHKeys(ctx, keys) return true } if errors.Is(err, fs.ErrExist) { @@ -129,16 +133,17 @@ func (s *Scheduler) downloadDeployment(ctx context.Context, ips []string) (succe return false } +// TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs // deploySSHKeys tries to deploy a list of SSH keys and logs errors encountered. -func (s *Scheduler) deploySSHKeys(ctx context.Context, keys []ssh.UserKey) { - for _, key := range keys { - err := s.ssh.DeployAuthorizedKey(ctx, key) - if err != nil { - s.log.With(zap.Error(err), zap.Any("key", key)).Errorf("Deploying SSH key failed") - continue - } - } -} +// func (s *Scheduler) deploySSHKeys(ctx context.Context, keys []ssh.UserKey) { +// for _, key := range keys { +// err := s.ssh.DeployAuthorizedKey(ctx, key) +// if err != nil { +// s.log.With(zap.Error(err), zap.Any("key", key)).Errorf("Deploying SSH key failed") +// continue +// } +// } +// } type downloader interface { DownloadDeployment(ctx context.Context, ip string) ([]ssh.UserKey, error) diff --git a/debugd/internal/debugd/metadata/scheduler_test.go b/debugd/internal/debugd/metadata/scheduler_test.go index ccb733a2e..e927f3666 100644 --- a/debugd/internal/debugd/metadata/scheduler_test.go +++ b/debugd/internal/debugd/metadata/scheduler_test.go @@ -36,12 +36,13 @@ func TestSchedulerStart(t *testing.T) { wantDebugdDownloads []string }{ "scheduler works and calls fetcher functions at least once": {}, - "ssh keys are fetched": { - fetcher: stubFetcher{ - keys: []ssh.UserKey{{Username: "test", PublicKey: "testkey"}}, - }, - wantSSHKeys: []ssh.UserKey{{Username: "test", PublicKey: "testkey"}}, - }, + // TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs. + // "ssh keys are fetched": { + // fetcher: stubFetcher{ + // keys: []ssh.UserKey{{Username: "test", PublicKey: "testkey"}}, + // }, + // wantSSHKeys: []ssh.UserKey{{Username: "test", PublicKey: "testkey"}}, + // }, "download for discovered debugd ips is started": { fetcher: stubFetcher{ ips: []string{"192.0.2.1", "192.0.2.2"}, @@ -58,9 +59,10 @@ func TestSchedulerStart(t *testing.T) { "endpoint discovery can fail": { fetcher: stubFetcher{discoverErr: someErr}, }, - "ssh key fetch can fail": { - fetcher: stubFetcher{fetchSSHKeysErr: someErr}, - }, + // TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs. + // "ssh key fetch can fail": { + // fetcher: stubFetcher{fetchSSHKeysErr: someErr}, + // }, } for name, tc := range testCases { @@ -80,10 +82,12 @@ func TestSchedulerStart(t *testing.T) { go scheduler.Start(ctx, wg) wg.Wait() - assert.Equal(tc.wantSSHKeys, tc.ssh.sshKeys) + // TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs. + // assert.Equal(tc.wantSSHKeys, tc.ssh.sshKeys) assert.Equal(tc.wantDebugdDownloads, tc.downloader.ips) assert.Greater(tc.fetcher.discoverCalls, 0) - assert.Greater(tc.fetcher.fetchSSHKeysCalls, 0) + // TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs. + // assert.Greater(tc.fetcher.fetchSSHKeysCalls, 0) }) } } diff --git a/debugd/internal/debugd/server/server.go b/debugd/internal/debugd/server/server.go index d3d8a2b4c..afecf8a7c 100644 --- a/debugd/internal/debugd/server/server.go +++ b/debugd/internal/debugd/server/server.go @@ -46,17 +46,27 @@ func New(log *logger.Logger, ssh sshDeployer, serviceManager serviceManager, str } } +// TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs. +// UploadAuthorizedKeys receives a list of authorized keys and forwards them to a channel. +// +// func (s *debugdServer) UploadAuthorizedKeys(ctx context.Context, in *pb.UploadAuthorizedKeysRequest) (*pb.UploadAuthorizedKeysResponse, error) { +// s.log.Infof("Uploading authorized keys") +// for _, key := range in.Keys { +// if err := s.ssh.DeployAuthorizedKey(ctx, ssh.UserKey{Username: key.Username, PublicKey: key.KeyValue}); err != nil { +// s.log.With(zap.Error(err)).Errorf("Uploading authorized keys failed") +// return &pb.UploadAuthorizedKeysResponse{ +// Status: pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_FAILURE, +// }, nil +// } +// } +// return &pb.UploadAuthorizedKeysResponse{ +// Status: pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_SUCCESS, +// }, nil +// } +// // UploadAuthorizedKeys receives a list of authorized keys and forwards them to a channel. func (s *debugdServer) UploadAuthorizedKeys(ctx context.Context, in *pb.UploadAuthorizedKeysRequest) (*pb.UploadAuthorizedKeysResponse, error) { - s.log.Infof("Uploading authorized keys") - for _, key := range in.Keys { - if err := s.ssh.DeployAuthorizedKey(ctx, ssh.UserKey{Username: key.Username, PublicKey: key.KeyValue}); err != nil { - s.log.With(zap.Error(err)).Errorf("Uploading authorized keys failed") - return &pb.UploadAuthorizedKeysResponse{ - Status: pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_FAILURE, - }, nil - } - } + s.log.Infof("Uploading authorized keys (Disabled feature)") return &pb.UploadAuthorizedKeysResponse{ Status: pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_SUCCESS, }, nil diff --git a/debugd/internal/debugd/server/server_test.go b/debugd/internal/debugd/server/server_test.go index 75b4ed9d4..e6dd612c2 100644 --- a/debugd/internal/debugd/server/server_test.go +++ b/debugd/internal/debugd/server/server_test.go @@ -33,84 +33,84 @@ func TestMain(m *testing.M) { goleak.VerifyTestMain(m) } -func TestUploadAuthorizedKeys(t *testing.T) { - endpoint := "192.0.2.1:" + strconv.Itoa(constants.DebugdPort) +// func TestUploadAuthorizedKeys(t *testing.T) { +// endpoint := "192.0.2.1:" + strconv.Itoa(constants.DebugdPort) - testCases := map[string]struct { - ssh stubSSHDeployer - serviceManager stubServiceManager - request *pb.UploadAuthorizedKeysRequest - wantErr bool - wantResponseStatus pb.UploadAuthorizedKeysStatus - wantKeys []ssh.UserKey - }{ - "upload authorized keys works": { - request: &pb.UploadAuthorizedKeysRequest{ - Keys: []*pb.AuthorizedKey{ - { - Username: "testuser", - KeyValue: "teskey", - }, - }, - }, - wantResponseStatus: pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_SUCCESS, - wantKeys: []ssh.UserKey{ - { - Username: "testuser", - PublicKey: "teskey", - }, - }, - }, - "deploy fails": { - request: &pb.UploadAuthorizedKeysRequest{ - Keys: []*pb.AuthorizedKey{ - { - Username: "testuser", - KeyValue: "teskey", - }, - }, - }, - ssh: stubSSHDeployer{deployErr: errors.New("ssh key deployment error")}, - wantResponseStatus: pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_FAILURE, - wantKeys: []ssh.UserKey{ - { - Username: "testuser", - PublicKey: "teskey", - }, - }, - }, - } +// testCases := map[string]struct { +// ssh stubSSHDeployer +// serviceManager stubServiceManager +// request *pb.UploadAuthorizedKeysRequest +// wantErr bool +// wantResponseStatus pb.UploadAuthorizedKeysStatus +// wantKeys []ssh.UserKey +// }{ +// "upload authorized keys works": { +// request: &pb.UploadAuthorizedKeysRequest{ +// Keys: []*pb.AuthorizedKey{ +// { +// Username: "testuser", +// KeyValue: "teskey", +// }, +// }, +// }, +// wantResponseStatus: pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_SUCCESS, +// wantKeys: []ssh.UserKey{ +// { +// Username: "testuser", +// PublicKey: "teskey", +// }, +// }, +// }, +// "deploy fails": { +// request: &pb.UploadAuthorizedKeysRequest{ +// Keys: []*pb.AuthorizedKey{ +// { +// Username: "testuser", +// KeyValue: "teskey", +// }, +// }, +// }, +// ssh: stubSSHDeployer{deployErr: errors.New("ssh key deployment error")}, +// wantResponseStatus: pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_FAILURE, +// wantKeys: []ssh.UserKey{ +// { +// Username: "testuser", +// PublicKey: "teskey", +// }, +// }, +// }, +// } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - assert := assert.New(t) - require := require.New(t) +// for name, tc := range testCases { +// t.Run(name, func(t *testing.T) { +// assert := assert.New(t) +// require := require.New(t) - serv := debugdServer{ - log: logger.NewTest(t), - ssh: &tc.ssh, - serviceManager: &tc.serviceManager, - streamer: &fakeStreamer{}, - } +// serv := debugdServer{ +// log: logger.NewTest(t), +// ssh: &tc.ssh, +// serviceManager: &tc.serviceManager, +// streamer: &fakeStreamer{}, +// } - grpcServ, conn, err := setupServerWithConn(endpoint, &serv) - require.NoError(err) - defer conn.Close() - client := pb.NewDebugdClient(conn) - resp, err := client.UploadAuthorizedKeys(context.Background(), tc.request) +// grpcServ, conn, err := setupServerWithConn(endpoint, &serv) +// require.NoError(err) +// defer conn.Close() +// client := pb.NewDebugdClient(conn) +// resp, err := client.UploadAuthorizedKeys(context.Background(), tc.request) - grpcServ.GracefulStop() +// grpcServ.GracefulStop() - if tc.wantErr { - assert.Error(err) - return - } - require.NoError(err) - assert.Equal(tc.wantResponseStatus, resp.Status) - assert.ElementsMatch(tc.ssh.sshKeys, tc.wantKeys) - }) - } -} +// if tc.wantErr { +// assert.Error(err) +// return +// } +// require.NoError(err) +// assert.Equal(tc.wantResponseStatus, resp.Status) +// assert.ElementsMatch(tc.ssh.sshKeys, tc.wantKeys) +// }) +// } +// } func TestUploadBootstrapper(t *testing.T) { endpoint := "192.0.2.1:" + strconv.Itoa(constants.DebugdPort)