Skip to content

Commit

Permalink
creates temporal ssh-key for DO provider as it is mandatory (#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
p0lyn0mial authored Mar 2, 2018
1 parent 5b01557 commit 619e58e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 79 deletions.
80 changes: 39 additions & 41 deletions pkg/cloudprovider/provider/digitalocean/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,40 @@ package digitalocean

import (
"context"
"crypto/rand"
"crypto/rsa"
"encoding/json"
"errors"
"fmt"
"net/http"
"strconv"
"sync"
"time"

"github.com/digitalocean/godo"
"github.com/golang/glog"
"golang.org/x/crypto/ssh"
"golang.org/x/oauth2"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"

"github.com/kubermatic/machine-controller/pkg/cloudprovider/cloud"
cloudprovidererrors "github.com/kubermatic/machine-controller/pkg/cloudprovider/errors"
"github.com/kubermatic/machine-controller/pkg/cloudprovider/instance"
"github.com/kubermatic/machine-controller/pkg/machines/v1alpha1"
"github.com/kubermatic/machine-controller/pkg/providerconfig"
machinessh "github.com/kubermatic/machine-controller/pkg/ssh"
"github.com/pborman/uuid"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
)

const privateRSAKeyBitSize = 4096

type provider struct {
// TODO(p0lyn0mial): remove privateKey
privateKey *machinessh.PrivateKey
configVarResolver *providerconfig.ConfigVarResolver
}

// New returns a digitalocean provider
func New(configVarResolver *providerconfig.ConfigVarResolver) cloud.Provider {
return &provider{privateKey: nil, configVarResolver: configVarResolver}
return &provider{configVarResolver: configVarResolver}
}

type RawConfig struct {
Expand Down Expand Up @@ -66,9 +66,6 @@ const (
createCheckFailedWaitPeriod = 10 * time.Second
)

// Protects creation of public key
var publicKeyCreationLock = &sync.Mutex{}

type TokenSource struct {
AccessToken string
}
Expand Down Expand Up @@ -230,33 +227,29 @@ func (p *provider) Validate(spec v1alpha1.MachineSpec) error {
return nil
}

func ensureSSHKeysExist(ctx context.Context, service godo.KeysService, key *machinessh.PrivateKey) (string, error) {
publicKeyCreationLock.Lock()
defer publicKeyCreationLock.Unlock()

publicKey := key.PublicKey()
pk, err := ssh.NewPublicKey(&publicKey)
// uploadSSHPublicKey uploads public part of the key to digital ocean
// this method returns an error if the key already exists
func uploadSSHPublicKey(ctx context.Context, service godo.KeysService, key *rsa.PublicKey) (string, error) {
pk, err := ssh.NewPublicKey(key)
if err != nil {
return "", fmt.Errorf("failed to parse publickey: %v", err)
}

fingerprint := ssh.FingerprintLegacyMD5(pk)
dokey, res, err := service.GetByFingerprint(ctx, fingerprint)
existingkey, res, err := service.GetByFingerprint(ctx, fingerprint)
if err == nil && existingkey != nil && res.StatusCode >= http.StatusOK && res.StatusCode <= http.StatusAccepted {
return "", fmt.Errorf("failed to create ssh public key, the key already exists")
}

newDoKey, _, err := service.Create(ctx, &godo.KeyCreateRequest{
PublicKey: string(ssh.MarshalAuthorizedKey(pk)),
Name: string(uuid.NewUUID()),
})
if err != nil {
if res != nil && res.StatusCode == http.StatusNotFound {
dokey, _, err = service.Create(ctx, &godo.KeyCreateRequest{
PublicKey: string(ssh.MarshalAuthorizedKey(pk)),
Name: key.Name(),
})
if err != nil {
return "", fmt.Errorf("failed to create ssh public key on digitalocean: %v", err)
}
return dokey.Fingerprint, nil
}
return "", fmt.Errorf("failed to get key from digitalocean: %v", err)
return "", fmt.Errorf("failed to create ssh public key on digitalocean: %v", err)
}

return dokey.Fingerprint, nil
return newDoKey.Fingerprint, nil
}

func (p *provider) Create(machine *v1alpha1.Machine, userdata string) (instance.Instance, error) {
Expand All @@ -268,19 +261,24 @@ func (p *provider) Create(machine *v1alpha1.Machine, userdata string) (instance.
ctx := context.TODO()
client := getClient(c.Token)

// TODO(p0lyn0mial): an ssh-key should be created only if the CoreOS was requested
// TODO(p0lyn0mial): an ssh-key must be temporal - deleted after an instance has been created.
if p.privateKey == nil {
var err error
p.privateKey, err = machinessh.NewPrivateKey("machine-controller")
if err != nil {
return nil, err
}
tmpRSAKeyPair, err := rsa.GenerateKey(rand.Reader, privateRSAKeyBitSize)
if err != nil {
return nil, fmt.Errorf("failed to create private RSA key: %v", err)
}

if err := tmpRSAKeyPair.Validate(); err != nil {
return nil, fmt.Errorf("failed to validate private RSA key: %v", err)
}
fingerprint, err := ensureSSHKeysExist(ctx, client.Keys, p.privateKey)
fingerprint, err := uploadSSHPublicKey(ctx, client.Keys, &tmpRSAKeyPair.PublicKey)
if err != nil {
return nil, fmt.Errorf("failed ensure that the ssh key '%s' exists: %v", p.privateKey.Name(), err)
return nil, fmt.Errorf("failed upload the ssh key, error = %v", err)
}
defer func() {
_, err := client.Keys.DeleteByFingerprint(ctx, fingerprint)
if err != nil {
glog.Errorf("failed to remove a temporary ssh key with fingerprint = %v, due to = %v", fingerprint, err)
}
}()

slug, err := getSlugForOS(pc.OperatingSystem)
if err != nil {
Expand Down
2 changes: 0 additions & 2 deletions pkg/controller/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import (
"github.com/kubermatic/machine-controller/pkg/containerruntime/docker"
machinev1alpha1 "github.com/kubermatic/machine-controller/pkg/machines/v1alpha1"
"github.com/kubermatic/machine-controller/pkg/providerconfig"
"github.com/kubermatic/machine-controller/pkg/ssh"
"github.com/kubermatic/machine-controller/pkg/userdata"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -78,7 +77,6 @@ type Controller struct {

workqueue workqueue.RateLimitingInterface

sshPrivateKey *ssh.PrivateKey
clusterDNSIPs []net.IP
metrics MetricsCollection
kubeconfigProvider KubeconfigProvider
Expand Down
36 changes: 0 additions & 36 deletions pkg/ssh/key.go

This file was deleted.

0 comments on commit 619e58e

Please sign in to comment.