Based on the Readme, if you specify a SSHKeyName in the cluster.spec,

you don't need to add an ssh public key, this change allows that
combination to work on aws.

Basically, if a key name is set on the spec and there's no admin key
file, the key name will be used and the key will not be managed in
terraform.
This commit is contained in:
Roberto Rodriguez Alcala 2019-05-06 16:13:51 -07:00
parent dbae685ee8
commit c6aa23cf91
4 changed files with 32 additions and 6 deletions

View File

@ -37,7 +37,9 @@ func (b *SSHKeyModelBuilder) Build(c *fi.ModelBuilderContext) error {
t := &awstasks.SSHKey{
Name: s(name),
Lifecycle: b.Lifecycle,
PublicKey: fi.WrapResource(fi.NewStringResource(string(b.SSHPublicKeys[0]))),
}
if len(b.SSHPublicKeys) >= 1 {
t.PublicKey = fi.WrapResource(fi.NewStringResource(string(b.SSHPublicKeys[0])))
}
c.AddTask(t)

View File

@ -441,13 +441,13 @@ func (c *ApplyClusterCmd) Run() error {
"spotinstElastigroup": &spotinsttasks.Elastigroup{},
})
if len(sshPublicKeys) == 0 {
if len(sshPublicKeys) == 0 && c.Cluster.Spec.SSHKeyName == "" {
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.ObjectMeta.Name)
}
modelContext.SSHPublicKeys = sshPublicKeys
if len(sshPublicKeys) != 1 {
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`")
}

View File

@ -38,7 +38,8 @@ func TestLaunchTemplateTerraformRender(t *testing.T) {
RootVolumeIops: fi.Int64(100),
RootVolumeSize: fi.Int64(64),
SSHKey: &SSHKey{
Name: fi.String("mykey"),
Name: fi.String("newkey"),
PublicKey: fi.WrapResource(fi.NewStringResource("newkey")),
},
SecurityGroups: []*SecurityGroup{
{Name: fi.String("nodes-1"), ID: fi.String("1111")},
@ -64,7 +65,7 @@ resource "aws_launch_template" "test" {
}
instance_type = "t2.medium"
key_name = "${aws_key_pair.mykey.id}"
key_name = "${aws_key_pair.newkey.id}"
network_interfaces = {
associate_public_ip_address = true
@ -141,7 +142,7 @@ resource "aws_launch_template" "test" {
}
instance_type = "t2.medium"
key_name = "${aws_key_pair.mykey.id}"
key_name = "mykey"
network_interfaces = {
associate_public_ip_address = true

View File

@ -108,6 +108,16 @@ func (e *SSHKey) Run(c *fi.Context) error {
}
glog.V(2).Infof("Computed SSH key fingerprint as %q", keyFingerprint)
e.KeyFingerprint = &keyFingerprint
} else if e.IsExistingKey() && *e.Name != "" {
a, err := e.Find(c)
if err != nil {
return err
}
if a == nil {
return fmt.Errorf("unable to find specified SSH key %q", *e.Name)
}
e.KeyFingerprint = a.KeyFingerprint
}
return fi.DefaultDeltaRunMethod(e, c)
}
@ -161,6 +171,10 @@ type terraformSSHKey struct {
}
func (_ *SSHKey) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *SSHKey) error {
// We don't want to render a key definition when we're using one that already exists
if e.IsExistingKey() {
return nil
}
tfName := strings.Replace(*e.Name, ":", "", -1)
publicKey, err := t.AddFile("aws_key_pair", tfName, "public_key", e.PublicKey)
if err != nil {
@ -175,7 +189,16 @@ func (_ *SSHKey) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *SS
return t.RenderResource("aws_key_pair", tfName, tf)
}
// IsExistingKey will be true if the task has been initialized without using a public key
// this is when we want to use a key that is already present in AWS.
func (e *SSHKey) IsExistingKey() bool {
return e.PublicKey == nil
}
func (e *SSHKey) TerraformLink() *terraform.Literal {
if e.IsExistingKey() {
return terraform.LiteralFromStringValue(*e.Name)
}
tfName := strings.Replace(*e.Name, ":", "", -1)
return terraform.LiteralProperty("aws_key_pair", tfName, "id")
}