Generate two certs and two private keys; only the necessary ones; make the certs…

Generate two certs and two private keys; only the necessary ones; make the certs and kubeconfig phases work with valid files already on-disk and some cleanup
parent 741b0b8c
...@@ -32,6 +32,7 @@ filegroup( ...@@ -32,6 +32,7 @@ filegroup(
":package-srcs", ":package-srcs",
"//cmd/kubeadm/app/apis/kubeadm:all-srcs", "//cmd/kubeadm/app/apis/kubeadm:all-srcs",
"//cmd/kubeadm/app/cmd:all-srcs", "//cmd/kubeadm/app/cmd:all-srcs",
"//cmd/kubeadm/app/constants:all-srcs",
"//cmd/kubeadm/app/discovery:all-srcs", "//cmd/kubeadm/app/discovery:all-srcs",
"//cmd/kubeadm/app/images:all-srcs", "//cmd/kubeadm/app/images:all-srcs",
"//cmd/kubeadm/app/master:all-srcs", "//cmd/kubeadm/app/master:all-srcs",
......
...@@ -191,7 +191,7 @@ func (i *Init) Validate() error { ...@@ -191,7 +191,7 @@ func (i *Init) Validate() error {
func (i *Init) Run(out io.Writer) error { func (i *Init) Run(out io.Writer) error {
// PHASE 1: Generate certificates // PHASE 1: Generate certificates
caCert, err := certphase.CreatePKIAssets(i.cfg, kubeadmapi.GlobalEnvParams.HostPKIPath) err := certphase.CreatePKIAssets(i.cfg, kubeadmapi.GlobalEnvParams.HostPKIPath)
if err != nil { if err != nil {
return err return err
} }
...@@ -249,7 +249,7 @@ func (i *Init) Run(out io.Writer) error { ...@@ -249,7 +249,7 @@ func (i *Init) Run(out io.Writer) error {
if i.cfg.Discovery.Token != nil { if i.cfg.Discovery.Token != nil {
fmt.Printf("[token-discovery] Using token: %s\n", kubeadmutil.BearerToken(i.cfg.Discovery.Token)) fmt.Printf("[token-discovery] Using token: %s\n", kubeadmutil.BearerToken(i.cfg.Discovery.Token))
if err := kubemaster.CreateDiscoveryDeploymentAndSecret(i.cfg, client, caCert); err != nil { if err := kubemaster.CreateDiscoveryDeploymentAndSecret(i.cfg, client); err != nil {
return err return err
} }
if err := kubeadmutil.UpdateOrCreateToken(client, i.cfg.Discovery.Token, kubeadmutil.DefaultTokenDuration); err != nil { if err := kubeadmutil.UpdateOrCreateToken(client, i.cfg.Discovery.Token, kubeadmutil.DefaultTokenDuration); err != nil {
......
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["constants.go"],
tags = ["automanaged"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
/*
Copyright 2016 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 constants
const (
CACertAndKeyBaseName = "ca"
CACertName = "ca.crt"
CAKeyName = "ca.key"
APIServerCertAndKeyBaseName = "apiserver"
APIServerCertName = "apiserver.crt"
APIServerKeyName = "apiserver.key"
)
...@@ -22,6 +22,7 @@ go_library( ...@@ -22,6 +22,7 @@ go_library(
deps = [ deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/images:go_default_library", "//cmd/kubeadm/app/images:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library", "//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util:go_default_library",
......
...@@ -36,6 +36,7 @@ import ( ...@@ -36,6 +36,7 @@ import (
const apiCallRetryInterval = 500 * time.Millisecond const apiCallRetryInterval = 500 * time.Millisecond
// TODO: This method shouldn't exist as a standalone function but be integrated into CreateClientFromFile
func createAPIClient(adminKubeconfig *clientcmdapi.Config) (*clientset.Clientset, error) { func createAPIClient(adminKubeconfig *clientcmdapi.Config) (*clientset.Clientset, error) {
adminClientConfig, err := clientcmd.NewDefaultClientConfig( adminClientConfig, err := clientcmd.NewDefaultClientConfig(
*adminKubeconfig, *adminKubeconfig,
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/images" "k8s.io/kubernetes/cmd/kubeadm/app/images"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
api "k8s.io/kubernetes/pkg/api/v1" api "k8s.io/kubernetes/pkg/api/v1"
...@@ -301,6 +302,10 @@ func getComponentBaseCommand(component string) []string { ...@@ -301,6 +302,10 @@ func getComponentBaseCommand(component string) []string {
return []string{"kube-" + component} return []string{"kube-" + component}
} }
func getCertFilePath(certName string) string {
return path.Join(kubeadmapi.GlobalEnvParams.HostPKIPath, certName)
}
func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) []string { func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) []string {
var command []string var command []string
...@@ -313,10 +318,10 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) [ ...@@ -313,10 +318,10 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) [
"--insecure-bind-address=127.0.0.1", "--insecure-bind-address=127.0.0.1",
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota", "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
"--service-cluster-ip-range="+cfg.Networking.ServiceSubnet, "--service-cluster-ip-range="+cfg.Networking.ServiceSubnet,
"--service-account-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem", "--service-account-key-file="+getCertFilePath(kubeadmconstants.APIServerKeyName),
"--client-ca-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem", "--client-ca-file="+getCertFilePath(kubeadmconstants.CACertName),
"--tls-cert-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver.pem", "--tls-cert-file="+getCertFilePath(kubeadmconstants.APIServerCertName),
"--tls-private-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem", "--tls-private-key-file="+getCertFilePath(kubeadmconstants.APIServerKeyName),
"--token-auth-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/tokens.csv", "--token-auth-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/tokens.csv",
fmt.Sprintf("--secure-port=%d", cfg.API.Port), fmt.Sprintf("--secure-port=%d", cfg.API.Port),
"--allow-privileged", "--allow-privileged",
...@@ -400,10 +405,10 @@ func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted ...@@ -400,10 +405,10 @@ func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted
"--leader-elect", "--leader-elect",
"--master=127.0.0.1:8080", "--master=127.0.0.1:8080",
"--cluster-name="+DefaultClusterName, "--cluster-name="+DefaultClusterName,
"--root-ca-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem", "--root-ca-file="+getCertFilePath(kubeadmconstants.CACertName),
"--service-account-private-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem", "--service-account-private-key-file="+getCertFilePath(kubeadmconstants.APIServerKeyName),
"--cluster-signing-cert-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem", "--cluster-signing-cert-file="+getCertFilePath(kubeadmconstants.CACertName),
"--cluster-signing-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca-key.pem", "--cluster-signing-key-file="+getCertFilePath(kubeadmconstants.CAKeyName),
"--insecure-experimental-approve-all-kubelet-csrs-for-group="+KubeletBootstrapGroup, "--insecure-experimental-approve-all-kubelet-csrs-for-group="+KubeletBootstrapGroup,
) )
......
...@@ -372,10 +372,10 @@ func TestGetAPIServerCommand(t *testing.T) { ...@@ -372,10 +372,10 @@ func TestGetAPIServerCommand(t *testing.T) {
"--insecure-bind-address=127.0.0.1", "--insecure-bind-address=127.0.0.1",
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota", "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
"--service-cluster-ip-range=bar", "--service-cluster-ip-range=bar",
"--service-account-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.pem", "--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
"--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv", "--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv",
fmt.Sprintf("--secure-port=%d", 123), fmt.Sprintf("--secure-port=%d", 123),
"--allow-privileged", "--allow-privileged",
...@@ -392,10 +392,10 @@ func TestGetAPIServerCommand(t *testing.T) { ...@@ -392,10 +392,10 @@ func TestGetAPIServerCommand(t *testing.T) {
"--insecure-bind-address=127.0.0.1", "--insecure-bind-address=127.0.0.1",
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota", "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
"--service-cluster-ip-range=bar", "--service-cluster-ip-range=bar",
"--service-account-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.pem", "--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
"--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv", "--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv",
fmt.Sprintf("--secure-port=%d", 123), fmt.Sprintf("--secure-port=%d", 123),
"--allow-privileged", "--allow-privileged",
...@@ -414,10 +414,10 @@ func TestGetAPIServerCommand(t *testing.T) { ...@@ -414,10 +414,10 @@ func TestGetAPIServerCommand(t *testing.T) {
"--insecure-bind-address=127.0.0.1", "--insecure-bind-address=127.0.0.1",
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota", "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
"--service-cluster-ip-range=bar", "--service-cluster-ip-range=bar",
"--service-account-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.pem", "--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
"--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv", "--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv",
fmt.Sprintf("--secure-port=%d", 123), fmt.Sprintf("--secure-port=%d", 123),
"--allow-privileged", "--allow-privileged",
...@@ -438,10 +438,10 @@ func TestGetAPIServerCommand(t *testing.T) { ...@@ -438,10 +438,10 @@ func TestGetAPIServerCommand(t *testing.T) {
"--insecure-bind-address=127.0.0.1", "--insecure-bind-address=127.0.0.1",
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota", "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
"--service-cluster-ip-range=bar", "--service-cluster-ip-range=bar",
"--service-account-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.pem", "--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
"--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv", "--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv",
fmt.Sprintf("--secure-port=%d", 123), fmt.Sprintf("--secure-port=%d", 123),
"--allow-privileged", "--allow-privileged",
...@@ -480,10 +480,10 @@ func TestGetControllerManagerCommand(t *testing.T) { ...@@ -480,10 +480,10 @@ func TestGetControllerManagerCommand(t *testing.T) {
"--leader-elect", "--leader-elect",
"--master=127.0.0.1:8080", "--master=127.0.0.1:8080",
"--cluster-name=" + DefaultClusterName, "--cluster-name=" + DefaultClusterName,
"--root-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--root-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca-key.pem", "--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.key",
"--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap", "--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap",
}, },
}, },
...@@ -495,10 +495,10 @@ func TestGetControllerManagerCommand(t *testing.T) { ...@@ -495,10 +495,10 @@ func TestGetControllerManagerCommand(t *testing.T) {
"--leader-elect", "--leader-elect",
"--master=127.0.0.1:8080", "--master=127.0.0.1:8080",
"--cluster-name=" + DefaultClusterName, "--cluster-name=" + DefaultClusterName,
"--root-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--root-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca-key.pem", "--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.key",
"--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap", "--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap",
"--cloud-provider=foo", "--cloud-provider=foo",
}, },
...@@ -511,10 +511,10 @@ func TestGetControllerManagerCommand(t *testing.T) { ...@@ -511,10 +511,10 @@ func TestGetControllerManagerCommand(t *testing.T) {
"--leader-elect", "--leader-elect",
"--master=127.0.0.1:8080", "--master=127.0.0.1:8080",
"--cluster-name=" + DefaultClusterName, "--cluster-name=" + DefaultClusterName,
"--root-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--root-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
"--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
"--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca-key.pem", "--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.key",
"--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap", "--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap",
"--allocate-node-cidrs=true", "--allocate-node-cidrs=true",
"--cluster-cidr=bar", "--cluster-cidr=bar",
......
...@@ -10,10 +10,7 @@ load( ...@@ -10,10 +10,7 @@ load(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = ["certs_test.go"],
"certs_test.go",
"pki_helpers_test.go",
],
library = ":go_default_library", library = ":go_default_library",
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
...@@ -27,12 +24,14 @@ go_library( ...@@ -27,12 +24,14 @@ go_library(
srcs = [ srcs = [
"certs.go", "certs.go",
"doc.go", "doc.go",
"pki_helpers.go",
], ],
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
"//pkg/registry/core/service/ipallocator:go_default_library", "//pkg/registry/core/service/ipallocator:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/client-go/pkg/util/cert", "//vendor:k8s.io/client-go/pkg/util/cert",
], ],
) )
...@@ -46,6 +45,9 @@ filegroup( ...@@ -46,6 +45,9 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [":package-srcs"], srcs = [
":package-srcs",
"//cmd/kubeadm/app/phases/certs/pkiutil:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
) )
...@@ -17,21 +17,30 @@ limitations under the License. ...@@ -17,21 +17,30 @@ limitations under the License.
package certs package certs
import ( import (
"crypto/rsa"
"crypto/x509" "crypto/x509"
"fmt" "fmt"
"net" "net"
"os" "os"
setutil "k8s.io/apimachinery/pkg/util/sets"
certutil "k8s.io/client-go/pkg/util/cert" certutil "k8s.io/client-go/pkg/util/cert"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator" "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
) )
// TODO: Integration test cases
// no files exist => create all four files
// valid ca.{crt,key} exists => create apiserver.{crt,key}
// valid ca.{crt,key} and apiserver.{crt,key} exists => do nothing
// invalid ca.{crt,key} exists => error
// only one of the .crt or .key file exists => error
// CreatePKIAssets will create and write to disk all PKI assets necessary to establish the control plane. // CreatePKIAssets will create and write to disk all PKI assets necessary to establish the control plane.
// It first generates a self-signed CA certificate, a server certificate (signed by the CA) and a key for // It generates a self-signed CA certificate and a server certificate (signed by the CA)
// signing service account tokens. It returns CA key and certificate, which is convenient for use with func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiDir string) error {
// client config funcs.
func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiPath string) (*x509.Certificate, error) {
altNames := certutil.AltNames{} altNames := certutil.AltNames{}
// First, define all domains this cert should be signed for // First, define all domains this cert should be signed for
...@@ -43,7 +52,7 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiPath string) (*x509 ...@@ -43,7 +52,7 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiPath string) (*x509
} }
hostname, err := os.Hostname() hostname, err := os.Hostname()
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't get the hostname: %v", err) return fmt.Errorf("couldn't get the hostname: %v", err)
} }
altNames.DNSNames = append(cfg.API.ExternalDNSNames, hostname) altNames.DNSNames = append(cfg.API.ExternalDNSNames, hostname)
altNames.DNSNames = append(altNames.DNSNames, internalAPIServerFQDN...) altNames.DNSNames = append(altNames.DNSNames, internalAPIServerFQDN...)
...@@ -53,50 +62,107 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiPath string) (*x509 ...@@ -53,50 +62,107 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration, pkiPath string) (*x509
if ip := net.ParseIP(a); ip != nil { if ip := net.ParseIP(a); ip != nil {
altNames.IPs = append(altNames.IPs, ip) altNames.IPs = append(altNames.IPs, ip)
} else { } else {
return nil, fmt.Errorf("could not parse ip %q", a) return fmt.Errorf("could not parse ip %q", a)
} }
} }
// and lastly, extract the internal IP address for the API server // and lastly, extract the internal IP address for the API server
_, n, err := net.ParseCIDR(cfg.Networking.ServiceSubnet) _, n, err := net.ParseCIDR(cfg.Networking.ServiceSubnet)
if err != nil { if err != nil {
return nil, fmt.Errorf("error parsing CIDR %q: %v", cfg.Networking.ServiceSubnet, err) return fmt.Errorf("error parsing CIDR %q: %v", cfg.Networking.ServiceSubnet, err)
} }
internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(n, 1) internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(n, 1)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to allocate IP address for the API server from the given CIDR (%q) [%v]", &cfg.Networking.ServiceSubnet, err) return fmt.Errorf("unable to allocate IP address for the API server from the given CIDR (%q) [%v]", &cfg.Networking.ServiceSubnet, err)
} }
altNames.IPs = append(altNames.IPs, internalAPIServerVirtualIP) altNames.IPs = append(altNames.IPs, internalAPIServerVirtualIP)
caKey, caCert, err := newCertificateAuthority() var caCert *x509.Certificate
if err != nil { var caKey *rsa.PrivateKey
return nil, fmt.Errorf("failure while creating CA keys and certificate [%v]", err) // If at least one of them exists, we should try to load them
} // In the case that only one exists, there will most likely be an error anyway
if pkiutil.CertOrKeyExist(pkiDir, kubeadmconstants.CACertAndKeyBaseName) {
// Try to load ca.crt and ca.key from the PKI directory
caCert, caKey, err = pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, kubeadmconstants.CACertAndKeyBaseName)
if err != nil || caCert == nil || caKey == nil {
return fmt.Errorf("certificate and/or key existed but they could not be loaded properly")
}
if err := writeKeysAndCert(pkiPath, "ca", caKey, caCert); err != nil { // The certificate and key could be loaded, but the certificate is not a CA
return nil, fmt.Errorf("failure while saving CA keys and certificate [%v]", err) if !caCert.IsCA {
} return fmt.Errorf("certificate and key could be loaded but the certificate is not a CA")
fmt.Println("[certificates] Generated Certificate Authority key and certificate.") }
apiKey, apiCert, err := newServerKeyAndCert(caCert, caKey, altNames) fmt.Println("[certificates] Using the existing CA certificate and key.")
if err != nil { } else {
return nil, fmt.Errorf("failure while creating API server keys and certificate [%v]", err) // The certificate and the key did NOT exist, let's generate them now
caCert, caKey, err = pkiutil.NewCertificateAuthority()
if err != nil {
return fmt.Errorf("failure while generating CA certificate and key [%v]", err)
}
if err = pkiutil.WriteCertAndKey(pkiDir, kubeadmconstants.CACertAndKeyBaseName, caCert, caKey); err != nil {
return fmt.Errorf("failure while saving CA certificate and key [%v]", err)
}
fmt.Println("[certificates] Generated CA certificate and key.")
} }
if err := writeKeysAndCert(pkiPath, "apiserver", apiKey, apiCert); err != nil { // If at least one of them exists, we should try to load them
return nil, fmt.Errorf("failure while saving API server keys and certificate [%v]", err) // In the case that only one exists, there will most likely be an error anyway
if pkiutil.CertOrKeyExist(pkiDir, kubeadmconstants.APIServerCertAndKeyBaseName) {
// Try to load ca.crt and ca.key from the PKI directory
apiCert, apiKey, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, kubeadmconstants.APIServerCertAndKeyBaseName)
if err != nil || apiCert == nil || apiKey == nil {
return fmt.Errorf("certificate and/or key existed but they could not be loaded properly")
}
fmt.Println("[certificates] Using the existing API Server certificate and key.")
} else {
// The certificate and the key did NOT exist, let's generate them now
// TODO: Add a test case to verify that this cert has the x509.ExtKeyUsageServerAuth flag
config := certutil.Config{
CommonName: "kube-apiserver",
AltNames: altNames,
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
}
apiCert, apiKey, err := pkiutil.NewCertAndKey(caCert, caKey, config)
if err != nil {
return fmt.Errorf("failure while creating API server key and certificate [%v]", err)
}
if err = pkiutil.WriteCertAndKey(pkiDir, kubeadmconstants.APIServerCertAndKeyBaseName, apiCert, apiKey); err != nil {
return fmt.Errorf("failure while saving API server certificate and key [%v]", err)
}
fmt.Println("[certificates] Generated API server certificate and key.")
} }
fmt.Println("[certificates] Generated API Server key and certificate")
// Generate a private key for service accounts fmt.Printf("[certificates] Valid certificates and keys now exist in %q\n", pkiDir)
saKey, err := certutil.NewPrivateKey()
if err != nil { return nil
return nil, fmt.Errorf("failure while creating service account signing keys [%v]", err) }
// Verify that the cert is valid for all IPs and DNS names it should be valid for
func checkAltNamesExist(IPs []net.IP, DNSNames []string, altNames certutil.AltNames) bool {
dnsset := setutil.NewString(DNSNames...)
for _, dnsNameThatShouldExist := range altNames.DNSNames {
if !dnsset.Has(dnsNameThatShouldExist) {
return false
}
} }
if err := writeKeysAndCert(pkiPath, "sa", saKey, nil); err != nil {
return nil, fmt.Errorf("failure while saving service account signing keys [%v]", err) for _, ipThatShouldExist := range altNames.IPs {
found := false
for _, ip := range IPs {
if ip.Equal(ipThatShouldExist) {
found = true
break
}
}
if !found {
return false
}
} }
fmt.Println("[certificates] Generated Service Account signing keys") return true
fmt.Printf("[certificates] Created keys and certificates in %q\n", pkiPath)
return caCert, nil
} }
...@@ -19,9 +19,11 @@ package certs ...@@ -19,9 +19,11 @@ package certs
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net"
"os" "os"
"testing" "testing"
certutil "k8s.io/client-go/pkg/util/cert"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
) )
...@@ -65,7 +67,7 @@ func TestCreatePKIAssets(t *testing.T) { ...@@ -65,7 +67,7 @@ func TestCreatePKIAssets(t *testing.T) {
}, },
} }
for _, rt := range tests { for _, rt := range tests {
_, actual := CreatePKIAssets(rt.cfg, fmt.Sprintf("%s/etc/kubernetes/pki", tmpdir)) actual := CreatePKIAssets(rt.cfg, fmt.Sprintf("%s/etc/kubernetes/pki", tmpdir))
if (actual == nil) != rt.expected { if (actual == nil) != rt.expected {
t.Errorf( t.Errorf(
"failed CreatePKIAssets with an error:\n\texpected: %t\n\t actual: %t", "failed CreatePKIAssets with an error:\n\texpected: %t\n\t actual: %t",
...@@ -75,3 +77,52 @@ func TestCreatePKIAssets(t *testing.T) { ...@@ -75,3 +77,52 @@ func TestCreatePKIAssets(t *testing.T) {
} }
} }
} }
func TestCheckAltNamesExist(t *testing.T) {
var tests = []struct {
IPs []net.IP
DNSNames []string
requiredAltNames certutil.AltNames
succeed bool
}{
{
// equal
requiredAltNames: certutil.AltNames{IPs: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("192.168.1.2")}, DNSNames: []string{"foo", "bar", "baz"}},
IPs: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("192.168.1.2")},
DNSNames: []string{"foo", "bar", "baz"},
succeed: true,
},
{
// the loaded cert has more ips than required, ok
requiredAltNames: certutil.AltNames{IPs: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("192.168.1.2")}, DNSNames: []string{"foo", "bar", "baz"}},
IPs: []net.IP{net.ParseIP("192.168.2.5"), net.ParseIP("1.1.1.1"), net.ParseIP("192.168.1.2")},
DNSNames: []string{"a", "foo", "b", "bar", "baz"},
succeed: true,
},
{
// the loaded cert doesn't have all ips
requiredAltNames: certutil.AltNames{IPs: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("192.168.2.5"), net.ParseIP("192.168.1.2")}, DNSNames: []string{"foo", "bar", "baz"}},
IPs: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("192.168.1.2")},
DNSNames: []string{"foo", "bar", "baz"},
succeed: false,
},
{
// the loaded cert doesn't have all ips
requiredAltNames: certutil.AltNames{IPs: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("192.168.1.2")}, DNSNames: []string{"foo", "bar", "b", "baz"}},
IPs: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("192.168.1.2")},
DNSNames: []string{"foo", "bar", "baz"},
succeed: false,
},
}
for _, rt := range tests {
succeeded := checkAltNamesExist(rt.IPs, rt.DNSNames, rt.requiredAltNames)
if succeeded != rt.succeed {
t.Errorf(
"failed checkAltNamesExist:\n\texpected: %t\n\t actual: %t",
rt.succeed,
succeeded,
)
}
}
}
...@@ -30,12 +30,9 @@ package certs ...@@ -30,12 +30,9 @@ package certs
OUTPUTS: OUTPUTS:
Files to PKIPath (default /etc/kubernetes/pki): Files to PKIPath (default /etc/kubernetes/pki):
- apiserver-key.pem - ca.crt
- apiserver-pub.pem - ca.key
- apiserver.pem - apiserver.crt
- ca-key.pem - apiserver.key
- ca-pub.pem
- ca.pem
- sa-key.pem
- sa-pub.pem
*/ */
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = ["pki_helpers_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = ["//vendor:k8s.io/client-go/pkg/util/cert"],
)
go_library(
name = "go_default_library",
srcs = ["pki_helpers.go"],
tags = ["automanaged"],
deps = ["//vendor:k8s.io/client-go/pkg/util/cert"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
...@@ -14,18 +14,24 @@ See the License for the specific language governing permissions and ...@@ -14,18 +14,24 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package certs package pkiutil
import ( import (
"crypto/ecdsa"
"crypto/rsa" "crypto/rsa"
"crypto/x509" "crypto/x509"
"fmt" "fmt"
"os"
"path" "path"
"time"
certutil "k8s.io/client-go/pkg/util/cert" certutil "k8s.io/client-go/pkg/util/cert"
) )
func newCertificateAuthority() (*rsa.PrivateKey, *x509.Certificate, error) { // TODO: It should be able to generate different types of private keys, at least: RSA and ECDSA (and in the future maybe Ed25519 as well)
// TODO: See if it makes sense to move this package directly to pkg/util/cert
func NewCertificateAuthority() (*x509.Certificate, *rsa.PrivateKey, error) {
key, err := certutil.NewPrivateKey() key, err := certutil.NewPrivateKey()
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("unable to create private key [%v]", err) return nil, nil, fmt.Errorf("unable to create private key [%v]", err)
...@@ -39,71 +45,101 @@ func newCertificateAuthority() (*rsa.PrivateKey, *x509.Certificate, error) { ...@@ -39,71 +45,101 @@ func newCertificateAuthority() (*rsa.PrivateKey, *x509.Certificate, error) {
return nil, nil, fmt.Errorf("unable to create self-signed certificate [%v]", err) return nil, nil, fmt.Errorf("unable to create self-signed certificate [%v]", err)
} }
return key, cert, nil return cert, key, nil
} }
func newServerKeyAndCert(caCert *x509.Certificate, caKey *rsa.PrivateKey, altNames certutil.AltNames) (*rsa.PrivateKey, *x509.Certificate, error) { func NewCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey, config certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
key, err := certutil.NewPrivateKey() key, err := certutil.NewPrivateKey()
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("unable to create private key [%v]", err) return nil, nil, fmt.Errorf("unable to create private key [%v]", err)
} }
config := certutil.Config{
CommonName: "kube-apiserver",
AltNames: altNames,
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
}
cert, err := certutil.NewSignedCert(config, key, caCert, caKey) cert, err := certutil.NewSignedCert(config, key, caCert, caKey)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("unable to sign certificate [%v]", err) return nil, nil, fmt.Errorf("unable to sign certificate [%v]", err)
} }
return key, cert, nil return cert, key, nil
} }
func NewClientKeyAndCert(config *certutil.Config, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*rsa.PrivateKey, *x509.Certificate, error) { func WriteCertAndKey(pkiPath string, name string, cert *x509.Certificate, key *rsa.PrivateKey) error {
key, err := certutil.NewPrivateKey() certificatePath, privateKeyPath := pathsForCertAndKey(pkiPath, name)
if err != nil {
return nil, nil, fmt.Errorf("unable to create private key [%v]", err) if cert == nil {
return fmt.Errorf("certificate cannot be nil when writing to file")
} }
// force usage to client usage if cert == nil {
configCopy := *config return fmt.Errorf("private key cannot be nil when writing to file")
configCopy.Usages = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth} }
cert, err := certutil.NewSignedCert(configCopy, key, caCert, caKey)
if err != nil { if err := certutil.WriteKey(privateKeyPath, certutil.EncodePrivateKeyPEM(key)); err != nil {
return nil, nil, fmt.Errorf("unable to sign certificate [%v]", err) return fmt.Errorf("unable to write private key to file %q: [%v]", privateKeyPath, err)
}
if err := certutil.WriteCert(certificatePath, certutil.EncodeCertPEM(cert)); err != nil {
return fmt.Errorf("unable to write certificate to file %q: [%v]", certificatePath, err)
}
return nil
}
// CertOrKeyExist retuns a boolean whether the cert or the key exists
func CertOrKeyExist(pkiPath, name string) bool {
certificatePath, privateKeyPath := pathsForCertAndKey(pkiPath, name)
_, certErr := os.Stat(certificatePath)
_, keyErr := os.Stat(privateKeyPath)
if os.IsNotExist(certErr) && os.IsNotExist(keyErr) {
// The cert or the key did not exist
return false
} }
return key, cert, nil // Both files exist or one of them
return true
} }
func writeKeysAndCert(pkiPath string, name string, key *rsa.PrivateKey, cert *x509.Certificate) error { // TryLoadCertAndKeyFromDisk tries to load a cert and a key from the disk and validates that they are valid
publicKeyPath, privateKeyPath, certificatePath := pathsKeysCerts(pkiPath, name) func TryLoadCertAndKeyFromDisk(pkiPath, name string) (*x509.Certificate, *rsa.PrivateKey, error) {
certificatePath, privateKeyPath := pathsForCertAndKey(pkiPath, name)
if key != nil {
if err := certutil.WriteKey(privateKeyPath, certutil.EncodePrivateKeyPEM(key)); err != nil { certs, err := certutil.CertsFromFile(certificatePath)
return fmt.Errorf("unable to write private key file (%q) [%v]", privateKeyPath, err) if err != nil {
} return nil, nil, fmt.Errorf("couldn't load the certificate file %s: %v", certificatePath, err)
if pubKey, err := certutil.EncodePublicKeyPEM(&key.PublicKey); err == nil { }
if err := certutil.WriteKey(publicKeyPath, pubKey); err != nil {
return fmt.Errorf("unable to write public key file (%q) [%v]", publicKeyPath, err) // We are only putting one certificate in the certificate pem file, so it's safe to just pick the first one
} // TODO: Support multiple certs here in order to be able to rotate certs
} else { cert := certs[0]
return fmt.Errorf("unable to encode public key to PEM [%v]", err)
} // Parse the private key from a file
privKey, err := certutil.PrivateKeyFromFile(privateKeyPath)
if err != nil {
return nil, nil, fmt.Errorf("couldn't load the private key file %s: %v", privateKeyPath, err)
}
var key *rsa.PrivateKey
switch k := privKey.(type) {
case *rsa.PrivateKey:
key = k
case *ecdsa.PrivateKey:
// TODO: Abstract rsa.PrivateKey away and make certutil.NewSignedCert accept a ecdsa.PrivateKey as well
// After that, we can support generating kubeconfig files from ecdsa private keys as well
return nil, nil, fmt.Errorf("the private key file %s isn't in RSA format", privateKeyPath)
default:
return nil, nil, fmt.Errorf("the private key file %s isn't in RSA format", privateKeyPath)
} }
if cert != nil { // Check so that the certificate is valid now
if err := certutil.WriteCert(certificatePath, certutil.EncodeCertPEM(cert)); err != nil { now := time.Now()
return fmt.Errorf("unable to write certificate file (%q) [%v]", certificatePath, err) if now.Before(cert.NotBefore) {
} return nil, nil, fmt.Errorf("the certificate is not valid yet")
}
if now.After(cert.NotAfter) {
return nil, nil, fmt.Errorf("the certificate is has expired")
} }
return nil return cert, key, nil
} }
func pathsKeysCerts(pkiPath, name string) (string, string, string) { func pathsForCertAndKey(pkiPath, name string) (string, string) {
return path.Join(pkiPath, fmt.Sprintf("%s-pub.pem", name)), return path.Join(pkiPath, fmt.Sprintf("%s.crt", name)), path.Join(pkiPath, fmt.Sprintf("%s.key", name))
path.Join(pkiPath, fmt.Sprintf("%s-key.pem", name)),
path.Join(pkiPath, fmt.Sprintf("%s.pem", name))
} }
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package certs package pkiutil
import ( import (
"crypto/rand" "crypto/rand"
...@@ -28,27 +28,27 @@ import ( ...@@ -28,27 +28,27 @@ import (
) )
func TestNewCertificateAuthority(t *testing.T) { func TestNewCertificateAuthority(t *testing.T) {
r, x, err := newCertificateAuthority() cert, key, err := NewCertificateAuthority()
if r == nil { if cert == nil {
t.Errorf( t.Errorf(
"failed newCertificateAuthority, rsa key == nil", "failed NewCertificateAuthority, cert == nil",
) )
} }
if x == nil { if key == nil {
t.Errorf( t.Errorf(
"failed newCertificateAuthority, x509 cert == nil", "failed NewCertificateAuthority, key == nil",
) )
} }
if err != nil { if err != nil {
t.Errorf( t.Errorf(
"failed newCertificateAuthority with an error: %v", "failed NewCertificateAuthority with an error: %v",
err, err,
) )
} }
} }
func TestNewServerKeyAndCert(t *testing.T) { func TestNewCertAndKey(t *testing.T) {
var tests = []struct { var tests = []struct {
caKeySize int caKeySize int
expected bool expected bool
...@@ -71,48 +71,14 @@ func TestNewServerKeyAndCert(t *testing.T) { ...@@ -71,48 +71,14 @@ func TestNewServerKeyAndCert(t *testing.T) {
t.Fatalf("Couldn't create rsa Private Key") t.Fatalf("Couldn't create rsa Private Key")
} }
caCert := &x509.Certificate{} caCert := &x509.Certificate{}
altNames := certutil.AltNames{} config := certutil.Config{
_, _, actual := newServerKeyAndCert(caCert, caKey, altNames)
if (actual == nil) != rt.expected {
t.Errorf(
"failed newServerKeyAndCert:\n\texpected: %t\n\t actual: %t",
rt.expected,
(actual == nil),
)
}
}
}
func TestNewClientKeyAndCert(t *testing.T) {
var tests = []struct {
caKeySize int
expected bool
}{
{
// RSA key too small
caKeySize: 128,
expected: false,
},
{
caKeySize: 2048,
expected: true,
},
}
for _, rt := range tests {
caKey, err := rsa.GenerateKey(rand.Reader, rt.caKeySize)
if err != nil {
t.Fatalf("Couldn't create rsa Private Key")
}
caCert := &x509.Certificate{}
config := &certutil.Config{
CommonName: "test", CommonName: "test",
Organization: []string{"test"}, Organization: []string{"test"},
} }
_, _, actual := NewClientKeyAndCert(config, caCert, caKey) _, _, actual := NewCertAndKey(caCert, caKey, config)
if (actual == nil) != rt.expected { if (actual == nil) != rt.expected {
t.Errorf( t.Errorf(
"failed NewClientKeyAndCert:\n\texpected: %t\n\t actual: %t", "failed NewCertAndKey:\n\texpected: %t\n\t actual: %t",
rt.expected, rt.expected,
(actual == nil), (actual == nil),
) )
...@@ -120,56 +86,23 @@ func TestNewClientKeyAndCert(t *testing.T) { ...@@ -120,56 +86,23 @@ func TestNewClientKeyAndCert(t *testing.T) {
} }
} }
func TestWriteKeysAndCert(t *testing.T) { func TestWriteCertAndKey(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "") tmpdir, err := ioutil.TempDir("", "")
if err != nil { if err != nil {
t.Fatalf("Couldn't create tmpdir") t.Fatalf("Couldn't create tmpdir")
} }
defer os.RemoveAll(tmpdir) defer os.Remove(tmpdir)
caKey, err := rsa.GenerateKey(rand.Reader, 2048) caKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil { if err != nil {
t.Fatalf("Couldn't create rsa Private Key") t.Fatalf("Couldn't create rsa Private Key")
} }
caCert := &x509.Certificate{} caCert := &x509.Certificate{}
actual := writeKeysAndCert(tmpdir, "foo", caKey, caCert) actual := WriteCertAndKey(tmpdir, "foo", caCert, caKey)
if actual != nil { if actual != nil {
t.Errorf( t.Errorf(
"failed writeKeysAndCert with an error: %v", "failed WriteCertAndKey with an error: %v",
actual, actual,
) )
} }
} }
func TestPathsKeysCerts(t *testing.T) {
var tests = []struct {
pkiPath string
name string
expected []string
}{
{
pkiPath: "foo",
name: "bar",
expected: []string{"foo/bar-pub.pem", "foo/bar-key.pem", "foo/bar.pem"},
},
{
pkiPath: "bar",
name: "foo",
expected: []string{"bar/foo-pub.pem", "bar/foo-key.pem", "bar/foo.pem"},
},
}
for _, rt := range tests {
a, b, c := pathsKeysCerts(rt.pkiPath, rt.name)
all := []string{a, b, c}
for i := range all {
if all[i] != rt.expected[i] {
t.Errorf(
"failed pathsKeysCerts:\n\texpected: %s\n\t actual: %s",
rt.expected[i],
all[i],
)
}
}
}
}
...@@ -24,7 +24,8 @@ go_library( ...@@ -24,7 +24,8 @@ go_library(
], ],
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//cmd/kubeadm/app/phases/certs:go_default_library", "//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
"//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/client/unversioned/clientcmd:go_default_library",
"//vendor:k8s.io/client-go/pkg/util/cert", "//vendor:k8s.io/client-go/pkg/util/cert",
"//vendor:k8s.io/client-go/tools/clientcmd/api", "//vendor:k8s.io/client-go/tools/clientcmd/api",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment