mirror of https://github.com/kubernetes/kops.git
kubetest2-kops - Create ephemeral SSH keys
This commit is contained in:
parent
91bce6627e
commit
fdad5cf9e5
|
|
@ -7,6 +7,7 @@ require (
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||||
github.com/octago/sflags v0.2.0
|
github.com/octago/sflags v0.2.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
|
||||||
k8s.io/api v0.23.5
|
k8s.io/api v0.23.5
|
||||||
k8s.io/apimachinery v0.23.5
|
k8s.io/apimachinery v0.23.5
|
||||||
k8s.io/client-go v9.0.0+incompatible
|
k8s.io/client-go v9.0.0+incompatible
|
||||||
|
|
@ -122,7 +123,6 @@ require (
|
||||||
github.com/xanzy/ssh-agent v0.3.1 // indirect
|
github.com/xanzy/ssh-agent v0.3.1 // indirect
|
||||||
go.opencensus.io v0.23.0 // indirect
|
go.opencensus.io v0.23.0 // indirect
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
|
|
||||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"k8s.io/kops/tests/e2e/kubetest2-kops/gce"
|
"k8s.io/kops/tests/e2e/kubetest2-kops/gce"
|
||||||
"k8s.io/kops/tests/e2e/pkg/kops"
|
"k8s.io/kops/tests/e2e/pkg/kops"
|
||||||
"k8s.io/kops/tests/e2e/pkg/target"
|
"k8s.io/kops/tests/e2e/pkg/target"
|
||||||
|
"k8s.io/kops/tests/e2e/pkg/util"
|
||||||
"sigs.k8s.io/kubetest2/pkg/boskos"
|
"sigs.k8s.io/kubetest2/pkg/boskos"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -66,13 +67,13 @@ func (d *deployer) initialize() error {
|
||||||
|
|
||||||
switch d.CloudProvider {
|
switch d.CloudProvider {
|
||||||
case "aws":
|
case "aws":
|
||||||
// These environment variables are defined by the "preset-aws-ssh" prow preset
|
if d.SSHPrivateKeyPath == "" || d.SSHPublicKeyPath == "" {
|
||||||
// https://github.com/kubernetes/test-infra/blob/3d3b325c98b739b526ba5d93ce21c90a05e1f46d/config/prow/config.yaml#L653-L670
|
publicKeyPath, privateKeyPath, err := util.CreateSSHKeyPair(d.ClusterName)
|
||||||
if d.SSHPrivateKeyPath == "" {
|
if err != nil {
|
||||||
d.SSHPrivateKeyPath = os.Getenv("AWS_SSH_PRIVATE_KEY_FILE")
|
return err
|
||||||
}
|
}
|
||||||
if d.SSHPublicKeyPath == "" {
|
d.SSHPublicKeyPath = publicKeyPath
|
||||||
d.SSHPublicKeyPath = os.Getenv("AWS_SSH_PUBLIC_KEY_FILE")
|
d.SSHPrivateKeyPath = privateKeyPath
|
||||||
}
|
}
|
||||||
case "digitalocean":
|
case "digitalocean":
|
||||||
if d.SSHPrivateKeyPath == "" {
|
if d.SSHPrivateKeyPath == "" {
|
||||||
|
|
@ -185,6 +186,9 @@ func (d *deployer) env() []string {
|
||||||
vars = append(vars, k+"="+v)
|
vars = append(vars, k+"="+v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Recognized by the e2e framework
|
||||||
|
// https://github.com/kubernetes/kubernetes/blob/a750d8054a6cb3167f495829ce3e77ab0ccca48e/test/e2e/framework/ssh/ssh.go#L59-L62
|
||||||
|
vars = append(vars, fmt.Sprintf("KUBE_SSH_KEY_PATH=%v", d.SSHPrivateKeyPath))
|
||||||
} else if d.CloudProvider == "digitalocean" {
|
} else if d.CloudProvider == "digitalocean" {
|
||||||
// Pass through some env vars if set
|
// Pass through some env vars if set
|
||||||
for _, k := range []string{"DIGITALOCEAN_ACCESS_TOKEN", "S3_ACCESS_KEY_ID", "S3_SECRET_ACCESS_KEY"} {
|
for _, k := range []string{"DIGITALOCEAN_ACCESS_TOKEN", "S3_ACCESS_KEY_ID", "S3_SECRET_ACCESS_KEY"} {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateSSHKeyPair creates a key pair in a temp directory
|
||||||
|
// and returns the paths to the private and public keys respectively.
|
||||||
|
// The file paths are deterministic from the clusterName.
|
||||||
|
func CreateSSHKeyPair(clusterName string) (string, string, error) {
|
||||||
|
_, privateKey, err := ed25519.GenerateKey(nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
publicKey, err := ssh.NewPublicKey(privateKey.Public())
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
publicKeyContents := ssh.MarshalAuthorizedKey(publicKey)
|
||||||
|
|
||||||
|
user := os.Getenv("USER")
|
||||||
|
if user == "" {
|
||||||
|
user = "user"
|
||||||
|
}
|
||||||
|
comment := fmt.Sprintf(" %v\n", user)
|
||||||
|
|
||||||
|
// AWS requires a comment on the SSH public key but MarshalAuthorizedKey doesn't create one
|
||||||
|
publicKeyContents = publicKeyContents[:len(publicKeyContents)-1]
|
||||||
|
publicKeyContents = append(publicKeyContents, []byte(comment)...)
|
||||||
|
|
||||||
|
privateKeyContents, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp := os.TempDir()
|
||||||
|
dir := filepath.Join(tmp, "kops", clusterName)
|
||||||
|
err = os.MkdirAll(dir, 0700)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
publicKeyPath := filepath.Join(dir, "id_ed25519.pub")
|
||||||
|
privateKeyPath := filepath.Join(dir, "id_ed25519")
|
||||||
|
|
||||||
|
if _, err := os.Stat(privateKeyPath); errors.Is(err, os.ErrNotExist) {
|
||||||
|
if err := os.WriteFile(publicKeyPath, publicKeyContents, 0644); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
f, err := os.OpenFile(privateKeyPath, os.O_WRONLY|os.O_CREATE, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
err = pem.Encode(f, &pem.Block{
|
||||||
|
Type: "PRIVATE KEY",
|
||||||
|
Bytes: privateKeyContents,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return publicKeyPath, privateKeyPath, nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue