Use the SSH key from the secret store

It is an error if there is not exactly one, but we have commands to
manage it now.
This commit is contained in:
Justin Santa Barbara 2016-08-11 11:06:56 -04:00
parent 189526ab20
commit 219c6e4308
5 changed files with 63 additions and 25 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/golang/glog"
"github.com/spf13/cobra"
"io/ioutil"
"k8s.io/kops/upup/pkg/api"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup"
@ -297,8 +298,14 @@ func (c *CreateClusterCmd) Run(args []string) error {
}
}
sshPublicKeys := make(map[string][]byte)
if c.SSHPublicKey != "" {
c.SSHPublicKey = utils.ExpandPath(c.SSHPublicKey)
authorized, err := ioutil.ReadFile(c.SSHPublicKey)
if err != nil {
return fmt.Errorf("error reading SSH key file %q: %v", c.SSHPublicKey, err)
}
sshPublicKeys[fi.SecretNameSSHPrimary] = authorized
}
if c.AdminAccess != "" {
@ -350,6 +357,14 @@ func (c *CreateClusterCmd) Run(args []string) error {
return fmt.Errorf("error writing completed cluster spec: %v", err)
}
for k, data := range sshPublicKeys {
keyStore := clusterRegistry.KeyStore(cluster.Name)
err = keyStore.AddSSHPublicKey(k, data)
if err != nil {
return fmt.Errorf("error addding SSH public key: %v", err)
}
}
if isDryrun {
fmt.Println("Previewing changes that will be made:\n")
}
@ -360,7 +375,6 @@ func (c *CreateClusterCmd) Run(args []string) error {
Models: strings.Split(c.Models, ","),
ClusterRegistry: clusterRegistry,
Target: c.Target,
SSHPublicKey: c.SSHPublicKey,
OutDir: c.OutDir,
DryRun: isDryrun,
}

View File

@ -186,7 +186,7 @@ func (c *RootCmd) Cluster() (*api.ClusterRegistry, *api.Cluster, error) {
}
func (c *RootCmd) InstanceGroupRegistry() (*api.InstanceGroupRegistry, error) {
clusterStore, err := c.ClusterRegistry()
clusterRegistry, err := c.ClusterRegistry()
if err != nil {
return nil, err
}
@ -196,11 +196,11 @@ func (c *RootCmd) InstanceGroupRegistry() (*api.InstanceGroupRegistry, error) {
return nil, fmt.Errorf("--name is required")
}
return clusterStore.InstanceGroups(clusterName)
return clusterRegistry.InstanceGroups(clusterName)
}
func (c *RootCmd) SecretStore() (fi.SecretStore, error) {
clusterStore, err := c.ClusterRegistry()
clusterRegistry, err := c.ClusterRegistry()
if err != nil {
return nil, err
}
@ -210,11 +210,11 @@ func (c *RootCmd) SecretStore() (fi.SecretStore, error) {
return nil, fmt.Errorf("--name is required")
}
return clusterStore.SecretStore(clusterName), nil
return clusterRegistry.SecretStore(clusterName), nil
}
func (c *RootCmd) KeyStore() (fi.CAStore, error) {
clusterStore, err := c.ClusterRegistry()
clusterRegistry, err := c.ClusterRegistry()
if err != nil {
return nil, err
}
@ -224,5 +224,5 @@ func (c *RootCmd) KeyStore() (fi.CAStore, error) {
return nil, fmt.Errorf("--name is required")
}
return clusterStore.KeyStore(clusterName), nil
return clusterRegistry.KeyStore(clusterName), nil
}

View File

@ -4,10 +4,13 @@ import (
"fmt"
"github.com/golang/glog"
"github.com/spf13/cobra"
"io/ioutil"
"k8s.io/kops/upup/pkg/api"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup"
"k8s.io/kops/upup/pkg/fi/utils"
"k8s.io/kops/upup/pkg/kutil"
"os"
"strings"
)
@ -39,7 +42,7 @@ func init() {
cmd.Flags().BoolVar(&updateCluster.Yes, "yes", false, "Actually create cloud resources")
cmd.Flags().StringVar(&updateCluster.Target, "target", "direct", "Target - direct, terraform")
cmd.Flags().StringVar(&updateCluster.Models, "model", "config,proto,cloudup", "Models to apply (separate multiple models with commas)")
cmd.Flags().StringVar(&updateCluster.SSHPublicKey, "ssh-public-key", "~/.ssh/id_rsa.pub", "SSH public key to use")
cmd.Flags().StringVar(&updateCluster.SSHPublicKey, "ssh-public-key", "", "SSH public key to use (deprecated: use kops create secret instead)")
cmd.Flags().StringVar(&updateCluster.OutDir, "out", "", "Path to write any local output")
}
@ -87,7 +90,21 @@ func (c *UpdateClusterCmd) Run(args []string) error {
}
if c.SSHPublicKey != "" {
fmt.Fprintf(os.Stderr, "--ssh-public-key on update is deprecated - please use `kops create secret --name %s sshpublickey admin -i ~/.ssh/id_rsa.pub` instead\n", cluster.Name)
c.SSHPublicKey = utils.ExpandPath(c.SSHPublicKey)
authorized, err := ioutil.ReadFile(c.SSHPublicKey)
if err != nil {
return fmt.Errorf("error reading SSH key file %q: %v", c.SSHPublicKey, err)
}
keyStore, err := rootCommand.KeyStore()
if err != nil {
return err
}
err = keyStore.AddSSHPublicKey(fi.SecretNameSSHPrimary, authorized)
if err != nil {
return fmt.Errorf("error addding SSH public key: %v", err)
}
}
strict := false
@ -102,7 +119,6 @@ func (c *UpdateClusterCmd) Run(args []string) error {
Models: strings.Split(c.Models, ","),
ClusterRegistry: clusterRegistry,
Target: c.Target,
SSHPublicKey: c.SSHPublicKey,
OutDir: c.OutDir,
DryRun: isDryrun,
}

View File

@ -32,6 +32,9 @@ const (
SecretTypeSSHPublicKey = "SSHPublicKey"
SecretTypeKeypair = "Keypair"
SecretTypeSecret = "Secret"
// Name for the primary SSH key
SecretNameSSHPrimary = "admin"
)
type KeystoreItem struct {

View File

@ -3,7 +3,6 @@ package cloudup
import (
"fmt"
"github.com/golang/glog"
"io/ioutil"
"k8s.io/kops/upup/pkg/api"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
@ -30,10 +29,7 @@ type ApplyClusterCmd struct {
// Target specifies how we are operating e.g. direct to GCE, or AWS, or dry-run, or terraform
Target string
//// The node model to use
//NodeModel string
// The SSH public key (file) to use
SSHPublicKey string
// OutDir is a local directory in which we place output, can cache files etc
OutDir string
@ -166,6 +162,18 @@ func (c *ApplyClusterCmd) Run() error {
region := ""
project := ""
var sshPublicKeys [][]byte
{
keys, err := keyStore.FindSSHPublicKeys(fi.SecretNameSSHPrimary)
if err != nil {
return fmt.Errorf("error retrieving SSH public key %q: %v", fi.SecretNameSSHPrimary, err)
}
for _, k := range keys {
sshPublicKeys = append(sshPublicKeys, k.Data)
}
}
switch cluster.Spec.CloudProvider {
case "gce":
{
@ -237,8 +245,14 @@ func (c *ApplyClusterCmd) Run() error {
"dnsZone": &awstasks.DNSZone{},
})
if c.SSHPublicKey == "" {
return fmt.Errorf("SSH public key must be specified when running with AWS")
if len(sshPublicKeys) == 0 {
return fmt.Errorf("SSH public key must be specified when running with AWS (create with `kops create secret --name %s sshpublickey admin -i ~/.ssh/id_rsa.pub`)", cluster.Name)
}
if len(sshPublicKeys) != 1 {
return fmt.Errorf("Exactly one 'admin' SSH public key can be specified when running with AWS; please delete a key using `kops delete secret`")
} else {
l.Resources["ssh-public-key"] = fi.NewStringResource(string(sshPublicKeys[0]))
}
l.TemplateFunctions["MachineTypeInfo"] = awsup.GetMachineTypeInfo
@ -348,15 +362,6 @@ func (c *ApplyClusterCmd) Run() error {
tf.AddTo(l.TemplateFunctions)
if c.SSHPublicKey != "" {
authorized, err := ioutil.ReadFile(c.SSHPublicKey)
if err != nil {
return fmt.Errorf("error reading SSH key file %q: %v", c.SSHPublicKey, err)
}
l.Resources["ssh-public-key"] = fi.NewStringResource(string(authorized))
}
taskMap, err := l.BuildTasks(modelStore, c.Models)
if err != nil {
return fmt.Errorf("error building tasks: %v", err)