diff --git a/api/v1alpha3/azuremachine_default.go b/api/v1alpha3/azuremachine_default.go index af5114feda5..b1eb67ba09d 100644 --- a/api/v1alpha3/azuremachine_default.go +++ b/api/v1alpha3/azuremachine_default.go @@ -17,27 +17,22 @@ limitations under the License. package v1alpha3 import ( - "crypto/rand" - "crypto/rsa" "encoding/base64" - "github.com/pkg/errors" "golang.org/x/crypto/ssh" + + utilSSH "sigs.k8s.io/cluster-api-provider-azure/util/ssh" ) // SetDefaultSSHPublicKey sets the default SSHPublicKey for an AzureMachine func (m *AzureMachine) SetDefaultSSHPublicKey() error { sshKeyData := m.Spec.SSHPublicKey if sshKeyData == "" { - privateKey, perr := rsa.GenerateKey(rand.Reader, 2048) - if perr != nil { - return errors.Wrap(perr, "Failed to generate private key") + _, publicRsaKey, err := utilSSH.GenerateSSHKey() + if err != nil { + return err } - publicRsaKey, perr := ssh.NewPublicKey(&privateKey.PublicKey) - if perr != nil { - return errors.Wrap(perr, "Failed to generate public key") - } m.Spec.SSHPublicKey = base64.StdEncoding.EncodeToString(ssh.MarshalAuthorizedKey(publicRsaKey)) } diff --git a/exp/api/v1alpha3/azuremachinepool_default.go b/exp/api/v1alpha3/azuremachinepool_default.go index ac361ee0629..d2e64e4d56d 100644 --- a/exp/api/v1alpha3/azuremachinepool_default.go +++ b/exp/api/v1alpha3/azuremachinepool_default.go @@ -17,27 +17,22 @@ limitations under the License. package v1alpha3 import ( - "crypto/rand" - "crypto/rsa" "encoding/base64" - "github.com/pkg/errors" "golang.org/x/crypto/ssh" + + utilSSH "sigs.k8s.io/cluster-api-provider-azure/util/ssh" ) // SetDefaultSSHPublicKey sets the default SSHPublicKey for an AzureMachinePool func (amp *AzureMachinePool) SetDefaultSSHPublicKey() error { sshKeyData := amp.Spec.Template.SSHPublicKey if sshKeyData == "" { - privateKey, perr := rsa.GenerateKey(rand.Reader, 2048) - if perr != nil { - return errors.Wrap(perr, "Failed to generate private key") + _, publicRsaKey, err := utilSSH.GenerateSSHKey() + if err != nil { + return err } - publicRsaKey, perr := ssh.NewPublicKey(&privateKey.PublicKey) - if perr != nil { - return errors.Wrap(perr, "Failed to generate public key") - } amp.Spec.Template.SSHPublicKey = base64.StdEncoding.EncodeToString(ssh.MarshalAuthorizedKey(publicRsaKey)) } diff --git a/exp/api/v1alpha3/azuremanagedcontrolplane_default.go b/exp/api/v1alpha3/azuremanagedcontrolplane_default.go index aec61137c84..6939d1c56a4 100644 --- a/exp/api/v1alpha3/azuremanagedcontrolplane_default.go +++ b/exp/api/v1alpha3/azuremanagedcontrolplane_default.go @@ -17,27 +17,22 @@ limitations under the License. package v1alpha3 import ( - "crypto/rand" - "crypto/rsa" "encoding/base64" - "github.com/pkg/errors" "golang.org/x/crypto/ssh" + + utilSSH "sigs.k8s.io/cluster-api-provider-azure/util/ssh" ) // SetDefaultSSHPublicKey sets the default SSHPublicKey for an AzureManagedControlPlane func (r *AzureManagedControlPlane) SetDefaultSSHPublicKey() error { sshKeyData := r.Spec.SSHPublicKey if sshKeyData == "" { - privateKey, perr := rsa.GenerateKey(rand.Reader, 2048) - if perr != nil { - return errors.Wrap(perr, "Failed to generate private key") + _, publicRsaKey, err := utilSSH.GenerateSSHKey() + if err != nil { + return err } - publicRsaKey, perr := ssh.NewPublicKey(&privateKey.PublicKey) - if perr != nil { - return errors.Wrap(perr, "Failed to generate public key") - } r.Spec.SSHPublicKey = base64.StdEncoding.EncodeToString(ssh.MarshalAuthorizedKey(publicRsaKey)) } diff --git a/templates/flavors/aks/cluster-template.yaml b/templates/flavors/aks/cluster-template.yaml index 2e2f0be72dc..febfd9e5310 100644 --- a/templates/flavors/aks/cluster-template.yaml +++ b/templates/flavors/aks/cluster-template.yaml @@ -33,7 +33,7 @@ spec: location: "${AZURE_LOCATION}" defaultPoolRef: name: "agentpool0" - sshPublicKey: "${AZURE_SSH_PUBLIC_KEY_B64}" + sshPublicKey: ${AZURE_SSH_PUBLIC_KEY_B64:=""} version: "${KUBERNETES_VERSION}" --- # Due to the nature of managed Kubernetes and the control plane implementation, diff --git a/util/ssh/ssh.go b/util/ssh/ssh.go new file mode 100644 index 00000000000..80c4b94cfe8 --- /dev/null +++ b/util/ssh/ssh.go @@ -0,0 +1,40 @@ +/* +Copyright 2020 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 ssh + +import ( + "crypto/rand" + "crypto/rsa" + + "github.com/pkg/errors" + "golang.org/x/crypto/ssh" +) + +// GenerateSSHKey generates a private and public ssh key +func GenerateSSHKey() (*rsa.PrivateKey, ssh.PublicKey, error) { + privateKey, perr := rsa.GenerateKey(rand.Reader, 2048) + if perr != nil { + return nil, nil, errors.Wrap(perr, "Failed to generate private key") + } + + publicRsaKey, perr := ssh.NewPublicKey(&privateKey.PublicKey) + if perr != nil { + return nil, nil, errors.Wrap(perr, "Failed to generate public key") + } + + return privateKey, publicRsaKey, nil +} diff --git a/util/ssh/ssh_test.go b/util/ssh/ssh_test.go new file mode 100644 index 00000000000..ec67f3027ab --- /dev/null +++ b/util/ssh/ssh_test.go @@ -0,0 +1,32 @@ +/* +Copyright 2020 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 ssh + +import ( + "testing" + + . "github.com/onsi/gomega" +) + +func TestGenerateSSHKey(t *testing.T) { + g := NewWithT(t) + + privateKey, publicKey, err := GenerateSSHKey() + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(privateKey).NotTo(BeNil()) + g.Expect(publicKey).NotTo(BeNil()) +}