diff --git a/.github/docs/layout.md b/.github/docs/layout.md index 3939b45bf..19894fde0 100644 --- a/.github/docs/layout.md +++ b/.github/docs/layout.md @@ -2,7 +2,6 @@ Core components: -* [access_manager](/access_manager): Contains the access-manager pod used to persist SSH users based on a K8s ConfigMap * [cli](/cli): The CLI is used to manage a Constellation cluster * [bootstrapper](/bootstrapper): The bootstrapper is a node agent whose most important task is to bootstrap a node * [image](/image): Build files for the Constellation disk image diff --git a/.github/docs/release.md b/.github/docs/release.md index fb31d2692..9d37d8236 100644 --- a/.github/docs/release.md +++ b/.github/docs/release.md @@ -33,7 +33,6 @@ This checklist will prepare `v1.3.0` from `v1.2.0`. Adjust your version numbers ``` ```sh - gh workflow run build-micro-service-manual.yml --ref release/v$minor -F microService=access-manager -F imageTag=v$ver -F version=$ver --repo edgelesssys/constellation gh workflow run build-micro-service-manual.yml --ref release/v$minor -F microService=join-service -F imageTag=v$ver -F version=$ver --repo edgelesssys/constellation gh workflow run build-micro-service-manual.yml --ref release/v$minor -F microService=kmsserver -F imageTag=v$ver -F version=$ver --repo edgelesssys/constellation gh workflow run build-micro-service-manual.yml --ref release/v$minor -F microService=verification-service -F imageTag=v$ver -F version=$ver --repo edgelesssys/constellation diff --git a/.github/workflows/build-access-manager-image.yml b/.github/workflows/build-access-manager-image.yml deleted file mode 100644 index cf56088ce..000000000 --- a/.github/workflows/build-access-manager-image.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Build and upload access-manager image -env: - REGISTRY: ghcr.io - IMAGE_NAME: access-manager - -on: - workflow_dispatch: - push: - branches: - - main - - "release/**" - paths: - - "access_manager/**" - - "internal/deploy/**" - -jobs: - build-access-manager: - runs-on: ubuntu-22.04 - permissions: - contents: read - packages: write - steps: - - name: Check out repository - id: checkout - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0 - - - name: Setup Go environment - uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f # tag=v3.3.1 - with: - go-version: "1.19.3" - - - name: Build and upload access-manager container image - id: build-and-upload - uses: ./.github/actions/build_micro_service - with: - name: access-manager - projectVersion: "0.0.0" - dockerfile: access_manager/Dockerfile - githubToken: ${{ secrets.GITHUB_TOKEN }} - cosignPublicKey: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PUBLIC_KEY || secrets.COSIGN_DEV_PUBLIC_KEY }} - cosignPrivateKey: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PRIVATE_KEY || secrets.COSIGN_DEV_PRIVATE_KEY }} - cosignPassword: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PASSWORD || secrets.COSIGN_DEV_PASSWORD }} diff --git a/.github/workflows/build-micro-service-manual.yml b/.github/workflows/build-micro-service-manual.yml index 1c4944a2c..16623ce79 100644 --- a/.github/workflows/build-micro-service-manual.yml +++ b/.github/workflows/build-micro-service-manual.yml @@ -7,12 +7,11 @@ on: description: "Name of the micro-service image to build" type: choice options: - - "access-manager" - "join-service" - "kmsserver" - "verification-service" required: true - default: "access-manager" + default: "join-service" imageTag: description: "Container image tag" required: true @@ -43,8 +42,6 @@ jobs: id: set-variable run: | case "${{ inputs.microService }}" in - "access-manager" ) - echo "microServiceDockerfile=access_manager/Dockerfile" >> $GITHUB_ENV ;; "join-service" ) echo "microServiceDockerfile=joinservice/Dockerfile" >> $GITHUB_ENV ;; "kmsserver" ) diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml index 17efb4de3..9a5dd17cb 100644 --- a/.github/workflows/check-links.yml +++ b/.github/workflows/check-links.yml @@ -26,6 +26,7 @@ jobs: - name: Link Checker uses: lycheeverse/lychee-action@4dcb8bee2a0a4531cba1a1f392c54e8375d6dd81 # v1.5.4 with: + args: "--verbose --no-progress --max-concurrency 5 './**/*.md' './**/*.html'" fail: true env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/CHANGELOG.md b/CHANGELOG.md index bce85b828..8a0a68a8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed +- `access-manager` was removed from code base. K8s native way to SSH into nodes documented. + ## [2.2.0] - 2022-11-08 diff --git a/access_manager/Dockerfile b/access_manager/Dockerfile deleted file mode 100644 index 4bced48ed..000000000 --- a/access_manager/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -FROM fedora:36@sha256:455fec9590de794fbc21f61dbc7e90bf9918b58492d2a03fa269c09db47b43f6 as build - -RUN dnf -y update && \ - dnf -y install @development-tools pkg-config iproute iputils wget git jq openssl-devel cryptsetup-libs cryptsetup-devel && \ - dnf clean all - -# Install Go -ARG GO_VER=1.19.3 -RUN wget -q https://go.dev/dl/go${GO_VER}.linux-amd64.tar.gz && \ - tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz && \ - rm go${GO_VER}.linux-amd64.tar.gz -ENV PATH ${PATH}:/usr/local/go/bin - -# Download go dependencies -WORKDIR /constellation/ -COPY go.mod ./ -COPY go.sum ./ -RUN go mod download all - -# Copy Repo -COPY . /constellation -RUN rm -rf ./hack/ - -# Build the access_manager -WORKDIR /constellation/access_manager/ -RUN --mount=type=cache,target=/root/.cache/go-build CGO_ENABLED=0 go build -o /constellation/build/access_manager -ldflags "-s -w" . - -# Copy the access_manager from build into a scratch container, which is eventually deployed into the cluster -FROM scratch as release -COPY --from=build /constellation/build/access_manager /access_manager -ENTRYPOINT [ "/access_manager" ] diff --git a/access_manager/access_manager.go b/access_manager/access_manager.go deleted file mode 100644 index 3642cf8a3..000000000 --- a/access_manager/access_manager.go +++ /dev/null @@ -1,335 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package main - -import ( - "context" - "errors" - "flag" - "fmt" - "os" - "path" - "path/filepath" - "syscall" - "time" - - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" - "github.com/edgelesssys/constellation/v2/internal/deploy/user" - "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/spf13/afero" - "go.uber.org/zap" - - v1 "k8s.io/api/core/v1" - v1Options "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" -) - -const ( - // hostPath holds the path to the host's root file system we chroot into. - hostPath = "/host" - - // normalHomePath holds the general home directory of a system. - normalHomePath = "/var/home" - - // evictedHomePath holds the directory to which deleted user directories are moved to. - evictedHomePath = "/var/evicted" - - // relativePathToSSHKeys holds the path inside a user's directory to the SSH keys. - // Needs to be in sync with internal/deploy/ssh.go. - relativePathToSSHKeys = ".ssh/authorized_keys.d/constellation-ssh-keys" - - // timeout is the maximum time to wait for communication with the Kubernetes API server. - timeout = 60 * time.Second -) - -// uidGidPair holds the user owner and group owner of a directory. -type uidGIDPair struct { - UID uint32 - GID uint32 -} - -func main() { - verbosity := flag.Int("v", 0, logger.CmdLineVerbosityDescription) - - flag.Parse() - log := logger.New(logger.JSONLog, logger.VerbosityFromInt(*verbosity)) - - hostname, err := os.Hostname() - if err != nil { - log.Warnf("Starting constellation-access-manager as unknown pod") - } else { - log.Infof("Starting constellation-access-manager as %q", hostname) - } - - // Retrieve configMap from Kubernetes API before we chroot into the host filesystem. - configMap, err := retrieveConfigMap(log) - if err != nil { - log.With(zap.Error(err)).Fatalf("Failed to retrieve ConfigMap from Kubernetes API") - } - - // Chroot into main system - if err := syscall.Chroot(hostPath); err != nil { - log.With(zap.Error(err)).Fatalf("Failed to chroot into host filesystem") - } - if err := syscall.Chdir("/"); err != nil { - log.With(zap.Error(err)).Fatalf("Failed to chdir into host filesystem") - } - - fs := afero.NewOsFs() - linuxUserManager := user.NewLinuxUserManager(fs) - - if err := run(log, fs, linuxUserManager, configMap); err != nil { - // So far there is only one error path in this code, and this is getting the user directories... So just make the error specific here for now. - log.With(zap.Error(err)).Fatalf("Failed to retrieve existing user directories") - } -} - -// loadClientSet loads the Kubernetes API client. -func loadClientSet() (*kubernetes.Clientset, error) { - // creates the in-cluster config - config, err := rest.InClusterConfig() - if err != nil { - return nil, err - } - // creates the clientset - clientset, err := kubernetes.NewForConfig(config) - if err != nil { - return nil, err - } - - return clientset, nil -} - -// deployKeys creates or evicts users based on the ConfigMap and deploy their SSH keys. -func deployKeys( - ctx context.Context, log *logger.Logger, configMap *v1.ConfigMap, fs afero.Fs, - linuxUserManager user.LinuxUserManager, userMap map[string]uidGIDPair, sshAccess *ssh.Access, -) { - // If no ConfigMap exists or has been emptied, evict all users and exit. - if configMap == nil || len(configMap.Data) == 0 { - for username, ownership := range userMap { - log := log.With(zap.String("username", username)) - if username != "root" { - evictedUserPath := path.Join(evictedHomePath, username) - log.With(zap.Uint32("UID", ownership.UID), zap.Uint32("GID", ownership.GID)). - Infof("Evicting user to %q", evictedUserPath) - - if err := evictUser(username, fs, linuxUserManager); err != nil { - log.With(zap.Error(err)).Errorf("Did not evict user") - continue - } - } else { - log.Infof("Removing any old keys for 'root', if existent") - // Remove root's SSH key specifically instead of evicting the whole directory. - if err := evictRootKey(fs, linuxUserManager); err != nil && !os.IsNotExist(err) { - log.With(zap.Error(err)).Errorf("Failed to remove previously existing root key") - continue - } - } - } - - return - } - - // First, recreate users that already existed, if they are defined in the configMap. - // For users which do not exist, we move their user directories to avoid accidental takeovers but also loss of data. - for username, ownership := range userMap { - log := log.With(zap.String("username", username)) - if username != "root" { - if _, ok := configMap.Data[username]; ok { - log.With(zap.Uint32("UID", ownership.UID), zap.Uint32("GID", ownership.GID)). - Infof("Recreating user, if not existent") - - if err := linuxUserManager.Creator.CreateUserWithSpecificUIDAndGID( - ctx, username, int(ownership.UID), int(ownership.GID), - ); err != nil { - if errors.Is(err, user.ErrUserOrGroupAlreadyExists) { - log.Infof("User already exists, skipping") - } else { - log.With(zap.Error(err)).Errorf("Failed to recreate user") - } - continue - } - } else { - evictedUserPath := path.Join(evictedHomePath, username) - log.With(zap.Uint32("UID", ownership.UID), zap.Uint32("GID", ownership.GID)). - Infof("Evicting user to %q", evictedUserPath) - if err := evictUser(username, fs, linuxUserManager); err != nil { - log.With(zap.Error(err)).Errorf("Did not evict user") - continue - } - } - } else { - log.Infof("Removing any old keys for 'root', if existent") - // Always remove the root key first, even if it is about to be redeployed. - if err := evictRootKey(fs, linuxUserManager); err != nil && !os.IsNotExist(err) { - log.With(zap.Error(err)).Errorf("Failed to remove previously existing root key") - continue - } - } - } - - // Then, create the remaining users from the configMap (if remaining) and deploy SSH keys for all users. - for username, publicKey := range configMap.Data { - log := log.With(zap.String("username", username)) - if _, ok := userMap[username]; !ok { - log.Infof("Creating user") - if err := linuxUserManager.Creator.CreateUser(ctx, username); err != nil { - if errors.Is(err, user.ErrUserOrGroupAlreadyExists) { - log.Infof("User already exists, skipping") - } else { - log.With(zap.Error(err)).Errorf("Failed to create user") - } - continue - } - } - - // If we created a user, let's actually get the home directory instead of assuming it's the same as the normal home directory. - user, err := linuxUserManager.GetLinuxUser(username) - if err != nil { - log.With(zap.Error(err)).Errorf("Failed to retrieve information about user") - continue - } - - // Delete already deployed keys - pathToSSHKeys := filepath.Join(user.Home, relativePathToSSHKeys) - if err := fs.Remove(pathToSSHKeys); err != nil && !os.IsNotExist(err) { - log.With(zap.Error(err)).Errorf("Failed to delete remaining managed SSH keys for user") - continue - } - - // And (re)deploy the keys from the ConfigMap - newKey := ssh.UserKey{ - Username: username, - PublicKey: publicKey, - } - - log.Infof("Deploying new SSH key for user") - if err := sshAccess.DeployAuthorizedKey(context.Background(), newKey); err != nil { - log.With(zap.Error(err)).Errorf("Failed to deploy SSH keys for user") - continue - } - } -} - -// evictUser moves a user directory to evictedPath and changes their owner recursive to root. -func evictUser(username string, fs afero.Fs, linuxUserManager user.LinuxUserManager) error { - if _, err := linuxUserManager.GetLinuxUser(username); err == nil { - return fmt.Errorf("user '%s' still seems to exist", username) - } - - // First, ensure evictedPath already exists. - if err := fs.MkdirAll(evictedHomePath, 0o700); err != nil { - return err - } - - // Build paths to the user's home directory and evicted home directory, which includes a timestamp to avoid collisions. - oldUserDir := path.Join(normalHomePath, username) - evictedUserDir := path.Join(evictedHomePath, fmt.Sprintf("%s_%d", username, time.Now().Unix())) - - // Move old, not recreated user directory to evictedPath. - if err := fs.Rename(oldUserDir, evictedUserDir); err != nil { - return err - } - - // Chown the user directory and all files inside to root, but do not change permissions to allow recovery without messed up permissions. - if err := fs.Chown(evictedUserDir, 0, 0); err != nil { - return err - } - if err := afero.Walk(fs, evictedUserDir, func(name string, info os.FileInfo, err error) error { - if err == nil { - err = fs.Chown(name, 0, 0) - } - - return err - }); err != nil { - return err - } - - return nil -} - -// evictRootKey removes the root key from the filesystem, instead of evicting the whole user directory. -func evictRootKey(fs afero.Fs, linuxUserManager user.LinuxUserManager) error { - user, err := linuxUserManager.GetLinuxUser("root") - if err != nil { - return err - } - - // Delete already deployed keys - pathToSSHKeys := filepath.Join(user.Home, relativePathToSSHKeys) - if err := fs.Remove(pathToSSHKeys); err != nil && !os.IsNotExist(err) { - return err - } - - return nil -} - -// retrieveConfigMap contacts the Kubernetes API server and retrieves the ssh-users ConfigMap. -func retrieveConfigMap(log *logger.Logger) (*v1.ConfigMap, error) { - // Authenticate with the Kubernetes API and get the information from the ssh-users ConfigMap to recreate the users we need. - log.Infof("Authenticating with Kubernetes...") - clientset, err := loadClientSet() - if err != nil { - return nil, err - } - - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - log.Infof("Requesting 'ssh-users' ConfigMap...") - configmap, err := clientset.CoreV1().ConfigMaps("kube-system").Get(ctx, "ssh-users", v1Options.GetOptions{}) - if err != nil { - return nil, err - } - - return configmap, err -} - -// generateUserMap iterates the list of existing home directories to create a map of previously existing usernames to their previous respective UID and GID. -func generateUserMap(log *logger.Logger, fs afero.Fs) (map[string]uidGIDPair, error) { - // Go through the normalHomePath directory, and create a mapping of existing user names in combination with their owner's UID & GID. - // We use this information later to create missing users under the same UID and GID to avoid breakage. - fileInfo, err := afero.ReadDir(fs, normalHomePath) - if err != nil { - return nil, err - } - - userMap := make(map[string]uidGIDPair) - userMap["root"] = uidGIDPair{UID: 0, GID: 0} - // This will fail under MemMapFS, since it's not UNIX-compatible. - for _, singleInfo := range fileInfo { - log := log.With("username", singleInfo.Name()) - // Fail gracefully instead of hard. - if stat, ok := singleInfo.Sys().(*syscall.Stat_t); ok { - userMap[singleInfo.Name()] = uidGIDPair{UID: stat.Uid, GID: stat.Gid} - log.With(zap.Uint32("UID", stat.Uid), zap.Uint32("GID", stat.Gid)). - Infof("Found home directory for user") - } else { - log.Warnf("Failed to retrieve UNIX stat for user. User will not be evicted, or if this directory belongs to a user that is to be created later, it might be created under a different UID/GID than before") - continue - } - } - - return userMap, nil -} - -func run(log *logger.Logger, fs afero.Fs, linuxUserManager user.LinuxUserManager, configMap *v1.ConfigMap) error { - sshAccess := ssh.NewAccess(log, linuxUserManager) - - // Generate userMap containing existing user directories and their ownership - userMap, err := generateUserMap(log, fs) - if err != nil { - return err - } - - // Try to deploy keys based on configmap. - deployKeys(context.Background(), log, configMap, fs, linuxUserManager, userMap, sshAccess) - - return nil -} diff --git a/access_manager/access_manager_test.go b/access_manager/access_manager_test.go deleted file mode 100644 index d615a07e5..000000000 --- a/access_manager/access_manager_test.go +++ /dev/null @@ -1,331 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package main - -import ( - "context" - "os" - "path" - "path/filepath" - "strconv" - "strings" - "testing" - - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" - "github.com/edgelesssys/constellation/v2/internal/deploy/user" - "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/spf13/afero" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.uber.org/goleak" - v1 "k8s.io/api/core/v1" -) - -func TestMain(m *testing.M) { - goleak.VerifyTestMain(m) -} - -func TestEvictUser(t *testing.T) { - require := require.New(t) - assert := assert.New(t) - - fs := afero.NewMemMapFs() - linuxUserManager := user.NewLinuxUserManagerFake(fs) - - // Create fake user directory - homePath := path.Join(normalHomePath, "myuser") - err := fs.MkdirAll(homePath, 0o700) - require.NoError(err) - - // Try to evict the user - assert.NoError(evictUser("myuser", fs, linuxUserManager)) - - // Check if user has been evicted - homeEntries, err := afero.ReadDir(fs, normalHomePath) - require.NoError(err) - evictedEntries, err := afero.ReadDir(fs, evictedHomePath) - require.NoError(err) - assert.Len(homeEntries, 0) - assert.Len(evictedEntries, 1) - for _, singleEntry := range evictedEntries { - assert.Contains(singleEntry.Name(), "myuser") - } - - /* - Note: Unfourtunaly, due to a bug in afero, we cannot test that the files inside the directory have actually been moved. - This works on the real filesystem, but not on the memory filesystem. - See: https://github.com/spf13/afero/issues/141 (known since 2017, guess it will never get fixed ¯\_(ツ)_/¯) - This limits the scope of this test, obviously... But I think as long as we can move the directory, - the functionality on the real filesystem should be there (unless it throws an error). - */ -} - -func TestDeployKeys(t *testing.T) { - require := require.New(t) - assert := assert.New(t) - - testCases := map[string]struct { - configMap *v1.ConfigMap - existingUsers map[string]uidGIDPair - }{ - "undefined": {}, - "undefined map, empty users": {existingUsers: map[string]uidGIDPair{}}, - "empty map, undefined users": {configMap: &v1.ConfigMap{}}, - "both empty": { - configMap: &v1.ConfigMap{ - Data: map[string]string{}, - }, - existingUsers: map[string]uidGIDPair{}, - }, - "create two users, no existing users": { - configMap: &v1.ConfigMap{ - Data: map[string]string{ - "user1": "ssh-rsa abcdefgh", - "user2": "ssh-ed25519 defghijklm", - }, - }, - existingUsers: map[string]uidGIDPair{}, - }, - "empty configMap, user1 and user2 should be evicted": { - configMap: &v1.ConfigMap{ - Data: map[string]string{}, - }, - existingUsers: map[string]uidGIDPair{ - "user1": { - UID: 1000, - GID: 1000, - }, - "user2": { - UID: 1001, - GID: 1001, - }, - }, - }, - "configMap contains user2, user1 should be evicted, user2 recreated": { - configMap: &v1.ConfigMap{ - Data: map[string]string{ - "user2": "ssh-rsa abcdefg", - }, - }, - existingUsers: map[string]uidGIDPair{ - "user1": { - UID: 1000, - GID: 1000, - }, - "user2": { - UID: 1001, - GID: 1001, - }, - }, - }, - "configMap contains user1 and user3, user1 should be recreated, user2 evicted, user3 created": { - configMap: &v1.ConfigMap{ - Data: map[string]string{ - "user1": "ssh-rsa abcdefg", - "user3": "ssh-ed25519 defghijklm", - }, - }, - existingUsers: map[string]uidGIDPair{ - "user1": { - UID: 1000, - GID: 1000, - }, - "user2": { - UID: 1001, - GID: 1001, - }, - }, - }, - "configMap contains user1 and user3, both should be recreated": { - configMap: &v1.ConfigMap{ - Data: map[string]string{ - "user1": "ssh-rsa abcdefg", - "user3": "ssh-ed25519 defghijklm", - }, - }, - existingUsers: map[string]uidGIDPair{ - "user1": { - UID: 1000, - GID: 1000, - }, - "user3": { - UID: 1002, - GID: 1002, - }, - }, - }, - "configMap contains user2, user1 and user3 should be evicted, user2 should be created": { - configMap: &v1.ConfigMap{ - Data: map[string]string{ - "user2": "ssh-ed25519 defghijklm", - }, - }, - existingUsers: map[string]uidGIDPair{ - "user1": { - UID: 1000, - GID: 1000, - }, - "user3": { - UID: 1002, - GID: 1002, - }, - }, - }, - } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - fs := afero.NewMemMapFs() - require.NoError(fs.MkdirAll(normalHomePath, 0o700)) - require.NoError(fs.Mkdir("/etc", 0o644)) - _, err := fs.Create("/etc/passwd") - require.NoError(err) - - // Create fake user directories - for user := range tc.existingUsers { - userHomePath := path.Join(normalHomePath, user) - err := fs.MkdirAll(userHomePath, 0o700) - require.NoError(err) - require.NoError(fs.Chown(userHomePath, int(tc.existingUsers[user].UID), int(tc.existingUsers[user].GID))) - } - - log := logger.NewTest(t) - linuxUserManager := user.NewLinuxUserManagerFake(fs) - sshAccess := ssh.NewAccess(log, linuxUserManager) - deployKeys(context.Background(), log, tc.configMap, fs, linuxUserManager, tc.existingUsers, sshAccess) - - // Unfortunately, we cannot retrieve the UID/GID from afero's MemMapFs without weird hacks, - // as it does not have getters and it is not exported. - if tc.configMap != nil && tc.existingUsers != nil { - // Parse /etc/passwd and check for users - passwdEntries, err := linuxUserManager.Passwd.Parse(fs) - require.NoError(err) - - // Check recreation or deletion - for user := range tc.existingUsers { - if _, ok := tc.configMap.Data[user]; ok { - checkHomeDirectory(user, fs, assert, true) - - // Check if user exists in /etc/passwd - userEntry, ok := passwdEntries[user] - assert.True(ok) - - // Check if user has been recreated with correct UID/GID - actualUID, err := strconv.Atoi(userEntry.UID) - assert.NoError(err) - assert.EqualValues(tc.existingUsers[user].UID, actualUID) - actualGID, err := strconv.Atoi(userEntry.GID) - assert.NoError(err) - assert.EqualValues(tc.existingUsers[user].GID, actualGID) - - // Check if the user has the right keys - checkSSHKeys(user, fs, assert, tc.configMap.Data[user]+"\n") - - } else { - // Check if home directory is not available anymore under the regular path - checkHomeDirectory(user, fs, assert, false) - - // Check if home directory has been evicted - homeDirs, err := afero.ReadDir(fs, evictedHomePath) - require.NoError(err) - - var userDirectoryName string - for _, singleDir := range homeDirs { - if strings.Contains(singleDir.Name(), user+"_") { - userDirectoryName = singleDir.Name() - break - } - } - assert.NotEmpty(userDirectoryName) - - // Check if user does not exist in /etc/passwd - _, ok := passwdEntries[user] - assert.False(ok) - } - } - - // Check creation of new users - for user := range tc.configMap.Data { - // We already checked recreated or evicted users, so skip them. - if _, ok := tc.existingUsers[user]; ok { - continue - } - - checkHomeDirectory(user, fs, assert, true) - checkSSHKeys(user, fs, assert, tc.configMap.Data[user]+"\n") - } - } - }) - } -} - -func TestEvictRootKey(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - fs := afero.NewMemMapFs() - - // Create /etc/passwd with root entry - require.NoError(fs.Mkdir("/etc", 0o644)) - file, err := fs.Create("/etc/passwd") - require.NoError(err) - passwdRootEntry := "root:x:0:0:root:/root:/bin/bash\n" - n, err := file.WriteString(passwdRootEntry) - require.NoError(err) - require.Equal(len(passwdRootEntry), n) - - // Deploy a fake key for root - require.NoError(fs.MkdirAll("/root/.ssh/authorized_keys.d", 0o700)) - file, err = fs.Create(filepath.Join("/root", relativePathToSSHKeys)) - require.NoError(err) - _, err = file.WriteString("ssh-ed25519 abcdefghijklm\n") - require.NoError(err) - - linuxUserManager := user.NewLinuxUserManagerFake(fs) - - // Parse /etc/passwd and check for users - passwdEntries, err := linuxUserManager.Passwd.Parse(fs) - require.NoError(err) - - // Check if user exists in /etc/passwd - userEntry, ok := passwdEntries["root"] - assert.True(ok) - - // Check if user has been recreated with correct UID/GID - actualUID, err := strconv.Atoi(userEntry.UID) - assert.NoError(err) - assert.EqualValues(0, actualUID) - actualGID, err := strconv.Atoi(userEntry.GID) - assert.NoError(err) - assert.EqualValues(0, actualGID) - - // Delete the key - assert.NoError(evictRootKey(fs, linuxUserManager)) - - // Check if the key has been deleted - _, err = fs.Stat(filepath.Join("/root", relativePathToSSHKeys)) - assert.True(os.IsNotExist(err)) -} - -func checkSSHKeys(user string, fs afero.Fs, assert *assert.Assertions, expectedValue string) { - // Do the same check as above - _, err := fs.Stat(path.Join(normalHomePath, user)) - assert.NoError(err) - - // Check if the user has the right keys - authorizedKeys, err := afero.ReadFile(fs, filepath.Join(normalHomePath, user, relativePathToSSHKeys)) - assert.NoError(err) - assert.EqualValues(expectedValue, string(authorizedKeys)) -} - -func checkHomeDirectory(user string, fs afero.Fs, assert *assert.Assertions, shouldExist bool) { - _, err := fs.Stat(path.Join(normalHomePath, user)) - if shouldExist { - assert.NoError(err) - } else { - assert.Error(err) - assert.True(os.IsNotExist(err)) - } -} diff --git a/bootstrapper/cmd/bootstrapper/test.go b/bootstrapper/cmd/bootstrapper/test.go index 449dc0226..11cbe44e2 100644 --- a/bootstrapper/cmd/bootstrapper/test.go +++ b/bootstrapper/cmd/bootstrapper/test.go @@ -21,7 +21,7 @@ type clusterFake struct{} // InitCluster fakes bootstrapping a new cluster with the current node being the master, returning the arguments required to join the cluster. func (c *clusterFake) InitCluster( context.Context, string, string, []byte, []uint32, bool, []byte, bool, - map[string]string, []byte, bool, *logger.Logger, + []byte, bool, *logger.Logger, ) ([]byte, error) { return []byte{}, nil } diff --git a/bootstrapper/initproto/init.pb.go b/bootstrapper/initproto/init.pb.go index e3e76cac8..f7e49915e 100644 --- a/bootstrapper/initproto/init.pb.go +++ b/bootstrapper/initproto/init.pb.go @@ -26,19 +26,19 @@ type InitRequest struct { unknownFields protoimpl.UnknownFields // repeated string autoscaling_node_groups = 1; removed - MasterSecret []byte `protobuf:"bytes,2,opt,name=master_secret,json=masterSecret,proto3" json:"master_secret,omitempty"` - KmsUri string `protobuf:"bytes,3,opt,name=kms_uri,json=kmsUri,proto3" json:"kms_uri,omitempty"` - StorageUri string `protobuf:"bytes,4,opt,name=storage_uri,json=storageUri,proto3" json:"storage_uri,omitempty"` - KeyEncryptionKeyId string `protobuf:"bytes,5,opt,name=key_encryption_key_id,json=keyEncryptionKeyId,proto3" json:"key_encryption_key_id,omitempty"` - UseExistingKek bool `protobuf:"varint,6,opt,name=use_existing_kek,json=useExistingKek,proto3" json:"use_existing_kek,omitempty"` - CloudServiceAccountUri string `protobuf:"bytes,7,opt,name=cloud_service_account_uri,json=cloudServiceAccountUri,proto3" json:"cloud_service_account_uri,omitempty"` - KubernetesVersion string `protobuf:"bytes,8,opt,name=kubernetes_version,json=kubernetesVersion,proto3" json:"kubernetes_version,omitempty"` - SshUserKeys []*SSHUserKey `protobuf:"bytes,9,rep,name=ssh_user_keys,json=sshUserKeys,proto3" json:"ssh_user_keys,omitempty"` - Salt []byte `protobuf:"bytes,10,opt,name=salt,proto3" json:"salt,omitempty"` - HelmDeployments []byte `protobuf:"bytes,11,opt,name=helm_deployments,json=helmDeployments,proto3" json:"helm_deployments,omitempty"` - EnforcedPcrs []uint32 `protobuf:"varint,12,rep,packed,name=enforced_pcrs,json=enforcedPcrs,proto3" json:"enforced_pcrs,omitempty"` - EnforceIdkeydigest bool `protobuf:"varint,13,opt,name=enforce_idkeydigest,json=enforceIdkeydigest,proto3" json:"enforce_idkeydigest,omitempty"` - ConformanceMode bool `protobuf:"varint,14,opt,name=conformance_mode,json=conformanceMode,proto3" json:"conformance_mode,omitempty"` + MasterSecret []byte `protobuf:"bytes,2,opt,name=master_secret,json=masterSecret,proto3" json:"master_secret,omitempty"` + KmsUri string `protobuf:"bytes,3,opt,name=kms_uri,json=kmsUri,proto3" json:"kms_uri,omitempty"` + StorageUri string `protobuf:"bytes,4,opt,name=storage_uri,json=storageUri,proto3" json:"storage_uri,omitempty"` + KeyEncryptionKeyId string `protobuf:"bytes,5,opt,name=key_encryption_key_id,json=keyEncryptionKeyId,proto3" json:"key_encryption_key_id,omitempty"` + UseExistingKek bool `protobuf:"varint,6,opt,name=use_existing_kek,json=useExistingKek,proto3" json:"use_existing_kek,omitempty"` + CloudServiceAccountUri string `protobuf:"bytes,7,opt,name=cloud_service_account_uri,json=cloudServiceAccountUri,proto3" json:"cloud_service_account_uri,omitempty"` + KubernetesVersion string `protobuf:"bytes,8,opt,name=kubernetes_version,json=kubernetesVersion,proto3" json:"kubernetes_version,omitempty"` + // repeated SSHUserKey ssh_user_keys = 9; removed + Salt []byte `protobuf:"bytes,10,opt,name=salt,proto3" json:"salt,omitempty"` + HelmDeployments []byte `protobuf:"bytes,11,opt,name=helm_deployments,json=helmDeployments,proto3" json:"helm_deployments,omitempty"` + EnforcedPcrs []uint32 `protobuf:"varint,12,rep,packed,name=enforced_pcrs,json=enforcedPcrs,proto3" json:"enforced_pcrs,omitempty"` + EnforceIdkeydigest bool `protobuf:"varint,13,opt,name=enforce_idkeydigest,json=enforceIdkeydigest,proto3" json:"enforce_idkeydigest,omitempty"` + ConformanceMode bool `protobuf:"varint,14,opt,name=conformance_mode,json=conformanceMode,proto3" json:"conformance_mode,omitempty"` } func (x *InitRequest) Reset() { @@ -122,13 +122,6 @@ func (x *InitRequest) GetKubernetesVersion() string { return "" } -func (x *InitRequest) GetSshUserKeys() []*SSHUserKey { - if x != nil { - return x.SshUserKeys - } - return nil -} - func (x *InitRequest) GetSalt() []byte { if x != nil { return x.Salt @@ -227,66 +220,11 @@ func (x *InitResponse) GetClusterId() []byte { return nil } -type SSHUserKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` - PublicKey string `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` -} - -func (x *SSHUserKey) Reset() { - *x = SSHUserKey{} - if protoimpl.UnsafeEnabled { - mi := &file_init_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SSHUserKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SSHUserKey) ProtoMessage() {} - -func (x *SSHUserKey) ProtoReflect() protoreflect.Message { - mi := &file_init_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SSHUserKey.ProtoReflect.Descriptor instead. -func (*SSHUserKey) Descriptor() ([]byte, []int) { - return file_init_proto_rawDescGZIP(), []int{2} -} - -func (x *SSHUserKey) GetUsername() string { - if x != nil { - return x.Username - } - return "" -} - -func (x *SSHUserKey) GetPublicKey() string { - if x != nil { - return x.PublicKey - } - return "" -} - var File_init_proto protoreflect.FileDescriptor var file_init_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x69, 0x6e, - 0x69, 0x74, 0x22, 0xa9, 0x04, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x69, 0x74, 0x22, 0xf3, 0x03, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x6d, 0x73, 0x5f, 0x75, @@ -305,42 +243,34 @@ var file_init_proto_rawDesc = []byte{ 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x72, 0x69, 0x12, 0x2d, 0x0a, 0x12, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, - 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x0d, 0x73, 0x73, 0x68, 0x5f, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x10, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x53, 0x53, 0x48, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x65, - 0x79, 0x52, 0x0b, 0x73, 0x73, 0x68, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x61, - 0x6c, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6d, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x68, 0x65, - 0x6c, 0x6d, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x23, 0x0a, - 0x0d, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x5f, 0x70, 0x63, 0x72, 0x73, 0x18, 0x0c, - 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x50, 0x63, - 0x72, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x6b, 0x65, 0x79, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x12, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x49, 0x64, 0x6b, 0x65, 0x79, 0x64, 0x69, 0x67, - 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, - 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, - 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x68, - 0x0a, 0x0c, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0a, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, - 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x47, 0x0a, 0x0a, 0x53, 0x53, 0x48, 0x55, - 0x73, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x32, 0x34, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x2d, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, - 0x12, 0x11, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, - 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, - 0x76, 0x32, 0x2f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2f, - 0x69, 0x6e, 0x69, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x61, 0x6c, 0x74, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x12, 0x29, 0x0a, 0x10, + 0x68, 0x65, 0x6c, 0x6d, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x68, 0x65, 0x6c, 0x6d, 0x44, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x64, 0x5f, 0x70, 0x63, 0x72, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, + 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x50, 0x63, 0x72, 0x73, 0x12, 0x2f, 0x0a, 0x13, + 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x64, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x6e, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x49, 0x64, 0x6b, 0x65, 0x79, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, + 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x68, 0x0a, 0x0c, 0x49, 0x6e, 0x69, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6b, 0x75, 0x62, 0x65, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6b, 0x75, + 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x49, 0x64, 0x32, 0x34, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x2d, 0x0a, 0x04, 0x49, 0x6e, 0x69, + 0x74, 0x12, 0x11, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, + 0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x76, 0x32, 0x2f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -355,21 +285,19 @@ func file_init_proto_rawDescGZIP() []byte { return file_init_proto_rawDescData } -var file_init_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_init_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_init_proto_goTypes = []interface{}{ (*InitRequest)(nil), // 0: init.InitRequest (*InitResponse)(nil), // 1: init.InitResponse - (*SSHUserKey)(nil), // 2: init.SSHUserKey } var file_init_proto_depIdxs = []int32{ - 2, // 0: init.InitRequest.ssh_user_keys:type_name -> init.SSHUserKey - 0, // 1: init.API.Init:input_type -> init.InitRequest - 1, // 2: init.API.Init:output_type -> init.InitResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 0, // 0: init.API.Init:input_type -> init.InitRequest + 1, // 1: init.API.Init:output_type -> init.InitResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_init_proto_init() } @@ -402,18 +330,6 @@ func file_init_proto_init() { return nil } } - file_init_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SSHUserKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } type x struct{} out := protoimpl.TypeBuilder{ @@ -421,7 +337,7 @@ func file_init_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_init_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 2, NumExtensions: 0, NumServices: 1, }, diff --git a/bootstrapper/initproto/init.proto b/bootstrapper/initproto/init.proto index 87169bf50..cec3d9ea2 100644 --- a/bootstrapper/initproto/init.proto +++ b/bootstrapper/initproto/init.proto @@ -17,7 +17,7 @@ message InitRequest { bool use_existing_kek = 6; string cloud_service_account_uri = 7; string kubernetes_version = 8; - repeated SSHUserKey ssh_user_keys = 9; + // repeated SSHUserKey ssh_user_keys = 9; removed bytes salt = 10; bytes helm_deployments = 11; repeated uint32 enforced_pcrs = 12; @@ -30,8 +30,3 @@ message InitResponse { bytes owner_id = 2; bytes cluster_id = 3; } - -message SSHUserKey { - string username = 1; - string public_key = 2; -} diff --git a/bootstrapper/internal/initserver/initserver.go b/bootstrapper/internal/initserver/initserver.go index 7b3f78fa7..c74113db0 100644 --- a/bootstrapper/internal/initserver/initserver.go +++ b/bootstrapper/internal/initserver/initserver.go @@ -131,7 +131,6 @@ func (s *Server) Init(ctx context.Context, req *initproto.InitRequest) (*initpro req.EnforceIdkeydigest, s.issuerWrapper.IDKeyDigest(), s.issuerWrapper.VMType() == vmtype.AzureCVM, - sshProtoKeysToMap(req.SshUserKeys), req.HelmDeployments, req.ConformanceMode, s.log, @@ -199,14 +198,6 @@ func (i *IssuerWrapper) IDKeyDigest() []byte { return i.idkeydigest } -func sshProtoKeysToMap(keys []*initproto.SSHUserKey) map[string]string { - keyMap := make(map[string]string) - for _, key := range keys { - keyMap[key.Username] = key.PublicKey - } - return keyMap -} - func deriveMeasurementValues(masterSecret, hkdfSalt []byte) (salt, clusterID []byte, err error) { salt, err = crypto.GenerateRandomBytes(crypto.RNGLengthDefault) if err != nil { @@ -236,7 +227,6 @@ type ClusterInitializer interface { enforceIDKeyDigest bool, idKeyDigest []byte, azureCVM bool, - sshUserKeys map[string]string, helmDeployments []byte, conformanceMode bool, log *logger.Logger, diff --git a/bootstrapper/internal/initserver/initserver_test.go b/bootstrapper/internal/initserver/initserver_test.go index 5ca2ccee3..0b9a1356c 100644 --- a/bootstrapper/internal/initserver/initserver_test.go +++ b/bootstrapper/internal/initserver/initserver_test.go @@ -155,45 +155,6 @@ func TestInit(t *testing.T) { } } -func TestSSHProtoKeysToMap(t *testing.T) { - testCases := map[string]struct { - keys []*initproto.SSHUserKey - want map[string]string - }{ - "empty": { - keys: []*initproto.SSHUserKey{}, - want: map[string]string{}, - }, - "one key": { - keys: []*initproto.SSHUserKey{ - {Username: "key1", PublicKey: "key1-key"}, - }, - want: map[string]string{ - "key1": "key1-key", - }, - }, - "two keys": { - keys: []*initproto.SSHUserKey{ - {Username: "key1", PublicKey: "key1-key"}, - {Username: "key2", PublicKey: "key2-key"}, - }, - want: map[string]string{ - "key1": "key1-key", - "key2": "key2-key", - }, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - assert := assert.New(t) - - got := sshProtoKeysToMap(tc.keys) - assert.Equal(tc.want, got) - }) - } -} - func TestSetupDisk(t *testing.T) { testCases := map[string]struct { uuid string @@ -289,7 +250,7 @@ type stubClusterInitializer struct { func (i *stubClusterInitializer) InitCluster( context.Context, string, string, []byte, []uint32, bool, []byte, bool, - map[string]string, []byte, bool, *logger.Logger, + []byte, bool, *logger.Logger, ) ([]byte, error) { return i.initClusterKubeconfig, i.initClusterErr } diff --git a/bootstrapper/internal/kubernetes/k8sapi/k8sutil.go b/bootstrapper/internal/kubernetes/k8sapi/k8sutil.go index 2feed68d6..54ac2a171 100644 --- a/bootstrapper/internal/kubernetes/k8sapi/k8sutil.go +++ b/bootstrapper/internal/kubernetes/k8sapi/k8sutil.go @@ -330,11 +330,6 @@ func (k *KubernetesUtil) SetupGCPGuestAgent(kubectl Client, guestAgentDaemonset return kubectl.Apply(guestAgentDaemonset, true) } -// SetupAccessManager deploys the constellation-access-manager for deploying SSH keys on control-plane & worker nodes. -func (k *KubernetesUtil) SetupAccessManager(kubectl Client, accessManagerConfiguration kubernetes.Marshaler) error { - return kubectl.Apply(accessManagerConfiguration, true) -} - // SetupVerificationService deploys the verification service. func (k *KubernetesUtil) SetupVerificationService(kubectl Client, verificationServiceConfiguration kubernetes.Marshaler) error { return kubectl.Apply(verificationServiceConfiguration, true) diff --git a/bootstrapper/internal/kubernetes/k8sapi/resources/access_manager.go b/bootstrapper/internal/kubernetes/k8sapi/resources/access_manager.go deleted file mode 100644 index 50f01d7ac..000000000 --- a/bootstrapper/internal/kubernetes/k8sapi/resources/access_manager.go +++ /dev/null @@ -1,203 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package resources - -import ( - "github.com/edgelesssys/constellation/v2/internal/kubernetes" - "github.com/edgelesssys/constellation/v2/internal/versions" - "google.golang.org/protobuf/proto" - apps "k8s.io/api/apps/v1" - k8s "k8s.io/api/core/v1" - rbac "k8s.io/api/rbac/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const accessManagerNamespace = "kube-system" - -// AccessManagerDeployment holds the configuration for the SSH user creation pods. User/Key definitions are stored in the ConfigMap, and the manager is deployed on each node by the DaemonSet. -type AccessManagerDeployment struct { - ConfigMap k8s.ConfigMap - ServiceAccount k8s.ServiceAccount - Role rbac.Role - RoleBinding rbac.RoleBinding - DaemonSet apps.DaemonSet -} - -// NewAccessManagerDeployment creates a new *accessManagerDeployment which manages the SSH users for the cluster. -func NewAccessManagerDeployment(sshUsers map[string]string) *AccessManagerDeployment { - return &AccessManagerDeployment{ - ServiceAccount: k8s.ServiceAccount{ - TypeMeta: v1.TypeMeta{ - APIVersion: "v1", - Kind: "ServiceAccount", - }, - ObjectMeta: v1.ObjectMeta{ - Labels: map[string]string{ - "app.kubernetes.io/instance": "constellation", - "app.kubernetes.io/name": "constellation-access-manager", - "app.kubernetes.io/managed-by": "Constellation", - }, - Name: "constellation-access-manager", - Namespace: accessManagerNamespace, - }, - AutomountServiceAccountToken: proto.Bool(true), - }, - ConfigMap: k8s.ConfigMap{ - TypeMeta: v1.TypeMeta{ - APIVersion: "v1", - Kind: "ConfigMap", - }, - ObjectMeta: v1.ObjectMeta{ - Name: "ssh-users", - Namespace: accessManagerNamespace, - }, - Data: sshUsers, - }, - DaemonSet: apps.DaemonSet{ - TypeMeta: v1.TypeMeta{ - APIVersion: "apps/v1", - Kind: "DaemonSet", - }, - ObjectMeta: v1.ObjectMeta{ - Name: "constellation-access-manager", - Namespace: accessManagerNamespace, - Labels: map[string]string{ - "app.kubernetes.io/instance": "constellation", - "app.kubernetes.io/name": "constellation-access-manager", - }, - }, - Spec: apps.DaemonSetSpec{ - Selector: &v1.LabelSelector{ - MatchLabels: map[string]string{ - "app.kubernetes.io/instance": "constellation", - "app.kubernetes.io/name": "constellation-access-manager", - }, - }, - Template: k8s.PodTemplateSpec{ - ObjectMeta: v1.ObjectMeta{ - Labels: map[string]string{ - "app.kubernetes.io/instance": "constellation", - "app.kubernetes.io/name": "constellation-access-manager", - }, - }, - Spec: k8s.PodSpec{ - Tolerations: []k8s.Toleration{ - { - Key: "node-role.kubernetes.io/master", - Operator: k8s.TolerationOpExists, - Effect: k8s.TaintEffectNoSchedule, - }, - { - Key: "node-role.kubernetes.io/control-plane", - Operator: k8s.TolerationOpExists, - Effect: k8s.TaintEffectNoSchedule, - }, - }, - Containers: []k8s.Container{ - { - Name: "pause", - Image: "gcr.io/google_containers/pause", - ImagePullPolicy: k8s.PullIfNotPresent, - }, - }, - InitContainers: []k8s.Container{ - { - Name: "constellation-access-manager", - Image: versions.AccessManagerImage, - VolumeMounts: []k8s.VolumeMount{ - { - Name: "host", - MountPath: "/host", - }, - }, - SecurityContext: &k8s.SecurityContext{ - Capabilities: &k8s.Capabilities{ - Add: []k8s.Capability{ - "SYS_CHROOT", - }, - }, - }, - }, - }, - ServiceAccountName: "constellation-access-manager", - Volumes: []k8s.Volume{ - { - Name: "host", - VolumeSource: k8s.VolumeSource{ - HostPath: &k8s.HostPathVolumeSource{ - Path: "/", - }, - }, - }, - }, - }, - }, - }, - }, - Role: rbac.Role{ - TypeMeta: v1.TypeMeta{ - APIVersion: "rbac.authorization.k8s.io/v1", - Kind: "Role", - }, - ObjectMeta: v1.ObjectMeta{ - Labels: map[string]string{ - "app.kubernetes.io/instance": "constellation", - "app.kubernetes.io/name": "constellation-access-manager", - "app.kubernetes.io/managed-by": "Constellation", - }, - Name: "constellation-access-manager", - Namespace: accessManagerNamespace, - }, - Rules: []rbac.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{ - "configmaps", - }, - ResourceNames: []string{ - "ssh-users", - }, - Verbs: []string{ - "get", - }, - }, - }, - }, - RoleBinding: rbac.RoleBinding{ - TypeMeta: v1.TypeMeta{ - APIVersion: "rbac.authorization.k8s.io/v1", - Kind: "RoleBinding", - }, - ObjectMeta: v1.ObjectMeta{ - Labels: map[string]string{ - "app.kubernetes.io/instance": "constellation", - "app.kubernetes.io/name": "constellation-access-manager", - "app.kubernetes.io/managed-by": "Constellation", - }, - Name: "constellation-access-manager", - Namespace: accessManagerNamespace, - }, - RoleRef: rbac.RoleRef{ - APIGroup: "rbac.authorization.k8s.io", - Kind: "Role", - Name: "constellation-access-manager", - }, - Subjects: []rbac.Subject{ - { - Kind: "ServiceAccount", - Name: "constellation-access-manager", - Namespace: accessManagerNamespace, - }, - }, - }, - } -} - -// Marshal marshals the access-manager deployment as YAML documents. -func (c *AccessManagerDeployment) Marshal() ([]byte, error) { - return kubernetes.MarshalK8SResources(c) -} diff --git a/bootstrapper/internal/kubernetes/k8sapi/resources/access_manager_test.go b/bootstrapper/internal/kubernetes/k8sapi/resources/access_manager_test.go deleted file mode 100644 index 9f02d6ab7..000000000 --- a/bootstrapper/internal/kubernetes/k8sapi/resources/access_manager_test.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package resources - -import ( - "testing" - - "github.com/edgelesssys/constellation/v2/internal/kubernetes" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.uber.org/goleak" -) - -func TestMain(m *testing.M) { - goleak.VerifyTestMain(m) -} - -func TestAccessManagerMarshalUnmarshal(t *testing.T) { - require := require.New(t) - assert := assert.New(t) - - // Without data - accessManagerDeplNil := NewAccessManagerDeployment(nil) - data, err := accessManagerDeplNil.Marshal() - require.NoError(err) - - var recreated AccessManagerDeployment - require.NoError(kubernetes.UnmarshalK8SResources(data, &recreated)) - assert.Equal(accessManagerDeplNil, &recreated) - - // With data - sshUsers := make(map[string]string) - sshUsers["test-user"] = "ssh-rsa abcdefg" - accessManagerDeplNil = NewAccessManagerDeployment(sshUsers) - data, err = accessManagerDeplNil.Marshal() - require.NoError(err) - - require.NoError(kubernetes.UnmarshalK8SResources(data, &recreated)) - assert.Equal(accessManagerDeplNil, &recreated) -} diff --git a/bootstrapper/internal/kubernetes/k8sapi/resources/gcp_guest_agent.go b/bootstrapper/internal/kubernetes/k8sapi/resources/gcp_guest_agent.go index bc43a1129..362171b91 100644 --- a/bootstrapper/internal/kubernetes/k8sapi/resources/gcp_guest_agent.go +++ b/bootstrapper/internal/kubernetes/k8sapi/resources/gcp_guest_agent.go @@ -178,7 +178,7 @@ func NewGCPGuestAgentDaemonset() *GCPGuestAgentDaemonset { } } -// Marshal marshals the access-manager deployment as YAML documents. +// Marshal marshals the gcp guest agent deployment as YAML documents. func (c *GCPGuestAgentDaemonset) Marshal() ([]byte, error) { return kubernetes.MarshalK8SResources(c) } diff --git a/bootstrapper/internal/kubernetes/k8sutil.go b/bootstrapper/internal/kubernetes/k8sutil.go index f09974f40..196da8896 100644 --- a/bootstrapper/internal/kubernetes/k8sutil.go +++ b/bootstrapper/internal/kubernetes/k8sutil.go @@ -22,7 +22,6 @@ type clusterUtil interface { InstallComponents(ctx context.Context, version versions.ValidK8sVersion) error InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger) error JoinCluster(ctx context.Context, joinConfig []byte, peerRole role.Role, controlPlaneEndpoint string, log *logger.Logger) error - SetupAccessManager(kubectl k8sapi.Client, sshUsers kubernetes.Marshaler) error SetupKonnectivity(kubectl k8sapi.Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error SetupVerificationService(kubectl k8sapi.Client, verificationServiceConfiguration kubernetes.Marshaler) error SetupGCPGuestAgent(kubectl k8sapi.Client, gcpGuestAgentConfiguration kubernetes.Marshaler) error diff --git a/bootstrapper/internal/kubernetes/kubernetes.go b/bootstrapper/internal/kubernetes/kubernetes.go index b65185e1f..a97ac9cf6 100644 --- a/bootstrapper/internal/kubernetes/kubernetes.go +++ b/bootstrapper/internal/kubernetes/kubernetes.go @@ -86,7 +86,7 @@ func New(cloudProvider string, clusterUtil clusterUtil, configProvider configura // InitCluster initializes a new Kubernetes cluster and applies pod network provider. func (k *KubeWrapper) InitCluster( ctx context.Context, cloudServiceAccountURI, versionString string, measurementSalt []byte, enforcedPCRs []uint32, - enforceIDKeyDigest bool, idKeyDigest []byte, azureCVM bool, sshUsers map[string]string, + enforceIDKeyDigest bool, idKeyDigest []byte, azureCVM bool, helmReleasesRaw []byte, conformanceMode bool, log *logger.Logger, ) ([]byte, error) { k8sVersion, err := versions.NewValidK8sVersion(versionString) @@ -205,12 +205,6 @@ func (k *KubeWrapper) InitCluster( return nil, fmt.Errorf("failed to setup internal ConfigMap: %w", err) } - // TODO: remove access manager or re-enable with support for readonly /etc - // accessManager := resources.NewAccessManagerDeployment(sshUsers) - // if err := k.clusterUtil.SetupAccessManager(k.client, accessManager); err != nil { - // return nil, fmt.Errorf("failed to setup access-manager: %w", err) - // } - if err := k.clusterUtil.SetupVerificationService( k.client, resources.NewVerificationDaemonSet(k.cloudProvider, controlPlaneEndpoint), ); err != nil { diff --git a/bootstrapper/internal/kubernetes/kubernetes_test.go b/bootstrapper/internal/kubernetes/kubernetes_test.go index 7a70eb591..b26a8b8b3 100644 --- a/bootstrapper/internal/kubernetes/kubernetes_test.go +++ b/bootstrapper/internal/kubernetes/kubernetes_test.go @@ -236,7 +236,7 @@ func TestInitCluster(t *testing.T) { _, err := kube.InitCluster( context.Background(), serviceAccountURI, string(tc.k8sVersion), - nil, nil, false, nil, true, nil, []byte("{}"), false, logger.NewTest(t), + nil, nil, false, nil, true, []byte("{}"), false, logger.NewTest(t), ) if tc.wantErr { @@ -419,7 +419,6 @@ type stubClusterUtil struct { initClusterErr error setupAutoscalingError error setupKonnectivityError error - setupAccessManagerError error setupVerificationServiceErr error setupGCPGuestAgentErr error setupOLMErr error @@ -453,10 +452,6 @@ func (s *stubClusterUtil) SetupGCPGuestAgent(kubectl k8sapi.Client, gcpGuestAgen return s.setupGCPGuestAgentErr } -func (s *stubClusterUtil) SetupAccessManager(kubectl k8sapi.Client, accessManagerConfiguration kubernetes.Marshaler) error { - return s.setupAccessManagerError -} - func (s *stubClusterUtil) SetupVerificationService(kubectl k8sapi.Client, verificationServiceConfiguration kubernetes.Marshaler) error { return s.setupVerificationServiceErr } diff --git a/cli/internal/cmd/init.go b/cli/internal/cmd/init.go index c030b01cd..d1d76f4d4 100644 --- a/cli/internal/cmd/init.go +++ b/cli/internal/cmd/init.go @@ -26,7 +26,6 @@ import ( "github.com/edgelesssys/constellation/v2/internal/config" "github.com/edgelesssys/constellation/v2/internal/constants" "github.com/edgelesssys/constellation/v2/internal/crypto" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/file" "github.com/edgelesssys/constellation/v2/internal/grpc/dialer" grpcRetry "github.com/edgelesssys/constellation/v2/internal/grpc/retry" @@ -103,14 +102,6 @@ func initialize(cmd *cobra.Command, newDialer func(validator *cloudcmd.Validator cmd.PrintErrf("License check failed: %v", err) } - var sshUsers []*ssh.UserKey - for _, user := range config.SSHUsers { - sshUsers = append(sshUsers, &ssh.UserKey{ - Username: user.Username, - PublicKey: user.PublicKey, - }) - } - validator, err := cloudcmd.NewValidator(provider, config) if err != nil { return err @@ -141,7 +132,6 @@ func initialize(cmd *cobra.Command, newDialer func(validator *cloudcmd.Validator UseExistingKek: false, CloudServiceAccountUri: serviceAccURI, KubernetesVersion: config.KubernetesVersion, - SshUserKeys: ssh.ToProtoSlice(sshUsers), HelmDeployments: helmDeployments, EnforcedPcrs: getEnforcedPCRs(provider, config), EnforceIdkeydigest: getEnforceIDKeyDigest(provider, config), diff --git a/cli/internal/helm/charts/cilium/README.md b/cli/internal/helm/charts/cilium/README.md index dfb644645..153bff0ec 100644 --- a/cli/internal/helm/charts/cilium/README.md +++ b/cli/internal/helm/charts/cilium/README.md @@ -37,7 +37,7 @@ $ helm install cilium cilium/cilium --namespace=kube-system ``` After Cilium is installed, you can explore the features that Cilium has to -offer from the [Getting Started Guides page](https://docs.cilium.io/en/latest/gettingstarted/k8s-install-default/#next-steps). +offer from the [Getting Started Guides page](https://docs.cilium.io/en/stable/gettingstarted/). ## Source Code diff --git a/cli/internal/helm/charts/cilium/README.md.gotmpl b/cli/internal/helm/charts/cilium/README.md.gotmpl index 1e777a251..225a0f819 100644 --- a/cli/internal/helm/charts/cilium/README.md.gotmpl +++ b/cli/internal/helm/charts/cilium/README.md.gotmpl @@ -39,7 +39,7 @@ $ helm install cilium cilium/cilium --namespace=kube-system ``` After Cilium is installed, you can explore the features that Cilium has to -offer from the [Getting Started Guides page](https://docs.cilium.io/en/latest/gettingstarted/). +offer from the [Getting Started Guides page](https://docs.cilium.io/en/stable/gettingstarted/). {{ template "chart.maintainersSection" . }} diff --git a/debugd/cmd/debugd/debugd.go b/debugd/cmd/debugd/debugd.go index 263450a9e..8f7e5045b 100644 --- a/debugd/cmd/debugd/debugd.go +++ b/debugd/cmd/debugd/debugd.go @@ -25,8 +25,6 @@ import ( platform "github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider" gcpcloud "github.com/edgelesssys/constellation/v2/internal/cloud/gcp" qemucloud "github.com/edgelesssys/constellation/v2/internal/cloud/qemu" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" - "github.com/edgelesssys/constellation/v2/internal/deploy/user" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/spf13/afero" "go.uber.org/zap" @@ -47,7 +45,6 @@ func main() { fs := afero.NewOsFs() streamer := bootstrapper.NewFileStreamer(fs) serviceManager := deploy.NewServiceManager(log.Named("serviceManager")) - ssh := ssh.NewAccess(log, user.NewLinuxUserManager(fs)) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -89,9 +86,8 @@ func main() { log.Errorf("Unknown / unimplemented cloud provider CONSTEL_CSP=%v. Using fallback", csp) fetcher = fallback.Fetcher{} } - - sched := metadata.NewScheduler(log.Named("scheduler"), fetcher, ssh, download) - serv := server.New(log.Named("server"), ssh, serviceManager, streamer) + sched := metadata.NewScheduler(log.Named("scheduler"), fetcher, download) + serv := server.New(log.Named("server"), serviceManager, streamer) if err := deploy.DefaultServiceUnit(ctx, serviceManager); err != nil { log.With(zap.Error(err)).Fatalf("Failed to create default service unit") } diff --git a/debugd/internal/cdbg/cmd/deploy.go b/debugd/internal/cdbg/cmd/deploy.go index 9b15770e1..182b0a3f1 100644 --- a/debugd/internal/cdbg/cmd/deploy.go +++ b/debugd/internal/cdbg/cmd/deploy.go @@ -28,8 +28,8 @@ import ( func newDeployCmd() *cobra.Command { deployCmd := &cobra.Command{ Use: "deploy", - Short: "Deploys a self-compiled bootstrapper binary and SSH keys on the current constellation", - Long: `Deploys a self-compiled bootstrapper binary and SSH keys on the current constellation. + Short: "Deploys a self-compiled bootstrapper binary on the current constellation", + Long: `Deploys a self-compiled bootstrapper binary on the current constellation. Uses config provided by --config and reads constellation config from its default location. If required, you can override the IP addresses that are used for a deployment by specifying "--ips" and a list of IP addresses. Specifying --bootstrapper will upload the bootstrapper from the specified path.`, @@ -88,7 +88,6 @@ func deploy(cmd *cobra.Command, fileHandler file.Handler, constellationConfig *c debugdEndpoint: net.JoinHostPort(ip, strconv.Itoa(constants.DebugdPort)), bootstrapperPath: bootstrapperPath, reader: reader, - authorizedKeys: constellationConfig.SSHUsers, } if err := deployOnEndpoint(cmd.Context(), input); err != nil { return err @@ -102,10 +101,9 @@ type deployOnEndpointInput struct { debugdEndpoint string bootstrapperPath string reader fileToStreamReader - authorizedKeys []config.UserKey } -// deployOnEndpoint deploys SSH public keys and a locally built bootstrapper binary to a debugd endpoint. +// deployOnEndpoint deploys a custom built bootstrapper binary to a debugd endpoint. func deployOnEndpoint(ctx context.Context, in deployOnEndpointInput) error { log.Printf("Deploying on %v\n", in.debugdEndpoint) dialCTX, cancel := context.WithTimeout(ctx, debugd.GRPCTimeout) @@ -117,23 +115,6 @@ func deployOnEndpoint(ctx context.Context, in deployOnEndpointInput) error { defer conn.Close() client := pb.NewDebugdClient(conn) - 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, 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/constants.go b/debugd/internal/debugd/constants.go index d475ee862..951d4a61d 100644 --- a/debugd/internal/debugd/constants.go +++ b/debugd/internal/debugd/constants.go @@ -12,7 +12,6 @@ import "time" const ( DebugdMetadataFlag = "constellation-debugd" GRPCTimeout = 5 * time.Minute - SSHCheckInterval = 30 * time.Second DiscoverDebugdInterval = 30 * time.Second BootstrapperDownloadRetryBackoff = 1 * time.Minute BootstrapperDeployFilename = "/run/state/bin/bootstrapper" diff --git a/debugd/internal/debugd/deploy/download.go b/debugd/internal/debugd/deploy/download.go index aede9a1c9..1d749ba22 100644 --- a/debugd/internal/debugd/deploy/download.go +++ b/debugd/internal/debugd/deploy/download.go @@ -17,7 +17,6 @@ import ( "github.com/edgelesssys/constellation/v2/debugd/internal/debugd" pb "github.com/edgelesssys/constellation/v2/debugd/service" "github.com/edgelesssys/constellation/v2/internal/constants" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/logger" "go.uber.org/zap" "google.golang.org/grpc" @@ -45,20 +44,20 @@ func New(log *logger.Logger, dialer NetDialer, serviceManager serviceManager, wr } // DownloadDeployment will open a new grpc connection to another instance, attempting to download a bootstrapper from that instance. -func (d *Download) DownloadDeployment(ctx context.Context, ip string) ([]ssh.UserKey, error) { +func (d *Download) DownloadDeployment(ctx context.Context, ip string) error { log := d.log.With(zap.String("ip", ip)) serverAddr := net.JoinHostPort(ip, strconv.Itoa(constants.DebugdPort)) // only retry download from same endpoint after backoff if lastAttempt, ok := d.attemptedDownloads[serverAddr]; ok && time.Since(lastAttempt) < debugd.BootstrapperDownloadRetryBackoff { - return nil, fmt.Errorf("download failed too recently: %v / %v", time.Since(lastAttempt), debugd.BootstrapperDownloadRetryBackoff) + return fmt.Errorf("download failed too recently: %v / %v", time.Since(lastAttempt), debugd.BootstrapperDownloadRetryBackoff) } log.Infof("Connecting to server") d.attemptedDownloads[serverAddr] = time.Now() conn, err := d.dial(ctx, serverAddr) if err != nil { - return nil, fmt.Errorf("connecting to other instance via gRPC: %w", err) + return fmt.Errorf("connecting to other instance via gRPC: %w", err) } defer conn.Close() client := pb.NewDebugdClient(conn) @@ -66,34 +65,23 @@ func (d *Download) DownloadDeployment(ctx context.Context, ip string) ([]ssh.Use log.Infof("Trying to download bootstrapper") stream, err := client.DownloadBootstrapper(ctx, &pb.DownloadBootstrapperRequest{}) if err != nil { - return nil, fmt.Errorf("starting bootstrapper download from other instance: %w", err) + return fmt.Errorf("starting bootstrapper download from other instance: %w", err) } if err := d.writer.WriteStream(debugd.BootstrapperDeployFilename, stream, true); err != nil { - return nil, fmt.Errorf("streaming bootstrapper from other instance: %w", err) + return fmt.Errorf("streaming bootstrapper from other instance: %w", err) } log.Infof("Successfully downloaded bootstrapper") - log.Infof("Trying to download ssh keys") - resp, err := client.DownloadAuthorizedKeys(ctx, &pb.DownloadAuthorizedKeysRequest{}) - if err != nil { - return nil, fmt.Errorf("downloading authorized keys: %w", err) - } - - var keys []ssh.UserKey - for _, key := range resp.Keys { - keys = append(keys, ssh.UserKey{Username: key.Username, PublicKey: key.KeyValue}) - } - // after the upload succeeds, try to restart the bootstrapper restartAction := ServiceManagerRequest{ Unit: debugd.BootstrapperSystemdUnitName, Action: Restart, } if err := d.serviceManager.SystemdAction(ctx, restartAction); err != nil { - return nil, fmt.Errorf("restarting bootstrapper: %w", err) + return fmt.Errorf("restarting bootstrapper: %w", err) } - return keys, nil + return nil } func (d *Download) dial(ctx context.Context, target string) (*grpc.ClientConn, error) { diff --git a/debugd/internal/debugd/deploy/download_test.go b/debugd/internal/debugd/deploy/download_test.go index 86ff84ca2..5cc5e6c27 100644 --- a/debugd/internal/debugd/deploy/download_test.go +++ b/debugd/internal/debugd/deploy/download_test.go @@ -20,7 +20,6 @@ import ( "github.com/edgelesssys/constellation/v2/debugd/internal/debugd" pb "github.com/edgelesssys/constellation/v2/debugd/service" "github.com/edgelesssys/constellation/v2/internal/constants" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/grpc/testdialer" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/stretchr/testify/assert" @@ -48,12 +47,10 @@ func TestDownloadBootstrapper(t *testing.T) { wantFile bool wantSystemdAction bool wantDeployed bool - wantKeys []ssh.UserKey }{ "download works": { server: fakeDownloadServer{ chunks: [][]byte{[]byte("test")}, - keys: []*pb.AuthorizedKey{{Username: "name", KeyValue: "key"}}, }, attemptedDownloads: map[string]time.Time{}, wantChunks: [][]byte{[]byte("test")}, @@ -61,7 +58,6 @@ func TestDownloadBootstrapper(t *testing.T) { wantFile: true, wantSystemdAction: true, wantDeployed: true, - wantKeys: []ssh.UserKey{{Username: "name", PublicKey: "key"}}, }, "second download is not attempted twice": { server: fakeDownloadServer{chunks: [][]byte{[]byte("test")}}, @@ -73,14 +69,6 @@ func TestDownloadBootstrapper(t *testing.T) { attemptedDownloads: map[string]time.Time{}, wantDownloadErr: true, }, - "download key error": { - server: fakeDownloadServer{ - chunks: [][]byte{[]byte("test")}, - downloadAuthorizedKeysErr: someErr, - }, - attemptedDownloads: map[string]time.Time{}, - wantDownloadErr: true, - }, "service restart error is detected": { server: fakeDownloadServer{chunks: [][]byte{[]byte("test")}}, serviceManager: stubServiceManager{systemdActionErr: someErr}, @@ -115,7 +103,7 @@ func TestDownloadBootstrapper(t *testing.T) { attemptedDownloads: tc.attemptedDownloads, } - keys, err := download.DownloadDeployment(context.Background(), ip) + err := download.DownloadDeployment(context.Background(), ip) if tc.wantDownloadErr { assert.Error(err) @@ -135,7 +123,6 @@ func TestDownloadBootstrapper(t *testing.T) { tc.serviceManager.requests, ) } - assert.Equal(tc.wantKeys, keys) }) } } @@ -171,10 +158,8 @@ func (f *fakeStreamToFileWriter) WriteStream(filename string, stream bootstrappe // fakeDownloadServer implements DebugdServer; only fakes DownloadBootstrapper, panics on every other rpc. type fakeDownloadServer struct { - chunks [][]byte - downladErr error - keys []*pb.AuthorizedKey - downloadAuthorizedKeysErr error + chunks [][]byte + downladErr error pb.UnimplementedDebugdServer } @@ -187,7 +172,3 @@ func (s *fakeDownloadServer) DownloadBootstrapper(request *pb.DownloadBootstrapp } return s.downladErr } - -func (s *fakeDownloadServer) DownloadAuthorizedKeys(context.Context, *pb.DownloadAuthorizedKeysRequest) (*pb.DownloadAuthorizedKeysResponse, error) { - return &pb.DownloadAuthorizedKeysResponse{Keys: s.keys}, s.downloadAuthorizedKeysErr -} diff --git a/debugd/internal/debugd/metadata/cloudprovider/cloudprovider.go b/debugd/internal/debugd/metadata/cloudprovider/cloudprovider.go index c791dbead..edf5b20e8 100644 --- a/debugd/internal/debugd/metadata/cloudprovider/cloudprovider.go +++ b/debugd/internal/debugd/metadata/cloudprovider/cloudprovider.go @@ -12,7 +12,6 @@ import ( "net" "github.com/edgelesssys/constellation/v2/internal/cloud/metadata" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/role" ) @@ -25,7 +24,7 @@ type providerMetadata interface { GetLoadBalancerEndpoint(ctx context.Context) (string, error) } -// Fetcher checks the metadata service to search for instances that were set up for debugging and cloud provider specific SSH keys. +// Fetcher checks the metadata service to search for instances that were set up for debugging. type Fetcher struct { metaAPI providerMetadata } @@ -92,20 +91,3 @@ func (f *Fetcher) DiscoverLoadbalancerIP(ctx context.Context) (string, error) { return lbIP, nil } - -// FetchSSHKeys will query the metadata of the current instance and deploys any SSH keys found. -func (f *Fetcher) FetchSSHKeys(ctx context.Context) ([]ssh.UserKey, error) { - self, err := f.metaAPI.Self(ctx) - if err != nil { - return nil, fmt.Errorf("retrieving ssh keys from cloud provider metadata: %w", err) - } - - keys := []ssh.UserKey{} - for username, userKeys := range self.SSHKeys { - for _, keyValue := range userKeys { - keys = append(keys, ssh.UserKey{Username: username, PublicKey: keyValue}) - } - } - - return keys, nil -} diff --git a/debugd/internal/debugd/metadata/cloudprovider/cloudprovider_test.go b/debugd/internal/debugd/metadata/cloudprovider/cloudprovider_test.go index b337b3052..26b83293e 100644 --- a/debugd/internal/debugd/metadata/cloudprovider/cloudprovider_test.go +++ b/debugd/internal/debugd/metadata/cloudprovider/cloudprovider_test.go @@ -12,7 +12,6 @@ import ( "testing" "github.com/edgelesssys/constellation/v2/internal/cloud/metadata" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/role" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -166,57 +165,6 @@ func TestDiscoverLoadbalancerIP(t *testing.T) { } } -func TestFetchSSHKeys(t *testing.T) { - err := errors.New("some err") - - testCases := map[string]struct { - meta stubMetadata - wantKeys []ssh.UserKey - wantErr bool - }{ - "fetch works": { - meta: stubMetadata{ - selfRes: metadata.InstanceMetadata{ - Name: "name", - ProviderID: "provider-id", - SSHKeys: map[string][]string{"bob": {"ssh-rsa bobskey"}}, - }, - }, - wantKeys: []ssh.UserKey{ - { - Username: "bob", - PublicKey: "ssh-rsa bobskey", - }, - }, - }, - "retrieve fails": { - meta: stubMetadata{ - selfErr: err, - }, - wantErr: true, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - - fetcher := Fetcher{ - metaAPI: &tc.meta, - } - keys, err := fetcher.FetchSSHKeys(context.Background()) - - if tc.wantErr { - assert.Error(err) - return - } - require.NoError(err) - assert.ElementsMatch(tc.wantKeys, keys) - }) - } -} - type stubMetadata struct { listRes []metadata.InstanceMetadata listErr error diff --git a/debugd/internal/debugd/metadata/fallback/fallback.go b/debugd/internal/debugd/metadata/fallback/fallback.go index c37db6b20..4521ec6c0 100644 --- a/debugd/internal/debugd/metadata/fallback/fallback.go +++ b/debugd/internal/debugd/metadata/fallback/fallback.go @@ -9,7 +9,6 @@ package fallback import ( "context" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/role" ) @@ -30,8 +29,3 @@ func (f Fetcher) DiscoverDebugdIPs(ctx context.Context) ([]string, error) { func (f Fetcher) DiscoverLoadbalancerIP(ctx context.Context) (string, error) { return "", nil } - -// FetchSSHKeys for fallback fetcher does not try to fetch ssh keys. -func (f Fetcher) FetchSSHKeys(ctx context.Context) ([]ssh.UserKey, error) { - return nil, nil -} diff --git a/debugd/internal/debugd/metadata/fallback/fallback_test.go b/debugd/internal/debugd/metadata/fallback/fallback_test.go index a5e904ef4..315fd0a1e 100644 --- a/debugd/internal/debugd/metadata/fallback/fallback_test.go +++ b/debugd/internal/debugd/metadata/fallback/fallback_test.go @@ -27,13 +27,3 @@ func TestDiscoverDebugdIPs(t *testing.T) { assert.NoError(err) assert.Empty(ips) } - -func TestFetchSSHKeys(t *testing.T) { - assert := assert.New(t) - - fetcher := Fetcher{} - keys, err := fetcher.FetchSSHKeys(context.Background()) - - assert.NoError(err) - assert.Empty(keys) -} diff --git a/debugd/internal/debugd/metadata/scheduler.go b/debugd/internal/debugd/metadata/scheduler.go index bb4a63284..028756e2b 100644 --- a/debugd/internal/debugd/metadata/scheduler.go +++ b/debugd/internal/debugd/metadata/scheduler.go @@ -14,17 +14,15 @@ import ( "time" "github.com/edgelesssys/constellation/v2/debugd/internal/debugd" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/role" "go.uber.org/zap" ) -// Fetcher retrieves other debugd IPs and SSH keys from cloud provider metadata. +// Fetcher retrieves other debugd IPs from cloud provider metadata. type Fetcher interface { Role(ctx context.Context) (role.Role, error) DiscoverDebugdIPs(ctx context.Context) ([]string, error) - FetchSSHKeys(ctx context.Context) ([]ssh.UserKey, error) DiscoverLoadbalancerIP(ctx context.Context) (string, error) } @@ -32,29 +30,24 @@ type Fetcher interface { type Scheduler struct { log *logger.Logger fetcher Fetcher - ssh sshDeployer downloader downloader } // NewScheduler returns a new scheduler. -func NewScheduler(log *logger.Logger, fetcher Fetcher, ssh sshDeployer, downloader downloader) *Scheduler { +func NewScheduler(log *logger.Logger, fetcher Fetcher, downloader downloader) *Scheduler { return &Scheduler{ log: log, fetcher: fetcher, - ssh: ssh, downloader: downloader, } } -// Start will start the loops for discovering debugd endpoints and ssh keys. +// Start the loops for discovering debugd endpoints. func (s *Scheduler) Start(ctx context.Context, wg *sync.WaitGroup) { defer wg.Done() wg.Add(1) go s.discoveryLoop(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. @@ -91,36 +84,11 @@ func (s *Scheduler) discoveryLoop(ctx context.Context, wg *sync.WaitGroup) { } } -// sshLoop discovers new ssh keys from cloud provider metadata periodically. -// 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) -// } - -// 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 { - _, err := s.downloader.DownloadDeployment(ctx, ip) + err := s.downloader.DownloadDeployment(ctx, ip) if err == nil { - // 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) { @@ -133,22 +101,6 @@ 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 -// } -// } -// } - type downloader interface { - DownloadDeployment(ctx context.Context, ip string) ([]ssh.UserKey, error) -} - -type sshDeployer interface { - DeployAuthorizedKey(ctx context.Context, sshKey ssh.UserKey) error + DownloadDeployment(ctx context.Context, ip string) error } diff --git a/debugd/internal/debugd/metadata/scheduler_test.go b/debugd/internal/debugd/metadata/scheduler_test.go index e927f3666..6b2e29823 100644 --- a/debugd/internal/debugd/metadata/scheduler_test.go +++ b/debugd/internal/debugd/metadata/scheduler_test.go @@ -13,7 +13,6 @@ import ( "testing" "time" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/role" "github.com/stretchr/testify/assert" @@ -29,20 +28,11 @@ func TestSchedulerStart(t *testing.T) { testCases := map[string]struct { fetcher stubFetcher - ssh stubSSHDeployer downloader stubDownloader timeout time.Duration - wantSSHKeys []ssh.UserKey wantDebugdDownloads []string }{ "scheduler works and calls fetcher functions at least once": {}, - // 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"}, @@ -59,10 +49,6 @@ func TestSchedulerStart(t *testing.T) { "endpoint discovery can fail": { fetcher: stubFetcher{discoverErr: 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 { @@ -75,31 +61,23 @@ func TestSchedulerStart(t *testing.T) { scheduler := Scheduler{ log: logger.NewTest(t), fetcher: &tc.fetcher, - ssh: &tc.ssh, downloader: &tc.downloader, } wg.Add(1) go scheduler.Start(ctx, wg) wg.Wait() - // 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) - // TODO (stateless-ssh): re-enable once ssh keys can be deployed on readonly rootfs. - // assert.Greater(tc.fetcher.fetchSSHKeysCalls, 0) }) } } type stubFetcher struct { - discoverCalls int - fetchSSHKeysCalls int + discoverCalls int - ips []string - keys []ssh.UserKey - discoverErr error - fetchSSHKeysErr error + ips []string + discoverErr error } func (s *stubFetcher) Role(_ context.Context) (role.Role, error) { @@ -111,34 +89,16 @@ func (s *stubFetcher) DiscoverDebugdIPs(ctx context.Context) ([]string, error) { return s.ips, s.discoverErr } -func (s *stubFetcher) FetchSSHKeys(ctx context.Context) ([]ssh.UserKey, error) { - s.fetchSSHKeysCalls++ - return s.keys, s.fetchSSHKeysErr -} - func (s *stubFetcher) DiscoverLoadbalancerIP(ctx context.Context) (string, error) { return "", nil } -type stubSSHDeployer struct { - sshKeys []ssh.UserKey - - deployErr error -} - -func (s *stubSSHDeployer) DeployAuthorizedKey(ctx context.Context, sshKey ssh.UserKey) error { - s.sshKeys = append(s.sshKeys, sshKey) - - return s.deployErr -} - type stubDownloader struct { ips []string downloadErr error - keys []ssh.UserKey } -func (s *stubDownloader) DownloadDeployment(ctx context.Context, ip string) ([]ssh.UserKey, error) { +func (s *stubDownloader) DownloadDeployment(ctx context.Context, ip string) error { s.ips = append(s.ips, ip) - return s.keys, s.downloadErr + return s.downloadErr } diff --git a/debugd/internal/debugd/server/server.go b/debugd/internal/debugd/server/server.go index afecf8a7c..e9f830fc8 100644 --- a/debugd/internal/debugd/server/server.go +++ b/debugd/internal/debugd/server/server.go @@ -21,7 +21,6 @@ import ( "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/deploy" pb "github.com/edgelesssys/constellation/v2/debugd/service" "github.com/edgelesssys/constellation/v2/internal/constants" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/logger" "go.uber.org/zap" "google.golang.org/grpc" @@ -30,48 +29,20 @@ import ( type debugdServer struct { log *logger.Logger - ssh sshDeployer serviceManager serviceManager streamer streamer pb.UnimplementedDebugdServer } // New creates a new debugdServer according to the gRPC spec. -func New(log *logger.Logger, ssh sshDeployer, serviceManager serviceManager, streamer streamer) pb.DebugdServer { +func New(log *logger.Logger, serviceManager serviceManager, streamer streamer) pb.DebugdServer { return &debugdServer{ log: log, - ssh: ssh, serviceManager: serviceManager, streamer: streamer, } } -// 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 (Disabled feature)") - return &pb.UploadAuthorizedKeysResponse{ - Status: pb.UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_SUCCESS, - }, nil -} - // UploadBootstrapper receives a bootstrapper binary in a stream of chunks and writes to a file. func (s *debugdServer) UploadBootstrapper(stream pb.Debugd_UploadBootstrapperServer) error { startAction := deploy.ServiceManagerRequest{ @@ -114,21 +85,6 @@ func (s *debugdServer) DownloadBootstrapper(request *pb.DownloadBootstrapperRequ return s.streamer.ReadStream(debugd.BootstrapperDeployFilename, stream, debugd.Chunksize, true) } -// DownloadAuthorizedKeys streams the local authorized keys to other instances. -func (s *debugdServer) DownloadAuthorizedKeys(_ context.Context, req *pb.DownloadAuthorizedKeysRequest) (*pb.DownloadAuthorizedKeysResponse, error) { - s.log.Infof("Sending authorized keys to other instance") - - var authKeys []*pb.AuthorizedKey - for _, key := range s.ssh.GetAuthorizedKeys() { - authKeys = append(authKeys, &pb.AuthorizedKey{ - Username: key.Username, - KeyValue: key.PublicKey, - }) - } - - return &pb.DownloadAuthorizedKeysResponse{Keys: authKeys}, nil -} - // UploadSystemServiceUnits receives systemd service units, writes them to a service file and schedules a daemon-reload. func (s *debugdServer) UploadSystemServiceUnits(ctx context.Context, in *pb.UploadSystemdServiceUnitsRequest) (*pb.UploadSystemdServiceUnitsResponse, error) { s.log.Infof("Uploading systemd service units") @@ -162,11 +118,6 @@ func Start(log *logger.Logger, wg *sync.WaitGroup, serv pb.DebugdServer) { grpcServer.Serve(lis) } -type sshDeployer interface { - DeployAuthorizedKey(ctx context.Context, sshKey ssh.UserKey) error - GetAuthorizedKeys() []ssh.UserKey -} - type serviceManager interface { SystemdAction(ctx context.Context, request deploy.ServiceManagerRequest) error WriteSystemdUnitFile(ctx context.Context, unit deploy.SystemdUnit) error diff --git a/debugd/internal/debugd/server/server_test.go b/debugd/internal/debugd/server/server_test.go index e6dd612c2..13ac96e11 100644 --- a/debugd/internal/debugd/server/server_test.go +++ b/debugd/internal/debugd/server/server_test.go @@ -19,7 +19,6 @@ import ( "github.com/edgelesssys/constellation/v2/debugd/internal/debugd/deploy" pb "github.com/edgelesssys/constellation/v2/debugd/service" "github.com/edgelesssys/constellation/v2/internal/constants" - "github.com/edgelesssys/constellation/v2/internal/deploy/ssh" "github.com/edgelesssys/constellation/v2/internal/grpc/testdialer" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/stretchr/testify/assert" @@ -33,90 +32,10 @@ func TestMain(m *testing.M) { goleak.VerifyTestMain(m) } -// 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", -// }, -// }, -// }, -// } - -// 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{}, -// } - -// 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() - -// 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) testCases := map[string]struct { - ssh stubSSHDeployer serviceManager stubServiceManager streamer fakeStreamer uploadChunks [][]byte @@ -164,7 +83,6 @@ func TestUploadBootstrapper(t *testing.T) { serv := debugdServer{ log: logger.NewTest(t), - ssh: &tc.ssh, serviceManager: &tc.serviceManager, streamer: &tc.streamer, } @@ -201,7 +119,6 @@ func TestDownloadBootstrapper(t *testing.T) { endpoint := "192.0.2.1:" + strconv.Itoa(constants.DebugdPort) testCases := map[string]struct { - ssh stubSSHDeployer serviceManager stubServiceManager request *pb.DownloadBootstrapperRequest streamer fakeStreamer @@ -236,7 +153,6 @@ func TestDownloadBootstrapper(t *testing.T) { serv := debugdServer{ log: logger.NewTest(t), - ssh: &tc.ssh, serviceManager: &tc.serviceManager, streamer: &tc.streamer, } @@ -261,44 +177,10 @@ func TestDownloadBootstrapper(t *testing.T) { } } -func TestDownloadAuthorizedKeys(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - - endpoint := "192.0.2.1:" + strconv.Itoa(constants.DebugdPort) - deployer := &stubSSHDeployer{ - sshKeys: []ssh.UserKey{ - {Username: "test1", PublicKey: "foo"}, - {Username: "test2", PublicKey: "bar"}, - }, - } - - serv := debugdServer{ - log: logger.NewTest(t), - ssh: deployer, - } - - grpcServ, conn, err := setupServerWithConn(endpoint, &serv) - require.NoError(err) - defer conn.Close() - defer grpcServ.GracefulStop() - client := pb.NewDebugdClient(conn) - - resp, err := client.DownloadAuthorizedKeys(context.Background(), &pb.DownloadAuthorizedKeysRequest{}) - - assert.NoError(err) - wantKeys := []*pb.AuthorizedKey{ - {Username: "test1", KeyValue: "foo"}, - {Username: "test2", KeyValue: "bar"}, - } - assert.ElementsMatch(wantKeys, resp.Keys) -} - func TestUploadSystemServiceUnits(t *testing.T) { endpoint := "192.0.2.1:" + strconv.Itoa(constants.DebugdPort) testCases := map[string]struct { - ssh stubSSHDeployer serviceManager stubServiceManager request *pb.UploadSystemdServiceUnitsRequest wantErr bool @@ -351,7 +233,6 @@ func TestUploadSystemServiceUnits(t *testing.T) { serv := debugdServer{ log: logger.NewTest(t), - ssh: &tc.ssh, serviceManager: &tc.serviceManager, streamer: &fakeStreamer{}, } @@ -375,22 +256,6 @@ func TestUploadSystemServiceUnits(t *testing.T) { } } -type stubSSHDeployer struct { - sshKeys []ssh.UserKey - - deployErr error -} - -func (s *stubSSHDeployer) DeployAuthorizedKey(ctx context.Context, sshKey ssh.UserKey) error { - s.sshKeys = append(s.sshKeys, sshKey) - - return s.deployErr -} - -func (s *stubSSHDeployer) GetAuthorizedKeys() []ssh.UserKey { - return s.sshKeys -} - type stubServiceManager struct { requests []deploy.ServiceManagerRequest unitFiles []deploy.SystemdUnit diff --git a/debugd/service/debugd.pb.go b/debugd/service/debugd.pb.go index f30e25557..0adb49d0d 100644 --- a/debugd/service/debugd.pb.go +++ b/debugd/service/debugd.pb.go @@ -20,52 +20,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type UploadAuthorizedKeysStatus int32 - -const ( - UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_SUCCESS UploadAuthorizedKeysStatus = 0 - UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_FAILURE UploadAuthorizedKeysStatus = 1 -) - -// Enum value maps for UploadAuthorizedKeysStatus. -var ( - UploadAuthorizedKeysStatus_name = map[int32]string{ - 0: "UPLOAD_AUTHORIZED_KEYS_SUCCESS", - 1: "UPLOAD_AUTHORIZED_KEYS_FAILURE", - } - UploadAuthorizedKeysStatus_value = map[string]int32{ - "UPLOAD_AUTHORIZED_KEYS_SUCCESS": 0, - "UPLOAD_AUTHORIZED_KEYS_FAILURE": 1, - } -) - -func (x UploadAuthorizedKeysStatus) Enum() *UploadAuthorizedKeysStatus { - p := new(UploadAuthorizedKeysStatus) - *p = x - return p -} - -func (x UploadAuthorizedKeysStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (UploadAuthorizedKeysStatus) Descriptor() protoreflect.EnumDescriptor { - return file_debugd_proto_enumTypes[0].Descriptor() -} - -func (UploadAuthorizedKeysStatus) Type() protoreflect.EnumType { - return &file_debugd_proto_enumTypes[0] -} - -func (x UploadAuthorizedKeysStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use UploadAuthorizedKeysStatus.Descriptor instead. -func (UploadAuthorizedKeysStatus) EnumDescriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{0} -} - type UploadBootstrapperStatus int32 const ( @@ -102,11 +56,11 @@ func (x UploadBootstrapperStatus) String() string { } func (UploadBootstrapperStatus) Descriptor() protoreflect.EnumDescriptor { - return file_debugd_proto_enumTypes[1].Descriptor() + return file_debugd_proto_enumTypes[0].Descriptor() } func (UploadBootstrapperStatus) Type() protoreflect.EnumType { - return &file_debugd_proto_enumTypes[1] + return &file_debugd_proto_enumTypes[0] } func (x UploadBootstrapperStatus) Number() protoreflect.EnumNumber { @@ -115,7 +69,7 @@ func (x UploadBootstrapperStatus) Number() protoreflect.EnumNumber { // Deprecated: Use UploadBootstrapperStatus.Descriptor instead. func (UploadBootstrapperStatus) EnumDescriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{1} + return file_debugd_proto_rawDescGZIP(), []int{0} } type UploadSystemdServiceUnitsStatus int32 @@ -148,11 +102,11 @@ func (x UploadSystemdServiceUnitsStatus) String() string { } func (UploadSystemdServiceUnitsStatus) Descriptor() protoreflect.EnumDescriptor { - return file_debugd_proto_enumTypes[2].Descriptor() + return file_debugd_proto_enumTypes[1].Descriptor() } func (UploadSystemdServiceUnitsStatus) Type() protoreflect.EnumType { - return &file_debugd_proto_enumTypes[2] + return &file_debugd_proto_enumTypes[1] } func (x UploadSystemdServiceUnitsStatus) Number() protoreflect.EnumNumber { @@ -161,7 +115,7 @@ func (x UploadSystemdServiceUnitsStatus) Number() protoreflect.EnumNumber { // Deprecated: Use UploadSystemdServiceUnitsStatus.Descriptor instead. func (UploadSystemdServiceUnitsStatus) EnumDescriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{2} + return file_debugd_proto_rawDescGZIP(), []int{1} } type DownloadBootstrapperRequest struct { @@ -202,240 +156,6 @@ func (*DownloadBootstrapperRequest) Descriptor() ([]byte, []int) { return file_debugd_proto_rawDescGZIP(), []int{0} } -type DownloadAuthorizedKeysRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *DownloadAuthorizedKeysRequest) Reset() { - *x = DownloadAuthorizedKeysRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DownloadAuthorizedKeysRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DownloadAuthorizedKeysRequest) ProtoMessage() {} - -func (x *DownloadAuthorizedKeysRequest) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DownloadAuthorizedKeysRequest.ProtoReflect.Descriptor instead. -func (*DownloadAuthorizedKeysRequest) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{1} -} - -type DownloadAuthorizedKeysResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Keys []*AuthorizedKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` -} - -func (x *DownloadAuthorizedKeysResponse) Reset() { - *x = DownloadAuthorizedKeysResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DownloadAuthorizedKeysResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DownloadAuthorizedKeysResponse) ProtoMessage() {} - -func (x *DownloadAuthorizedKeysResponse) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DownloadAuthorizedKeysResponse.ProtoReflect.Descriptor instead. -func (*DownloadAuthorizedKeysResponse) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{2} -} - -func (x *DownloadAuthorizedKeysResponse) GetKeys() []*AuthorizedKey { - if x != nil { - return x.Keys - } - return nil -} - -type AuthorizedKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` - KeyValue string `protobuf:"bytes,2,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` -} - -func (x *AuthorizedKey) Reset() { - *x = AuthorizedKey{} - if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AuthorizedKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AuthorizedKey) ProtoMessage() {} - -func (x *AuthorizedKey) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AuthorizedKey.ProtoReflect.Descriptor instead. -func (*AuthorizedKey) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{3} -} - -func (x *AuthorizedKey) GetUsername() string { - if x != nil { - return x.Username - } - return "" -} - -func (x *AuthorizedKey) GetKeyValue() string { - if x != nil { - return x.KeyValue - } - return "" -} - -type UploadAuthorizedKeysRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Keys []*AuthorizedKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` -} - -func (x *UploadAuthorizedKeysRequest) Reset() { - *x = UploadAuthorizedKeysRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UploadAuthorizedKeysRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UploadAuthorizedKeysRequest) ProtoMessage() {} - -func (x *UploadAuthorizedKeysRequest) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UploadAuthorizedKeysRequest.ProtoReflect.Descriptor instead. -func (*UploadAuthorizedKeysRequest) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{4} -} - -func (x *UploadAuthorizedKeysRequest) GetKeys() []*AuthorizedKey { - if x != nil { - return x.Keys - } - return nil -} - -type UploadAuthorizedKeysResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Status UploadAuthorizedKeysStatus `protobuf:"varint,1,opt,name=status,proto3,enum=debugd.UploadAuthorizedKeysStatus" json:"status,omitempty"` -} - -func (x *UploadAuthorizedKeysResponse) Reset() { - *x = UploadAuthorizedKeysResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UploadAuthorizedKeysResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UploadAuthorizedKeysResponse) ProtoMessage() {} - -func (x *UploadAuthorizedKeysResponse) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UploadAuthorizedKeysResponse.ProtoReflect.Descriptor instead. -func (*UploadAuthorizedKeysResponse) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{5} -} - -func (x *UploadAuthorizedKeysResponse) GetStatus() UploadAuthorizedKeysStatus { - if x != nil { - return x.Status - } - return UploadAuthorizedKeysStatus_UPLOAD_AUTHORIZED_KEYS_SUCCESS -} - type Chunk struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -447,7 +167,7 @@ type Chunk struct { func (x *Chunk) Reset() { *x = Chunk{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[6] + mi := &file_debugd_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -460,7 +180,7 @@ func (x *Chunk) String() string { func (*Chunk) ProtoMessage() {} func (x *Chunk) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[6] + mi := &file_debugd_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -473,7 +193,7 @@ func (x *Chunk) ProtoReflect() protoreflect.Message { // Deprecated: Use Chunk.ProtoReflect.Descriptor instead. func (*Chunk) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{6} + return file_debugd_proto_rawDescGZIP(), []int{1} } func (x *Chunk) GetContent() []byte { @@ -494,7 +214,7 @@ type UploadBootstrapperResponse struct { func (x *UploadBootstrapperResponse) Reset() { *x = UploadBootstrapperResponse{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[7] + mi := &file_debugd_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -507,7 +227,7 @@ func (x *UploadBootstrapperResponse) String() string { func (*UploadBootstrapperResponse) ProtoMessage() {} func (x *UploadBootstrapperResponse) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[7] + mi := &file_debugd_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -520,7 +240,7 @@ func (x *UploadBootstrapperResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadBootstrapperResponse.ProtoReflect.Descriptor instead. func (*UploadBootstrapperResponse) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{7} + return file_debugd_proto_rawDescGZIP(), []int{2} } func (x *UploadBootstrapperResponse) GetStatus() UploadBootstrapperStatus { @@ -542,7 +262,7 @@ type ServiceUnit struct { func (x *ServiceUnit) Reset() { *x = ServiceUnit{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[8] + mi := &file_debugd_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -555,7 +275,7 @@ func (x *ServiceUnit) String() string { func (*ServiceUnit) ProtoMessage() {} func (x *ServiceUnit) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[8] + mi := &file_debugd_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -568,7 +288,7 @@ func (x *ServiceUnit) ProtoReflect() protoreflect.Message { // Deprecated: Use ServiceUnit.ProtoReflect.Descriptor instead. func (*ServiceUnit) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{8} + return file_debugd_proto_rawDescGZIP(), []int{3} } func (x *ServiceUnit) GetName() string { @@ -596,7 +316,7 @@ type UploadSystemdServiceUnitsRequest struct { func (x *UploadSystemdServiceUnitsRequest) Reset() { *x = UploadSystemdServiceUnitsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[9] + mi := &file_debugd_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -609,7 +329,7 @@ func (x *UploadSystemdServiceUnitsRequest) String() string { func (*UploadSystemdServiceUnitsRequest) ProtoMessage() {} func (x *UploadSystemdServiceUnitsRequest) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[9] + mi := &file_debugd_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -622,7 +342,7 @@ func (x *UploadSystemdServiceUnitsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadSystemdServiceUnitsRequest.ProtoReflect.Descriptor instead. func (*UploadSystemdServiceUnitsRequest) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{9} + return file_debugd_proto_rawDescGZIP(), []int{4} } func (x *UploadSystemdServiceUnitsRequest) GetUnits() []*ServiceUnit { @@ -643,7 +363,7 @@ type UploadSystemdServiceUnitsResponse struct { func (x *UploadSystemdServiceUnitsResponse) Reset() { *x = UploadSystemdServiceUnitsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_debugd_proto_msgTypes[10] + mi := &file_debugd_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -656,7 +376,7 @@ func (x *UploadSystemdServiceUnitsResponse) String() string { func (*UploadSystemdServiceUnitsResponse) ProtoMessage() {} func (x *UploadSystemdServiceUnitsResponse) ProtoReflect() protoreflect.Message { - mi := &file_debugd_proto_msgTypes[10] + mi := &file_debugd_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -669,7 +389,7 @@ func (x *UploadSystemdServiceUnitsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use UploadSystemdServiceUnitsResponse.ProtoReflect.Descriptor instead. func (*UploadSystemdServiceUnitsResponse) Descriptor() ([]byte, []int) { - return file_debugd_proto_rawDescGZIP(), []int{10} + return file_debugd_proto_rawDescGZIP(), []int{5} } func (x *UploadSystemdServiceUnitsResponse) GetStatus() UploadSystemdServiceUnitsStatus { @@ -685,111 +405,70 @@ var file_debugd_proto_rawDesc = []byte{ 0x0a, 0x0c, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, - 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4b, 0x0a, 0x1e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, - 0x65, 0x79, 0x73, 0x22, 0x48, 0x0a, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, - 0x64, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x48, 0x0a, - 0x1b, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, - 0x64, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x04, - 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x64, 0x65, 0x62, - 0x75, 0x67, 0x64, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, - 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x5a, 0x0a, 0x1c, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, - 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, - 0x64, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x22, 0x21, 0x0a, 0x05, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x18, 0x0a, 0x07, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x56, 0x0a, 0x1a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3d, - 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x4d, 0x0a, - 0x20, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x29, 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x55, 0x6e, 0x69, 0x74, 0x52, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x22, 0x64, 0x0a, 0x21, - 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x27, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, - 0x6e, 0x69, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x2a, 0x64, 0x0a, 0x1a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x22, 0x0a, 0x1e, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x4f, - 0x52, 0x49, 0x5a, 0x45, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, - 0x53, 0x53, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x41, - 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x5f, 0x46, - 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x01, 0x2a, 0xad, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, - 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, - 0x43, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, - 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x55, 0x50, - 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x24, 0x0a, - 0x20, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, - 0x50, 0x50, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, - 0x44, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, - 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, - 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x03, 0x2a, 0x75, 0x0a, 0x1f, 0x55, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x55, 0x6e, 0x69, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x24, 0x55, - 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x44, 0x5f, 0x53, 0x45, - 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, - 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x28, 0x0a, 0x24, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, - 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, - 0x55, 0x4e, 0x49, 0x54, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x01, 0x32, - 0xe8, 0x03, 0x0a, 0x06, 0x44, 0x65, 0x62, 0x75, 0x67, 0x64, 0x12, 0x63, 0x0a, 0x14, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, - 0x79, 0x73, 0x12, 0x23, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, - 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, - 0x64, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x4b, 0x0a, 0x12, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x43, - 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x22, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x4e, 0x0a, 0x14, - 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x12, 0x23, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x44, 0x6f, - 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x64, 0x65, 0x62, 0x75, - 0x67, 0x64, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x22, 0x00, 0x30, 0x01, 0x12, 0x69, 0x0a, 0x16, - 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x25, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, - 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, - 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x18, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, - 0x69, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x21, 0x0a, 0x05, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x56, 0x0a, 0x1a, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x3d, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, + 0x4d, 0x0a, 0x20, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x52, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x22, 0x64, + 0x0a, 0x21, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, - 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, - 0x73, 0x73, 0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2f, 0x76, 0x32, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x2a, 0xad, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, + 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, + 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, + 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, + 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, + 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x55, 0x50, 0x4c, + 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, + 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, + 0x23, 0x0a, 0x1f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, + 0x52, 0x41, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x58, 0x49, 0x53, + 0x54, 0x53, 0x10, 0x03, 0x2a, 0x75, 0x0a, 0x1f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x24, 0x55, 0x50, 0x4c, 0x4f, 0x41, + 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, + 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, + 0x00, 0x12, 0x28, 0x0a, 0x24, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, + 0x45, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, + 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x01, 0x32, 0x98, 0x02, 0x0a, 0x06, + 0x44, 0x65, 0x62, 0x75, 0x67, 0x64, 0x12, 0x4b, 0x0a, 0x12, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x64, + 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x22, 0x2e, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, 0x74, 0x73, + 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x28, 0x01, 0x12, 0x4e, 0x0a, 0x14, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, + 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x23, 0x2e, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x64, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x6f, + 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x0d, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x22, + 0x00, 0x30, 0x01, 0x12, 0x71, 0x0a, 0x18, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x12, + 0x28, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x64, 0x65, 0x62, 0x75, + 0x67, 0x64, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x64, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, + 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x32, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -804,46 +483,33 @@ func file_debugd_proto_rawDescGZIP() []byte { return file_debugd_proto_rawDescData } -var file_debugd_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_debugd_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_debugd_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_debugd_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_debugd_proto_goTypes = []interface{}{ - (UploadAuthorizedKeysStatus)(0), // 0: debugd.UploadAuthorizedKeysStatus - (UploadBootstrapperStatus)(0), // 1: debugd.UploadBootstrapperStatus - (UploadSystemdServiceUnitsStatus)(0), // 2: debugd.UploadSystemdServiceUnitsStatus - (*DownloadBootstrapperRequest)(nil), // 3: debugd.DownloadBootstrapperRequest - (*DownloadAuthorizedKeysRequest)(nil), // 4: debugd.DownloadAuthorizedKeysRequest - (*DownloadAuthorizedKeysResponse)(nil), // 5: debugd.DownloadAuthorizedKeysResponse - (*AuthorizedKey)(nil), // 6: debugd.AuthorizedKey - (*UploadAuthorizedKeysRequest)(nil), // 7: debugd.UploadAuthorizedKeysRequest - (*UploadAuthorizedKeysResponse)(nil), // 8: debugd.UploadAuthorizedKeysResponse - (*Chunk)(nil), // 9: debugd.Chunk - (*UploadBootstrapperResponse)(nil), // 10: debugd.UploadBootstrapperResponse - (*ServiceUnit)(nil), // 11: debugd.ServiceUnit - (*UploadSystemdServiceUnitsRequest)(nil), // 12: debugd.UploadSystemdServiceUnitsRequest - (*UploadSystemdServiceUnitsResponse)(nil), // 13: debugd.UploadSystemdServiceUnitsResponse + (UploadBootstrapperStatus)(0), // 0: debugd.UploadBootstrapperStatus + (UploadSystemdServiceUnitsStatus)(0), // 1: debugd.UploadSystemdServiceUnitsStatus + (*DownloadBootstrapperRequest)(nil), // 2: debugd.DownloadBootstrapperRequest + (*Chunk)(nil), // 3: debugd.Chunk + (*UploadBootstrapperResponse)(nil), // 4: debugd.UploadBootstrapperResponse + (*ServiceUnit)(nil), // 5: debugd.ServiceUnit + (*UploadSystemdServiceUnitsRequest)(nil), // 6: debugd.UploadSystemdServiceUnitsRequest + (*UploadSystemdServiceUnitsResponse)(nil), // 7: debugd.UploadSystemdServiceUnitsResponse } var file_debugd_proto_depIdxs = []int32{ - 6, // 0: debugd.DownloadAuthorizedKeysResponse.keys:type_name -> debugd.AuthorizedKey - 6, // 1: debugd.UploadAuthorizedKeysRequest.keys:type_name -> debugd.AuthorizedKey - 0, // 2: debugd.UploadAuthorizedKeysResponse.status:type_name -> debugd.UploadAuthorizedKeysStatus - 1, // 3: debugd.UploadBootstrapperResponse.status:type_name -> debugd.UploadBootstrapperStatus - 11, // 4: debugd.UploadSystemdServiceUnitsRequest.units:type_name -> debugd.ServiceUnit - 2, // 5: debugd.UploadSystemdServiceUnitsResponse.status:type_name -> debugd.UploadSystemdServiceUnitsStatus - 7, // 6: debugd.Debugd.UploadAuthorizedKeys:input_type -> debugd.UploadAuthorizedKeysRequest - 9, // 7: debugd.Debugd.UploadBootstrapper:input_type -> debugd.Chunk - 3, // 8: debugd.Debugd.DownloadBootstrapper:input_type -> debugd.DownloadBootstrapperRequest - 4, // 9: debugd.Debugd.DownloadAuthorizedKeys:input_type -> debugd.DownloadAuthorizedKeysRequest - 12, // 10: debugd.Debugd.UploadSystemServiceUnits:input_type -> debugd.UploadSystemdServiceUnitsRequest - 8, // 11: debugd.Debugd.UploadAuthorizedKeys:output_type -> debugd.UploadAuthorizedKeysResponse - 10, // 12: debugd.Debugd.UploadBootstrapper:output_type -> debugd.UploadBootstrapperResponse - 9, // 13: debugd.Debugd.DownloadBootstrapper:output_type -> debugd.Chunk - 5, // 14: debugd.Debugd.DownloadAuthorizedKeys:output_type -> debugd.DownloadAuthorizedKeysResponse - 13, // 15: debugd.Debugd.UploadSystemServiceUnits:output_type -> debugd.UploadSystemdServiceUnitsResponse - 11, // [11:16] is the sub-list for method output_type - 6, // [6:11] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 0, // 0: debugd.UploadBootstrapperResponse.status:type_name -> debugd.UploadBootstrapperStatus + 5, // 1: debugd.UploadSystemdServiceUnitsRequest.units:type_name -> debugd.ServiceUnit + 1, // 2: debugd.UploadSystemdServiceUnitsResponse.status:type_name -> debugd.UploadSystemdServiceUnitsStatus + 3, // 3: debugd.Debugd.UploadBootstrapper:input_type -> debugd.Chunk + 2, // 4: debugd.Debugd.DownloadBootstrapper:input_type -> debugd.DownloadBootstrapperRequest + 6, // 5: debugd.Debugd.UploadSystemServiceUnits:input_type -> debugd.UploadSystemdServiceUnitsRequest + 4, // 6: debugd.Debugd.UploadBootstrapper:output_type -> debugd.UploadBootstrapperResponse + 3, // 7: debugd.Debugd.DownloadBootstrapper:output_type -> debugd.Chunk + 7, // 8: debugd.Debugd.UploadSystemServiceUnits:output_type -> debugd.UploadSystemdServiceUnitsResponse + 6, // [6:9] is the sub-list for method output_type + 3, // [3:6] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_debugd_proto_init() } @@ -865,66 +531,6 @@ func file_debugd_proto_init() { } } file_debugd_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DownloadAuthorizedKeysRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debugd_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DownloadAuthorizedKeysResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debugd_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthorizedKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debugd_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadAuthorizedKeysRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debugd_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadAuthorizedKeysResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debugd_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Chunk); i { case 0: return &v.state @@ -936,7 +542,7 @@ func file_debugd_proto_init() { return nil } } - file_debugd_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_debugd_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UploadBootstrapperResponse); i { case 0: return &v.state @@ -948,7 +554,7 @@ func file_debugd_proto_init() { return nil } } - file_debugd_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_debugd_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ServiceUnit); i { case 0: return &v.state @@ -960,7 +566,7 @@ func file_debugd_proto_init() { return nil } } - file_debugd_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_debugd_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UploadSystemdServiceUnitsRequest); i { case 0: return &v.state @@ -972,7 +578,7 @@ func file_debugd_proto_init() { return nil } } - file_debugd_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_debugd_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UploadSystemdServiceUnitsResponse); i { case 0: return &v.state @@ -990,8 +596,8 @@ func file_debugd_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_debugd_proto_rawDesc, - NumEnums: 3, - NumMessages: 11, + NumEnums: 2, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/debugd/service/debugd.proto b/debugd/service/debugd.proto index 435f122fe..7df02c628 100644 --- a/debugd/service/debugd.proto +++ b/debugd/service/debugd.proto @@ -5,39 +5,13 @@ option go_package = "github.com/edgelesssys/constellation/v2/debugd/service"; package debugd; service Debugd { - rpc UploadAuthorizedKeys(UploadAuthorizedKeysRequest) returns (UploadAuthorizedKeysResponse) {} rpc UploadBootstrapper(stream Chunk) returns (UploadBootstrapperResponse) {} rpc DownloadBootstrapper(DownloadBootstrapperRequest) returns (stream Chunk) {} - rpc DownloadAuthorizedKeys(DownloadAuthorizedKeysRequest) returns (DownloadAuthorizedKeysResponse) {} rpc UploadSystemServiceUnits(UploadSystemdServiceUnitsRequest) returns (UploadSystemdServiceUnitsResponse) {} } message DownloadBootstrapperRequest {} -message DownloadAuthorizedKeysRequest {} - -message DownloadAuthorizedKeysResponse { - repeated AuthorizedKey keys = 1; -} - -message AuthorizedKey { - string username = 1; - string key_value = 2; -} - -message UploadAuthorizedKeysRequest { - repeated AuthorizedKey keys = 1; -} - -message UploadAuthorizedKeysResponse { - UploadAuthorizedKeysStatus status = 1; -} - -enum UploadAuthorizedKeysStatus { - UPLOAD_AUTHORIZED_KEYS_SUCCESS = 0; - UPLOAD_AUTHORIZED_KEYS_FAILURE = 1; -} - message Chunk { bytes content = 1; } diff --git a/debugd/service/debugd_grpc.pb.go b/debugd/service/debugd_grpc.pb.go index 10c9cff37..935e35407 100644 --- a/debugd/service/debugd_grpc.pb.go +++ b/debugd/service/debugd_grpc.pb.go @@ -22,10 +22,8 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type DebugdClient interface { - UploadAuthorizedKeys(ctx context.Context, in *UploadAuthorizedKeysRequest, opts ...grpc.CallOption) (*UploadAuthorizedKeysResponse, error) UploadBootstrapper(ctx context.Context, opts ...grpc.CallOption) (Debugd_UploadBootstrapperClient, error) DownloadBootstrapper(ctx context.Context, in *DownloadBootstrapperRequest, opts ...grpc.CallOption) (Debugd_DownloadBootstrapperClient, error) - DownloadAuthorizedKeys(ctx context.Context, in *DownloadAuthorizedKeysRequest, opts ...grpc.CallOption) (*DownloadAuthorizedKeysResponse, error) UploadSystemServiceUnits(ctx context.Context, in *UploadSystemdServiceUnitsRequest, opts ...grpc.CallOption) (*UploadSystemdServiceUnitsResponse, error) } @@ -37,15 +35,6 @@ func NewDebugdClient(cc grpc.ClientConnInterface) DebugdClient { return &debugdClient{cc} } -func (c *debugdClient) UploadAuthorizedKeys(ctx context.Context, in *UploadAuthorizedKeysRequest, opts ...grpc.CallOption) (*UploadAuthorizedKeysResponse, error) { - out := new(UploadAuthorizedKeysResponse) - err := c.cc.Invoke(ctx, "/debugd.Debugd/UploadAuthorizedKeys", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *debugdClient) UploadBootstrapper(ctx context.Context, opts ...grpc.CallOption) (Debugd_UploadBootstrapperClient, error) { stream, err := c.cc.NewStream(ctx, &Debugd_ServiceDesc.Streams[0], "/debugd.Debugd/UploadBootstrapper", opts...) if err != nil { @@ -112,15 +101,6 @@ func (x *debugdDownloadBootstrapperClient) Recv() (*Chunk, error) { return m, nil } -func (c *debugdClient) DownloadAuthorizedKeys(ctx context.Context, in *DownloadAuthorizedKeysRequest, opts ...grpc.CallOption) (*DownloadAuthorizedKeysResponse, error) { - out := new(DownloadAuthorizedKeysResponse) - err := c.cc.Invoke(ctx, "/debugd.Debugd/DownloadAuthorizedKeys", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *debugdClient) UploadSystemServiceUnits(ctx context.Context, in *UploadSystemdServiceUnitsRequest, opts ...grpc.CallOption) (*UploadSystemdServiceUnitsResponse, error) { out := new(UploadSystemdServiceUnitsResponse) err := c.cc.Invoke(ctx, "/debugd.Debugd/UploadSystemServiceUnits", in, out, opts...) @@ -134,10 +114,8 @@ func (c *debugdClient) UploadSystemServiceUnits(ctx context.Context, in *UploadS // All implementations must embed UnimplementedDebugdServer // for forward compatibility type DebugdServer interface { - UploadAuthorizedKeys(context.Context, *UploadAuthorizedKeysRequest) (*UploadAuthorizedKeysResponse, error) UploadBootstrapper(Debugd_UploadBootstrapperServer) error DownloadBootstrapper(*DownloadBootstrapperRequest, Debugd_DownloadBootstrapperServer) error - DownloadAuthorizedKeys(context.Context, *DownloadAuthorizedKeysRequest) (*DownloadAuthorizedKeysResponse, error) UploadSystemServiceUnits(context.Context, *UploadSystemdServiceUnitsRequest) (*UploadSystemdServiceUnitsResponse, error) mustEmbedUnimplementedDebugdServer() } @@ -146,18 +124,12 @@ type DebugdServer interface { type UnimplementedDebugdServer struct { } -func (UnimplementedDebugdServer) UploadAuthorizedKeys(context.Context, *UploadAuthorizedKeysRequest) (*UploadAuthorizedKeysResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UploadAuthorizedKeys not implemented") -} func (UnimplementedDebugdServer) UploadBootstrapper(Debugd_UploadBootstrapperServer) error { return status.Errorf(codes.Unimplemented, "method UploadBootstrapper not implemented") } func (UnimplementedDebugdServer) DownloadBootstrapper(*DownloadBootstrapperRequest, Debugd_DownloadBootstrapperServer) error { return status.Errorf(codes.Unimplemented, "method DownloadBootstrapper not implemented") } -func (UnimplementedDebugdServer) DownloadAuthorizedKeys(context.Context, *DownloadAuthorizedKeysRequest) (*DownloadAuthorizedKeysResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DownloadAuthorizedKeys not implemented") -} func (UnimplementedDebugdServer) UploadSystemServiceUnits(context.Context, *UploadSystemdServiceUnitsRequest) (*UploadSystemdServiceUnitsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UploadSystemServiceUnits not implemented") } @@ -174,24 +146,6 @@ func RegisterDebugdServer(s grpc.ServiceRegistrar, srv DebugdServer) { s.RegisterService(&Debugd_ServiceDesc, srv) } -func _Debugd_UploadAuthorizedKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UploadAuthorizedKeysRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DebugdServer).UploadAuthorizedKeys(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/debugd.Debugd/UploadAuthorizedKeys", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DebugdServer).UploadAuthorizedKeys(ctx, req.(*UploadAuthorizedKeysRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _Debugd_UploadBootstrapper_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(DebugdServer).UploadBootstrapper(&debugdUploadBootstrapperServer{stream}) } @@ -239,24 +193,6 @@ func (x *debugdDownloadBootstrapperServer) Send(m *Chunk) error { return x.ServerStream.SendMsg(m) } -func _Debugd_DownloadAuthorizedKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DownloadAuthorizedKeysRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DebugdServer).DownloadAuthorizedKeys(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/debugd.Debugd/DownloadAuthorizedKeys", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DebugdServer).DownloadAuthorizedKeys(ctx, req.(*DownloadAuthorizedKeysRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _Debugd_UploadSystemServiceUnits_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UploadSystemdServiceUnitsRequest) if err := dec(in); err != nil { @@ -282,14 +218,6 @@ var Debugd_ServiceDesc = grpc.ServiceDesc{ ServiceName: "debugd.Debugd", HandlerType: (*DebugdServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "UploadAuthorizedKeys", - Handler: _Debugd_UploadAuthorizedKeys_Handler, - }, - { - MethodName: "DownloadAuthorizedKeys", - Handler: _Debugd_DownloadAuthorizedKeys_Handler, - }, { MethodName: "UploadSystemServiceUnits", Handler: _Debugd_UploadSystemServiceUnits_Handler, diff --git a/docs/docs/architecture/components.md b/docs/docs/architecture/components.md index 2ba453a3f..c2e09293b 100644 --- a/docs/docs/architecture/components.md +++ b/docs/docs/architecture/components.md @@ -8,7 +8,6 @@ These features are provided by several components: * The [JoinService](components.md#joinservice) joins new nodes to an existing cluster * The [VerificationService](components.md#verificationservice) provides remote attestation functionality * The [Key Management Service (KMS)](components.md#kms) manages Constellation-internal keys -* The [AccessManager](components.md#accessmanager) manages node SSH access The relations between components are shown in the following diagram: @@ -22,7 +21,6 @@ flowchart LR C[Bootstrapper] end subgraph Kubernetes - D[AccessManager] E[JoinService] F[KMS] G[VerificationService] @@ -74,8 +72,3 @@ Read more about the hardware-based [attestation feature](attestation.md) of Cons The *KMS* runs as DaemonSet on each control-plane node. It implements the key management for the [storage encryption keys](keys.md#storage-encryption) in Constellation. These keys are used for the [state disk](images.md#state-disk) of each node and the [transparently encrypted storage](encrypted-storage.md) for Kubernetes. Depending on wether the [constellation-managed](keys.md#constellation-managed-key-management) or [user-managed](keys.md#user-managed-key-management) mode is used, the *KMS* holds the key encryption key (KEK) directly or calls an external service for key derivation respectively. - -## AccessManager - -The *AccessManager* runs as DaemonSet on each node. -It manages the user's SSH access to nodes as specified in the config. diff --git a/docs/docs/workflows/ssh.md b/docs/docs/workflows/ssh.md deleted file mode 100644 index 0871973f7..000000000 --- a/docs/docs/workflows/ssh.md +++ /dev/null @@ -1,59 +0,0 @@ -# Manage SSH keys - -Constellation allows you to create UNIX users that can connect to both control-plane and worker nodes over SSH. As the system partitions are read-only, users need to be re-created upon each restart of a node. This is automated by the *Access Manager*. - -On cluster initialization, users defined in the `ssh-users` section of the Constellation configuration file are created and stored in the `ssh-users` ConfigMap in the `kube-system` namespace. For a running cluster, you can add or remove users by modifying the ConfigMap and restarting a node. - -## Access Manager -The Access Manager supports all OpenSSH key types. These are RSA, ECDSA (using the `nistp256`, `nistp384`, `nistp521` curves) and Ed25519. - -:::note -All users are automatically created with `sudo` capabilities. -::: - -The Access Manager is deployed as a DaemonSet called `constellation-access-manager`, running as an `initContainer` and afterward running a `pause` container to avoid automatic restarts. While technically killing the Pod and letting it restart works for the (re-)creation of users, it doesn't automatically remove users. Thus, a node restart is required after making changes to the ConfigMap. - -When a user is deleted from the ConfigMap, it won't be re-created after the next restart of a node. The home directories of the affected users will be moved to `/var/evicted`. - -You can update the ConfigMap by: -```bash -kubectl edit configmap -n kube-system ssh-users -``` - -Or alternatively, by modifying and re-applying it with the definition listed in the examples. - -## Examples -You can add a user `myuser` in `constellation-config.yaml` like this: - -```yaml -# Create SSH users on Constellation nodes upon the first initialization of the cluster. -sshUsers: - myuser: "ssh-rsa AAAA...mgNJd9jc=" -``` - -This user is then created upon the first initialization of the cluster, and translated into a ConfigMap as shown below: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: ssh-users - namespace: kube-system -data: - myuser: "ssh-rsa AAAA...mgNJd9jc=" -``` - -You can add users by adding `data` entries: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: ssh-users - namespace: kube-system -data: - myuser: "ssh-rsa AAAA...mgNJd9jc=" - anotheruser: "ssh-ed25519 AAAA...CldH" -``` - -Similarly, removing any entries causes users to be evicted upon the next restart of the node. diff --git a/docs/docs/workflows/troubleshooting.md b/docs/docs/workflows/troubleshooting.md index 0cf87db0c..0555e9076 100644 --- a/docs/docs/workflows/troubleshooting.md +++ b/docs/docs/workflows/troubleshooting.md @@ -45,3 +45,31 @@ Constellation uses the default bucket to store logs. Its [default retention peri + +## Connect to nodes via SSH + +Debugging via a shell on a node is [directly supported by Kubernetes](https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#node-shell-session). + +1. Figure out which node to connect to: + + ```sh + kubectl get nodes + # or to see more information, such as IPs: + kubectl get nodes -o wide + ``` + +2. Connect to the node: + + ```sh + kubectl debug node/constell-worker-xksa0-000000 -it --image=busybox + ``` + + You will be presented with a prompt. + + The nodes file system is mounted at `/host`. + +3. Once finished, cleanup the debug pod: + + ```sh + kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj + ``` diff --git a/docs/sidebars.js b/docs/sidebars.js index 5b3609283..16be5d97d 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -153,11 +153,6 @@ const sidebars = { label: 'Verify your cluster', id: 'workflows/verify-cluster', }, - { - type: 'doc', - label: 'Manage SSH keys', - id: 'workflows/ssh', - }, { type: 'doc', label: 'Use persistent storage', diff --git a/internal/cloud/azure/metadata.go b/internal/cloud/azure/metadata.go index 348491b49..0def7f643 100644 --- a/internal/cloud/azure/metadata.go +++ b/internal/cloud/azure/metadata.go @@ -23,10 +23,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/cloud/metadata" ) -var ( - publicIPAddressRegexp = regexp.MustCompile(`/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft.Network/publicIPAddresses/(?P[^/]+)`) - keyPathRegexp = regexp.MustCompile(`^\/home\/([^\/]+)\/\.ssh\/authorized_keys$`) -) +var publicIPAddressRegexp = regexp.MustCompile(`/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft.Network/publicIPAddresses/(?P[^/]+)`) // Metadata implements azure metadata APIs. type Metadata struct { @@ -364,22 +361,6 @@ func extractInstanceTags(tags map[string]*string) map[string]string { return metadataMap } -// extractSSHKeys extracts SSH public keys from azure instance OS Profile. -func extractSSHKeys(sshConfig armcomputev2.SSHConfiguration) map[string][]string { - sshKeys := map[string][]string{} - for _, key := range sshConfig.PublicKeys { - if key == nil || key.Path == nil || key.KeyData == nil { - continue - } - matches := keyPathRegexp.FindStringSubmatch(*key.Path) - if len(matches) != 2 { - continue - } - sshKeys[matches[1]] = append(sshKeys[matches[1]], *key.KeyData) - } - return sshKeys -} - type cloudConfig struct { Cloud string `json:"cloud,omitempty"` TenantID string `json:"tenantId,omitempty"` diff --git a/internal/cloud/azure/metadata_test.go b/internal/cloud/azure/metadata_test.go index 523c17519..7ef352f5e 100644 --- a/internal/cloud/azure/metadata_test.go +++ b/internal/cloud/azure/metadata_test.go @@ -28,7 +28,6 @@ func TestList(t *testing.T) { ProviderID: "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set-name/virtualMachines/instance-id", Role: role.Worker, VPCIP: "192.0.2.0", - SSHKeys: map[string][]string{"user": {"key-data"}}, }, } testCases := map[string]struct { @@ -92,7 +91,6 @@ func TestSelf(t *testing.T) { ProviderID: "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set-name/virtualMachines/instance-id", Role: role.Worker, VPCIP: "192.0.2.0", - SSHKeys: map[string][]string{"user": {"key-data"}}, } testCases := map[string]struct { imdsAPI imdsAPI @@ -561,70 +559,6 @@ func TestExtractInstanceTags(t *testing.T) { } } -func TestExtractSSHKeys(t *testing.T) { - testCases := map[string]struct { - in armcomputev2.SSHConfiguration - wantKeys map[string][]string - }{ - "ssh key is extracted": { - in: armcomputev2.SSHConfiguration{ - PublicKeys: []*armcomputev2.SSHPublicKey{ - { - KeyData: to.Ptr("key-data"), - Path: to.Ptr("/home/user/.ssh/authorized_keys"), - }, - }, - }, - wantKeys: map[string][]string{"user": {"key-data"}}, - }, - "invalid path is skipped": { - in: armcomputev2.SSHConfiguration{ - PublicKeys: []*armcomputev2.SSHPublicKey{ - { - KeyData: to.Ptr("key-data"), - Path: to.Ptr("invalid-path"), - }, - }, - }, - wantKeys: map[string][]string{}, - }, - "key data is nil": { - in: armcomputev2.SSHConfiguration{ - PublicKeys: []*armcomputev2.SSHPublicKey{ - { - Path: to.Ptr("/home/user/.ssh/authorized_keys"), - }, - }, - }, - wantKeys: map[string][]string{}, - }, - "path is nil": { - in: armcomputev2.SSHConfiguration{ - PublicKeys: []*armcomputev2.SSHPublicKey{ - { - KeyData: to.Ptr("key-data"), - }, - }, - }, - wantKeys: map[string][]string{}, - }, - "public keys are nil": { - in: armcomputev2.SSHConfiguration{}, - wantKeys: map[string][]string{}, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - assert := assert.New(t) - - keys := extractSSHKeys(tc.in) - - assert.Equal(tc.wantKeys, keys) - }) - } -} - func newNetworkInterfacesStub() *stubNetworkInterfacesAPI { return &stubNetworkInterfacesAPI{ getInterface: armnetwork.Interface{ @@ -673,16 +607,6 @@ func newVirtualMachineScaleSetsVMsStub() *stubVirtualMachineScaleSetVMsAPI { }, OSProfile: &armcomputev2.OSProfile{ ComputerName: to.Ptr("scale-set-name-instance-id"), - LinuxConfiguration: &armcomputev2.LinuxConfiguration{ - SSH: &armcomputev2.SSHConfiguration{ - PublicKeys: []*armcomputev2.SSHPublicKey{ - { - KeyData: to.Ptr("key-data"), - Path: to.Ptr("/home/user/.ssh/authorized_keys"), - }, - }, - }, - }, }, }, Tags: map[string]*string{ @@ -706,16 +630,6 @@ func newVirtualMachineScaleSetsVMsStub() *stubVirtualMachineScaleSetVMsAPI { }, OSProfile: &armcomputev2.OSProfile{ ComputerName: to.Ptr("scale-set-name-instance-id"), - LinuxConfiguration: &armcomputev2.LinuxConfiguration{ - SSH: &armcomputev2.SSHConfiguration{ - PublicKeys: []*armcomputev2.SSHPublicKey{ - { - KeyData: to.Ptr("key-data"), - Path: to.Ptr("/home/user/.ssh/authorized_keys"), - }, - }, - }, - }, }, }, Tags: map[string]*string{ diff --git a/internal/cloud/azure/scaleset.go b/internal/cloud/azure/scaleset.go index 02f1f9786..1b3cc8a87 100644 --- a/internal/cloud/azure/scaleset.go +++ b/internal/cloud/azure/scaleset.go @@ -87,12 +87,6 @@ func convertScaleSetVMToCoreInstance(vm armcomputev2.VirtualMachineScaleSetVM, n if vm.Properties == nil || vm.Properties.OSProfile == nil || vm.Properties.OSProfile.ComputerName == nil { return metadata.InstanceMetadata{}, errors.New("retrieving instance from armcompute API client returned no computer name") } - var sshKeys map[string][]string - if vm.Properties.OSProfile.LinuxConfiguration == nil || vm.Properties.OSProfile.LinuxConfiguration.SSH == nil { - sshKeys = map[string][]string{} - } else { - sshKeys = extractSSHKeys(*vm.Properties.OSProfile.LinuxConfiguration.SSH) - } if vm.Tags == nil { return metadata.InstanceMetadata{}, errors.New("retrieving instance from armcompute API client returned no tags") @@ -103,7 +97,6 @@ func convertScaleSetVMToCoreInstance(vm armcomputev2.VirtualMachineScaleSetVM, n ProviderID: "azure://" + *vm.ID, Role: extractScaleSetVMRole(vm.Tags), VPCIP: extractVPCIP(networkInterfaces), - SSHKeys: sshKeys, }, nil } diff --git a/internal/cloud/azure/scaleset_test.go b/internal/cloud/azure/scaleset_test.go index f6134846e..9f53b47af 100644 --- a/internal/cloud/azure/scaleset_test.go +++ b/internal/cloud/azure/scaleset_test.go @@ -27,7 +27,6 @@ func TestGetScaleSetVM(t *testing.T) { ProviderID: "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set-name/virtualMachines/instance-id", Role: role.Worker, VPCIP: "192.0.2.0", - SSHKeys: map[string][]string{"user": {"key-data"}}, } testCases := map[string]struct { providerID string @@ -87,7 +86,6 @@ func TestListScaleSetVMs(t *testing.T) { ProviderID: "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set-name/virtualMachines/instance-id", Role: role.Worker, VPCIP: "192.0.2.0", - SSHKeys: map[string][]string{"user": {"key-data"}}, }, } testCases := map[string]struct { @@ -189,7 +187,6 @@ func TestConvertScaleSetVMToCoreInstance(t *testing.T) { Name: "scale-set-name-instance-id", ProviderID: "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set-name/virtualMachines/instance-id", VPCIP: "192.0.2.0", - SSHKeys: map[string][]string{}, }, }, "invalid instance": { @@ -290,16 +287,6 @@ func newListContainingNilScaleSetVirtualMachinesStub() *stubVirtualMachineScaleS }, OSProfile: &armcomputev2.OSProfile{ ComputerName: to.Ptr("scale-set-name-instance-id"), - LinuxConfiguration: &armcomputev2.LinuxConfiguration{ - SSH: &armcomputev2.SSHConfiguration{ - PublicKeys: []*armcomputev2.SSHPublicKey{ - { - KeyData: to.Ptr("key-data"), - Path: to.Ptr("/home/user/.ssh/authorized_keys"), - }, - }, - }, - }, }, }, }, diff --git a/internal/cloud/metadata/metadata.go b/internal/cloud/metadata/metadata.go index daabd6a8f..61b501a09 100644 --- a/internal/cloud/metadata/metadata.go +++ b/internal/cloud/metadata/metadata.go @@ -23,9 +23,7 @@ type InstanceMetadata struct { Role role.Role // VPCIP is the primary IP address of the instance in the VPC. VPCIP string - // SSHKeys maps usernames to ssh public keys. - // TODO: remove everywhere. - SSHKeys map[string][]string + // SecondaryIPRange is the VPC wide CIDR from which subnets are attached to VMs as AliasIPRanges. // May be empty on certain CSPs. SecondaryIPRange string diff --git a/internal/config/config.go b/internal/config/config.go index c93ef5074..f2d4430d9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -55,7 +55,7 @@ type Config struct { // Supported cloud providers and their specific configurations. Provider ProviderConfig `yaml:"provider" validate:"dive"` // description: | - // Create SSH users on Constellation nodes. + // Deprecated: Does nothing! To get node SSH access, see: https://constellation-docs.edgeless.systems/constellation/workflows/troubleshooting#connect-to-nodes-via-ssh // examples: // - value: '[]UserKey{ { Username: "Alice", PublicKey: "ssh-rsa AAAAB3NzaC...5QXHKW1rufgtJeSeJ8= alice@domain.com" } }' SSHUsers []UserKey `yaml:"sshUsers,omitempty" validate:"dive"` @@ -77,12 +77,20 @@ type UpgradeConfig struct { } // UserKey describes a user that should be created with corresponding public SSH key. +// +// Deprecated: UserKey was used as configuration for access-manager, which was removed +// in v2.2, but config needs to retain these values for backwards compatibility and +// config validation. type UserKey struct { // description: | // Username of new SSH user. + // + // Deprecated: See UserKey. Username string `yaml:"username" validate:"required"` // description: | // Public key of new SSH user. + // + // Deprecated: See UserKey. PublicKey string `yaml:"publicKey" validate:"required"` } diff --git a/internal/config/config_doc.go b/internal/config/config_doc.go index c6f1e51de..7e040d452 100644 --- a/internal/config/config_doc.go +++ b/internal/config/config_doc.go @@ -54,8 +54,8 @@ func init() { ConfigDoc.Fields[5].Name = "sshUsers" ConfigDoc.Fields[5].Type = "[]UserKey" ConfigDoc.Fields[5].Note = "" - ConfigDoc.Fields[5].Description = "Create SSH users on Constellation nodes." - ConfigDoc.Fields[5].Comments[encoder.LineComment] = "Create SSH users on Constellation nodes." + ConfigDoc.Fields[5].Description = "Deprecated: Does nothing! To get node SSH access, see: https://constellation-docs.edgeless.systems/constellation/workflows/troubleshooting#connect-to-nodes-via-ssh" + ConfigDoc.Fields[5].Comments[encoder.LineComment] = "Deprecated: Does nothing! To get node SSH access, see: https://constellation-docs.edgeless.systems/constellation/workflows/troubleshooting#connect-to-nodes-via-ssh" ConfigDoc.Fields[5].AddExample("", []UserKey{{Username: "Alice", PublicKey: "ssh-rsa AAAAB3NzaC...5QXHKW1rufgtJeSeJ8= alice@domain.com"}}) ConfigDoc.Fields[6].Name = "upgrade" @@ -91,7 +91,7 @@ func init() { UserKeyDoc.Type = "UserKey" UserKeyDoc.Comments[encoder.LineComment] = "UserKey describes a user that should be created with corresponding public SSH key." - UserKeyDoc.Description = "UserKey describes a user that should be created with corresponding public SSH key." + UserKeyDoc.Description = "UserKey describes a user that should be created with corresponding public SSH key.\n\nDeprecated: UserKey was used as configuration for access-manager, which was removed\nin v2.2, but config needs to retain these values for backwards compatibility and\nconfig validation.\n" UserKeyDoc.AddExample("", []UserKey{{Username: "Alice", PublicKey: "ssh-rsa AAAAB3NzaC...5QXHKW1rufgtJeSeJ8= alice@domain.com"}}) UserKeyDoc.AppearsIn = []encoder.Appearance{ @@ -104,12 +104,12 @@ func init() { UserKeyDoc.Fields[0].Name = "username" UserKeyDoc.Fields[0].Type = "string" UserKeyDoc.Fields[0].Note = "" - UserKeyDoc.Fields[0].Description = "Username of new SSH user." + UserKeyDoc.Fields[0].Description = "Username of new SSH user.\n\nDeprecated: See UserKey." UserKeyDoc.Fields[0].Comments[encoder.LineComment] = "Username of new SSH user." UserKeyDoc.Fields[1].Name = "publicKey" UserKeyDoc.Fields[1].Type = "string" UserKeyDoc.Fields[1].Note = "" - UserKeyDoc.Fields[1].Description = "Public key of new SSH user." + UserKeyDoc.Fields[1].Description = "Public key of new SSH user.\n\nDeprecated: See UserKey." UserKeyDoc.Fields[1].Comments[encoder.LineComment] = "Public key of new SSH user." ProviderConfigDoc.Type = "ProviderConfig" @@ -347,8 +347,8 @@ func init() { GCPConfigDoc.Fields[8].Comments[encoder.LineComment] = "List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning." QEMUConfigDoc.Type = "QEMUConfig" - QEMUConfigDoc.Comments[encoder.LineComment] = "" - QEMUConfigDoc.Description = "" + QEMUConfigDoc.Comments[encoder.LineComment] = "QEMUConfig holds config information for QEMU based Constellation deployments." + QEMUConfigDoc.Description = "QEMUConfig holds config information for QEMU based Constellation deployments." QEMUConfigDoc.AppearsIn = []encoder.Appearance{ { TypeName: "ProviderConfig", diff --git a/internal/config/config_test.go b/internal/config/config_test.go index d7e6ec47f..708344019 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -255,7 +255,6 @@ func TestConfigGeneratedDocsFresh(t *testing.T) { assert.Len(ConfigDoc.Fields, reflect.ValueOf(Config{}).NumField(), updateMsg) assert.Len(UpgradeConfigDoc.Fields, reflect.ValueOf(UpgradeConfig{}).NumField(), updateMsg) - assert.Len(UserKeyDoc.Fields, reflect.ValueOf(UserKey{}).NumField(), updateMsg) assert.Len(ProviderConfigDoc.Fields, reflect.ValueOf(ProviderConfig{}).NumField(), updateMsg) assert.Len(AzureConfigDoc.Fields, reflect.ValueOf(AzureConfig{}).NumField(), updateMsg) assert.Len(GCPConfigDoc.Fields, reflect.ValueOf(GCPConfig{}).NumField(), updateMsg) diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 1b11cb524..109ba44ae 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -52,8 +52,6 @@ const ( KubernetesPort = 6443 // RecoveryPort port for Constellation recovery server. RecoveryPort = 9999 - // SSHPort port for SSH access. - SSHPort = 22 // DebugdPort port for debugd process. DebugdPort = 4000 // KonnectivityPort port for konnectivity k8s service. diff --git a/internal/deploy/ssh/proto.go b/internal/deploy/ssh/proto.go deleted file mode 100644 index 415f263bc..000000000 --- a/internal/deploy/ssh/proto.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package ssh - -import ( - "github.com/edgelesssys/constellation/v2/bootstrapper/initproto" -) - -// FromProtoSlice converts a SSH UserKey definition from pubproto to the Go flavor. -func FromProtoSlice(input []*initproto.SSHUserKey) []UserKey { - if input == nil { - return nil - } - - output := make([]UserKey, 0) - - for _, pair := range input { - singlePair := UserKey{ - Username: pair.Username, - PublicKey: pair.PublicKey, - } - - output = append(output, singlePair) - } - - return output -} - -// ToProtoSlice converts a SSH UserKey definition from Go to pubproto flavor. -func ToProtoSlice(input []*UserKey) []*initproto.SSHUserKey { - if input == nil { - return nil - } - - output := make([]*initproto.SSHUserKey, 0) - for _, pair := range input { - singlePair := initproto.SSHUserKey{ - Username: pair.Username, - PublicKey: pair.PublicKey, - } - - output = append(output, &singlePair) - } - - return output -} diff --git a/internal/deploy/ssh/proto_test.go b/internal/deploy/ssh/proto_test.go deleted file mode 100644 index f458b06b9..000000000 --- a/internal/deploy/ssh/proto_test.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package ssh - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestToAndFromProtoSlice(t *testing.T) { - assert := assert.New(t) - - DemoSSHUser1 := UserKey{ - Username: "test-user-2", - PublicKey: "ssh-rsa abcdefg", - } - - DemoSSHUser2 := UserKey{ - Username: "test-user-2", - PublicKey: "ssh-rsa hijklmnop", - } - - // Input usually consists of pointers (from config parsing) - DemoSSHUsersPointers := make([]*UserKey, 0) - DemoSSHUsersPointers = append(DemoSSHUsersPointers, &DemoSSHUser1) - DemoSSHUsersPointers = append(DemoSSHUsersPointers, &DemoSSHUser2) - - // Expected output usually does not consist of pointers - DemoSSHUsersNoPointers := make([]UserKey, 0) - DemoSSHUsersNoPointers = append(DemoSSHUsersNoPointers, DemoSSHUser1) - DemoSSHUsersNoPointers = append(DemoSSHUsersNoPointers, DemoSSHUser2) - - ToProtoArray := ToProtoSlice(DemoSSHUsersPointers) - FromProtoArray := FromProtoSlice(ToProtoArray) - - assert.Equal(DemoSSHUsersNoPointers, FromProtoArray) -} diff --git a/internal/deploy/ssh/ssh.go b/internal/deploy/ssh/ssh.go deleted file mode 100644 index 4d35bbab3..000000000 --- a/internal/deploy/ssh/ssh.go +++ /dev/null @@ -1,114 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package ssh - -import ( - "context" - "fmt" - "os" - "sync" - - "github.com/edgelesssys/constellation/v2/internal/deploy/user" - "github.com/edgelesssys/constellation/v2/internal/logger" - "go.uber.org/zap" -) - -// UserKey describes an user that should be created with a corresponding public SSH key. -type UserKey struct { - Username string - PublicKey string -} - -// Access reads SSH public keys from a channel, creates the specified users if required and writes the public keys to the users authorized_keys file. -type Access struct { - log *logger.Logger - userManager user.LinuxUserManager - authorized map[UserKey]bool - mux sync.Mutex -} - -// NewAccess creates a new Access. -func NewAccess(log *logger.Logger, userManager user.LinuxUserManager) *Access { - return &Access{ - log: log, - userManager: userManager, - authorized: map[UserKey]bool{}, - } -} - -// alreadyAuthorized checks if key was written to authorized keys before. -func (s *Access) alreadyAuthorized(sshKey UserKey) bool { - _, ok := s.authorized[sshKey] - return ok -} - -// rememberAuthorized marks this key as already written to authorized keys.. -func (s *Access) rememberAuthorized(sshKey UserKey) { - s.authorized[sshKey] = true -} - -// GetAuthorizedKeys returns a list of authorized keys for the specified user. -func (s *Access) GetAuthorizedKeys() []UserKey { - s.mux.Lock() - defer s.mux.Unlock() - - var authorizedKeys []UserKey - for key := range s.authorized { - authorizedKeys = append(authorizedKeys, key) - } - - return authorizedKeys -} - -// DeployAuthorizedKey takes an user & public key pair, creates the user if required and deploy a SSH key for them. -// TODO: Refactor to not write to /etc or /home. -func (s *Access) DeployAuthorizedKey(ctx context.Context, sshKey UserKey) error { - // allow only one thread to write to authorized keys, create users and update the authorized map at a time - s.mux.Lock() - defer s.mux.Unlock() - if s.alreadyAuthorized(sshKey) { - return nil - } - s.log.With(zap.String("username", sshKey.Username)).Infof("Trying to deploy ssh key for user") - user, err := s.userManager.EnsureLinuxUserExists(ctx, sshKey.Username) - if err != nil { - return err - } - // CoreOS uses https://github.com/coreos/ssh-key-dir to search for ssh keys in ~/.ssh/authorized_keys.d/* - sshFolder := fmt.Sprintf("%s/.ssh", user.Home) - authorizedKeysD := fmt.Sprintf("%s/authorized_keys.d", sshFolder) - if err := s.userManager.Fs.MkdirAll(authorizedKeysD, 0o700); err != nil { - return err - } - if err := s.userManager.Fs.Chown(sshFolder, user.UID, user.GID); err != nil { - return err - } - if err := s.userManager.Fs.Chown(authorizedKeysD, user.UID, user.GID); err != nil { - return err - } - authorizedKeysPath := fmt.Sprintf("%s/constellation-ssh-keys", authorizedKeysD) - authorizedKeysFile, err := s.userManager.Fs.OpenFile(authorizedKeysPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) - if err != nil { - return err - } - _, err = authorizedKeysFile.WriteString(fmt.Sprintf("%s\n", sshKey.PublicKey)) - if err != nil { - return err - } - if err := authorizedKeysFile.Close(); err != nil { - return err - } - if err := s.userManager.Fs.Chown(authorizedKeysPath, user.UID, user.GID); err != nil { - return err - } - if err := s.userManager.Fs.Chmod(authorizedKeysPath, 0o644); err != nil { - return err - } - s.rememberAuthorized(sshKey) - s.log.With(zap.String("username", sshKey.Username)).Infof("Successfully authorized user") - return nil -} diff --git a/internal/deploy/ssh/ssh_test.go b/internal/deploy/ssh/ssh_test.go deleted file mode 100644 index cb0a7df9e..000000000 --- a/internal/deploy/ssh/ssh_test.go +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package ssh - -import ( - "context" - "sync" - "testing" - - "github.com/edgelesssys/constellation/v2/internal/deploy/user" - "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/spf13/afero" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.uber.org/goleak" -) - -func TestMain(m *testing.M) { - goleak.VerifyTestMain(m) -} - -func TestGetAuthorizedKeys(t *testing.T) { - testCases := map[string]struct { - authorized map[UserKey]bool - want []UserKey - }{ - "success": { - authorized: map[UserKey]bool{ - {Username: "user1", PublicKey: "ssh-rsa test1=="}: true, - {Username: "user2", PublicKey: "ssh-rsa test2=="}: true, - }, - want: []UserKey{ - {Username: "user1", PublicKey: "ssh-rsa test1=="}, - {Username: "user2", PublicKey: "ssh-rsa test2=="}, - }, - }, - "empty": { - authorized: map[UserKey]bool{}, - want: []UserKey(nil), - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - assert := assert.New(t) - - sshAccess := Access{authorized: tc.authorized} - - keys := sshAccess.GetAuthorizedKeys() - assert.ElementsMatch(tc.want, keys) - }) - } -} - -func TestDeployAuthorizedKey(t *testing.T) { - authorizedKey := UserKey{ - Username: "user", - PublicKey: "ssh-rsa testkey", - } - - testCases := map[string]struct { - fs afero.Fs - passwdContents string - alreadyDeployed bool - readonly bool - wantErr bool - wantFile bool - wantFileContents string - }{ - "deploy works": { - fs: afero.NewMemMapFs(), - wantErr: false, - wantFile: true, - wantFileContents: "ssh-rsa testkey\n", - }, - "appending ssh key works": { - fs: memMapFsWithFile("/var/home/user/.ssh/authorized_keys.d/constellation-ssh-keys", "ssh-rsa preexistingkey\n"), - wantErr: false, - wantFile: true, - wantFileContents: "ssh-rsa preexistingkey\nssh-rsa testkey\n", - }, - "redeployment avoided": { - fs: afero.NewMemMapFs(), - wantErr: false, - alreadyDeployed: true, - wantFile: false, - }, - "readonly fs": { - fs: afero.NewMemMapFs(), - readonly: true, - wantErr: true, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - userManager := user.NewLinuxUserManagerFake(tc.fs) - - assert.NoError(afero.WriteFile(userManager.Fs, "/etc/passwd", []byte(tc.passwdContents), 0o755)) - if tc.readonly { - userManager.Fs = afero.NewReadOnlyFs(userManager.Fs) - } - authorized := map[UserKey]bool{} - if tc.alreadyDeployed { - authorized[UserKey{ - Username: "user", - PublicKey: "ssh-rsa testkey", - }] = true - } - sshAccess := Access{ - log: logger.NewTest(t), - userManager: userManager, - mux: sync.Mutex{}, - authorized: authorized, - } - err := sshAccess.DeployAuthorizedKey(context.Background(), authorizedKey) - - if tc.wantErr { - assert.Error(err) - return - } - require.NoError(err) - if tc.wantFile { - fileContents, err := afero.ReadFile(userManager.Fs, "/var/home/user/.ssh/authorized_keys.d/constellation-ssh-keys") - assert.NoError(err) - assert.Equal(tc.wantFileContents, string(fileContents)) - } else { - exists, err := afero.Exists(userManager.Fs, "/var/home/user/.ssh/authorized_keys.d/constellation-ssh-keys") - assert.NoError(err) - assert.False(exists) - } - }) - } -} - -func memMapFsWithFile(path string, contents string) afero.Fs { - fs := afero.NewMemMapFs() - err := afero.WriteFile(fs, path, []byte(contents), 0o755) - if err != nil { - panic(err) - } - return fs -} diff --git a/internal/versions/versions.go b/internal/versions/versions.go index 77cbec4a5..dbbc887a2 100644 --- a/internal/versions/versions.go +++ b/internal/versions/versions.go @@ -53,8 +53,6 @@ const ( KonnectivityServerImage = "registry.k8s.io/kas-network-proxy/proxy-server:v0.0.33@sha256:2c111f004bec24888d8cfa2a812a38fb8341350abac67dcd0ac64e709dfe389c" // renovate:container // JoinImage image of Constellation join service. JoinImage = "ghcr.io/edgelesssys/constellation/join-service:v2.3.0-pre.0.20221109145754-0d12e37c9699@sha256:afe838fdf9753a6d50eef3a36a17d8993c1732397bb3f965dd25f291e7521acc" // renovate:container - // AccessManagerImage image of Constellation access manager. - AccessManagerImage = "ghcr.io/edgelesssys/constellation/access-manager:v2.3.0-pre.0.20221109145754-0d12e37c9699@sha256:9fe850517115851a0e0969401cc407dad2f2f9157aac86b69db51e28ee4559c4" // renovate:container // KmsImage image of Constellation KMS server. KmsImage = "ghcr.io/edgelesssys/constellation/kmsserver:v2.3.0-pre.0.20221109145754-0d12e37c9699@sha256:bed58eff5ca1ad2bb0eddfdbb642a5dc5454bfd6a0248487ae8e2756227e0e80" // renovate:container // VerificationImage image of Constellation verification service. diff --git a/rfc/updates.md b/rfc/updates.md index f7e40b4d7..7ffde08a7 100644 --- a/rfc/updates.md +++ b/rfc/updates.md @@ -174,7 +174,7 @@ we should add comments to those fields who will not update the cluster. ```yaml kubernetesVersion: 1.24.3 kubernetesServicesVersion: 1.24.5 # Bundled Kubernetes components (Autoscaler, CloudControllerManager, CloudNodeManager, GCP Guest Agent, Konnectivity) -microserviceVersion: 2.2.0 # or constellationVersion: (KMS, AccessManager, JoinService, NodeMaintainanceOperator, NodeOperator, OLM, Verification, Cilium) +microserviceVersion: 2.2.0 # or constellationVersion: (KMS, JoinService, NodeMaintainanceOperator, NodeOperator, OLM, Verification, Cilium) provider: azure: image: /communityGalleries/ConstellationCVM-b3782fa0-0df7-4f2f-963e-fc7fc42663df/images/constellation/versions/2.3.0