88 lines
2.3 KiB
Go
88 lines
2.3 KiB
Go
package cert
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/docker/machine/libmachine/auth"
|
|
"github.com/docker/machine/libmachine/log"
|
|
"github.com/docker/machine/libmachine/mcnutils"
|
|
)
|
|
|
|
func BootstrapCertificates(authOptions *auth.Options) error {
|
|
certDir := authOptions.CertDir
|
|
caCertPath := authOptions.CaCertPath
|
|
caPrivateKeyPath := authOptions.CaPrivateKeyPath
|
|
clientCertPath := authOptions.ClientCertPath
|
|
clientKeyPath := authOptions.ClientKeyPath
|
|
|
|
// TODO: I'm not super happy about this use of "org", the user should
|
|
// have to specify it explicitly instead of implicitly basing it on
|
|
// $USER.
|
|
caOrg := mcnutils.GetUsername()
|
|
org := caOrg + ".<bootstrap>"
|
|
|
|
bits := 2048
|
|
|
|
if _, err := os.Stat(certDir); err != nil {
|
|
if os.IsNotExist(err) {
|
|
if err := os.MkdirAll(certDir, 0700); err != nil {
|
|
return fmt.Errorf("Creating machine certificate dir failed: %s", err)
|
|
}
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if _, err := os.Stat(caCertPath); os.IsNotExist(err) {
|
|
log.Infof("Creating CA: %s", caCertPath)
|
|
|
|
// check if the key path exists; if so, error
|
|
if _, err := os.Stat(caPrivateKeyPath); err == nil {
|
|
return errors.New("certificate authority key already exists")
|
|
}
|
|
|
|
if err := GenerateCACertificate(caCertPath, caPrivateKeyPath, caOrg, bits); err != nil {
|
|
return fmt.Errorf("Generating CA certificate failed: %s", err)
|
|
}
|
|
}
|
|
|
|
if _, err := os.Stat(clientCertPath); os.IsNotExist(err) {
|
|
log.Infof("Creating client certificate: %s", clientCertPath)
|
|
|
|
if _, err := os.Stat(certDir); err != nil {
|
|
if os.IsNotExist(err) {
|
|
if err := os.Mkdir(certDir, 0700); err != nil {
|
|
return fmt.Errorf("failure creating machine client cert dir: %s", err)
|
|
}
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// check if the key path exists; if so, error
|
|
if _, err := os.Stat(clientKeyPath); err == nil {
|
|
return errors.New("client key already exists")
|
|
}
|
|
|
|
// Used to generate the client certificate.
|
|
certOptions := &Options{
|
|
Hosts: []string{""},
|
|
CertFile: clientCertPath,
|
|
KeyFile: clientKeyPath,
|
|
CAFile: caCertPath,
|
|
CAKeyFile: caPrivateKeyPath,
|
|
Org: org,
|
|
Bits: bits,
|
|
SwarmMaster: false,
|
|
}
|
|
|
|
if err := GenerateCert(certOptions); err != nil {
|
|
return fmt.Errorf("failure generating client certificate: %s", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|