From 5359842b917f998c567553c4d3b0e9a56f29effb Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Wed, 5 Dec 2018 15:38:48 -0500 Subject: [PATCH] Fix node join post-1.13 (#446) --- .gitignore | 1 + .../aws/services/certificates/certificates.go | 14 +++++++++ pkg/cloud/aws/services/ec2/BUILD | 1 + pkg/cloud/aws/services/ec2/instances.go | 29 ++++++++++--------- pkg/cloud/aws/services/userdata/node.go | 22 ++------------ 5 files changed, 35 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index abdd0a91f5..5083208fcb 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ envfile # kubeconfigs +kind.kubeconfig minikube.kubeconfig kubeconfig diff --git a/pkg/cloud/aws/services/certificates/certificates.go b/pkg/cloud/aws/services/certificates/certificates.go index a55d41bab7..9c9c2c8cee 100644 --- a/pkg/cloud/aws/services/certificates/certificates.go +++ b/pkg/cloud/aws/services/certificates/certificates.go @@ -16,13 +16,16 @@ package certificates import ( "crypto/rand" "crypto/rsa" + "crypto/sha256" "crypto/x509" "crypto/x509/pkix" + "encoding/hex" "encoding/pem" "fmt" "math" "math/big" "net" + "strings" "time" "github.com/pkg/errors" @@ -222,3 +225,14 @@ func DecodePrivateKeyPEM(encoded []byte) (*rsa.PrivateKey, error) { return x509.ParsePKCS1PrivateKey(block.Bytes) } + +// GenerateCertificateHash returns the encoded sha256 hash for the certificate provided +func GenerateCertificateHash(encoded []byte) (string, error) { + cert, err := DecodeCertPEM(encoded) + if err != nil || cert == nil { + return "", errors.Errorf("failed to parse PEM block containing the public key") + } + + certHash := sha256.Sum256(cert.RawSubjectPublicKeyInfo) + return "sha256:" + strings.ToLower(hex.EncodeToString(certHash[:])), nil +} diff --git a/pkg/cloud/aws/services/ec2/BUILD b/pkg/cloud/aws/services/ec2/BUILD index f2f13808d1..31603f3e7c 100644 --- a/pkg/cloud/aws/services/ec2/BUILD +++ b/pkg/cloud/aws/services/ec2/BUILD @@ -26,6 +26,7 @@ go_library( "//pkg/cloud/aws/converters:go_default_library", "//pkg/cloud/aws/filter:go_default_library", "//pkg/cloud/aws/services/awserrors:go_default_library", + "//pkg/cloud/aws/services/certificates:go_default_library", "//pkg/cloud/aws/services/userdata:go_default_library", "//pkg/cloud/aws/services/wait:go_default_library", "//pkg/cloud/aws/tags:go_default_library", diff --git a/pkg/cloud/aws/services/ec2/instances.go b/pkg/cloud/aws/services/ec2/instances.go index 8549235b0d..94bb9a357b 100644 --- a/pkg/cloud/aws/services/ec2/instances.go +++ b/pkg/cloud/aws/services/ec2/instances.go @@ -16,21 +16,19 @@ package ec2 import ( "encoding/base64" - "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/actuators" - "sigs.k8s.io/cluster-api-provider-aws/pkg/record" - - "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/filter" - "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/tags" - - "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/converters" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/pkg/errors" "k8s.io/klog" "sigs.k8s.io/cluster-api-provider-aws/pkg/apis/awsprovider/v1alpha1" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/actuators" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/converters" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/filter" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/services/awserrors" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/services/certificates" "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/services/userdata" + "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/aws/tags" + "sigs.k8s.io/cluster-api-provider-aws/pkg/record" ) // InstanceByTags returns the existing instance or nothing if it doesn't exist. @@ -90,7 +88,7 @@ func (s *Service) InstanceIfExists(id string) (*v1alpha1.Instance, error) { } // createInstance runs an ec2 instance. -func (s *Service) createInstance(machine *actuators.MachineScope, token string) (*v1alpha1.Instance, error) { +func (s *Service) createInstance(machine *actuators.MachineScope, bootstrapToken string) (*v1alpha1.Instance, error) { klog.V(2).Infof("Creating a new instance for machine %q", machine.Name()) input := &v1alpha1.Instance{ @@ -174,9 +172,14 @@ func (s *Service) createInstance(machine *actuators.MachineScope, token string) if machine.Role() == "node" { input.SecurityGroupIDs = append(input.SecurityGroupIDs, s.scope.SecurityGroups()[v1alpha1.SecurityGroupNode].ID) + caCertHash, err := certificates.GenerateCertificateHash(s.scope.ClusterConfig.CACertificate) + if err != nil { + return input, err + } + userData, err := userdata.NewNode(&userdata.NodeInput{ - CACert: string(s.scope.ClusterConfig.CACertificate), - BootstrapToken: token, + CACertHash: caCertHash, + BootstrapToken: bootstrapToken, ELBAddress: s.scope.Network().APIServerELB.DNSName, }) @@ -242,7 +245,7 @@ func (s *Service) TerminateInstanceAndWait(instanceID string) error { } // CreateOrGetMachine will either return an existing instance or create and return an instance. -func (s *Service) CreateOrGetMachine(machine *actuators.MachineScope, token string) (*v1alpha1.Instance, error) { +func (s *Service) CreateOrGetMachine(machine *actuators.MachineScope, bootstrapToken string) (*v1alpha1.Instance, error) { klog.V(2).Infof("Attempting to create or get machine %q", machine.Name()) // instance id exists, try to get it @@ -265,7 +268,7 @@ func (s *Service) CreateOrGetMachine(machine *actuators.MachineScope, token stri return instance, nil } - return s.createInstance(machine, token) + return s.createInstance(machine, bootstrapToken) } func (s *Service) runInstance(role string, i *v1alpha1.Instance) (*v1alpha1.Instance, error) { diff --git a/pkg/cloud/aws/services/userdata/node.go b/pkg/cloud/aws/services/userdata/node.go index 160453d89f..db9f6e1f87 100644 --- a/pkg/cloud/aws/services/userdata/node.go +++ b/pkg/cloud/aws/services/userdata/node.go @@ -16,22 +16,6 @@ package userdata const ( nodeBashScript = `{{.Header}} -certificate=$(echo '{{.CACert}}' | base64 -w0) - -cat >/tmp/cluster-info.yaml </tmp/kubeadm-node.yaml <