Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
5fc1a9a8
Unverified
Commit
5fc1a9a8
authored
Nov 05, 2018
by
liz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Option to generate CSRs instead of issued certificates
parent
076adbf4
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
526 additions
and
9 deletions
+526
-9
BUILD
cmd/kubeadm/app/cmd/alpha/BUILD
+1
-0
certs.go
cmd/kubeadm/app/cmd/alpha/certs.go
+15
-0
certs_test.go
cmd/kubeadm/app/cmd/alpha/certs_test.go
+14
-0
certs.go
cmd/kubeadm/app/cmd/options/certs.go
+10
-0
constant.go
cmd/kubeadm/app/cmd/options/constant.go
+6
-0
BUILD
cmd/kubeadm/app/cmd/phases/BUILD
+10
-1
certs.go
cmd/kubeadm/app/cmd/phases/certs.go
+28
-1
certs_test.go
cmd/kubeadm/app/cmd/phases/certs_test.go
+77
-0
BUILD
cmd/kubeadm/app/phases/certs/BUILD
+1
-0
certs.go
cmd/kubeadm/app/phases/certs/certs.go
+46
-0
certs_test.go
cmd/kubeadm/app/phases/certs/certs_test.go
+116
-0
pki_helpers.go
cmd/kubeadm/app/util/pkiutil/pki_helpers.go
+134
-3
pki_helpers_test.go
cmd/kubeadm/app/util/pkiutil/pki_helpers_test.go
+26
-1
BUILD
cmd/kubeadm/test/cmd/BUILD
+3
-0
init_test.go
cmd/kubeadm/test/cmd/init_test.go
+30
-0
util.go
cmd/kubeadm/test/cmd/util.go
+9
-3
No files found.
cmd/kubeadm/app/cmd/alpha/BUILD
View file @
5fc1a9a8
...
@@ -62,6 +62,7 @@ go_test(
...
@@ -62,6 +62,7 @@ go_test(
embed = [":go_default_library"],
embed = [":go_default_library"],
deps = [
deps = [
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/certs:go_default_library",
"//cmd/kubeadm/app/util/pkiutil:go_default_library",
"//cmd/kubeadm/app/util/pkiutil:go_default_library",
"//cmd/kubeadm/test:go_default_library",
"//cmd/kubeadm/test:go_default_library",
"//cmd/kubeadm/test/certs:go_default_library",
"//cmd/kubeadm/test/certs:go_default_library",
...
...
cmd/kubeadm/app/cmd/alpha/certs.go
View file @
5fc1a9a8
...
@@ -76,6 +76,8 @@ type renewConfig struct {
...
@@ -76,6 +76,8 @@ type renewConfig struct {
kubeconfigPath
string
kubeconfigPath
string
cfg
kubeadmapiv1beta1
.
InitConfiguration
cfg
kubeadmapiv1beta1
.
InitConfiguration
useAPI
bool
useAPI
bool
useCSR
bool
csrPath
string
}
}
func
getRenewSubCommands
()
[]
*
cobra
.
Command
{
func
getRenewSubCommands
()
[]
*
cobra
.
Command
{
...
@@ -126,6 +128,8 @@ func addFlags(cmd *cobra.Command, cfg *renewConfig) {
...
@@ -126,6 +128,8 @@ func addFlags(cmd *cobra.Command, cfg *renewConfig) {
options
.
AddConfigFlag
(
cmd
.
Flags
(),
&
cfg
.
cfgPath
)
options
.
AddConfigFlag
(
cmd
.
Flags
(),
&
cfg
.
cfgPath
)
options
.
AddCertificateDirFlag
(
cmd
.
Flags
(),
&
cfg
.
cfg
.
CertificatesDir
)
options
.
AddCertificateDirFlag
(
cmd
.
Flags
(),
&
cfg
.
cfg
.
CertificatesDir
)
options
.
AddKubeConfigFlag
(
cmd
.
Flags
(),
&
cfg
.
kubeconfigPath
)
options
.
AddKubeConfigFlag
(
cmd
.
Flags
(),
&
cfg
.
kubeconfigPath
)
options
.
AddCSRFlag
(
cmd
.
Flags
(),
&
cfg
.
useCSR
)
options
.
AddCSRDirFlag
(
cmd
.
Flags
(),
&
cfg
.
csrPath
)
cmd
.
Flags
()
.
BoolVar
(
&
cfg
.
useAPI
,
"use-api"
,
cfg
.
useAPI
,
"Use the Kubernetes certificate API to renew certificates"
)
cmd
.
Flags
()
.
BoolVar
(
&
cfg
.
useAPI
,
"use-api"
,
cfg
.
useAPI
,
"Use the Kubernetes certificate API to renew certificates"
)
}
}
...
@@ -133,6 +137,17 @@ func generateRenewalFunction(cert *certsphase.KubeadmCert, caCert *certsphase.Ku
...
@@ -133,6 +137,17 @@ func generateRenewalFunction(cert *certsphase.KubeadmCert, caCert *certsphase.Ku
return
func
()
{
return
func
()
{
internalcfg
,
err
:=
configutil
.
ConfigFileAndDefaultsToInternalConfig
(
cfg
.
cfgPath
,
&
cfg
.
cfg
)
internalcfg
,
err
:=
configutil
.
ConfigFileAndDefaultsToInternalConfig
(
cfg
.
cfgPath
,
&
cfg
.
cfg
)
kubeadmutil
.
CheckErr
(
err
)
kubeadmutil
.
CheckErr
(
err
)
if
cfg
.
useCSR
{
path
:=
cfg
.
csrPath
if
path
==
""
{
path
=
cfg
.
cfg
.
CertificatesDir
}
err
:=
certsphase
.
CreateCSR
(
cert
,
internalcfg
,
path
)
kubeadmutil
.
CheckErr
(
err
)
return
}
renewer
,
err
:=
getRenewer
(
cfg
,
caCert
.
BaseName
)
renewer
,
err
:=
getRenewer
(
cfg
,
caCert
.
BaseName
)
kubeadmutil
.
CheckErr
(
err
)
kubeadmutil
.
CheckErr
(
err
)
...
...
cmd/kubeadm/app/cmd/alpha/certs_test.go
View file @
5fc1a9a8
...
@@ -30,6 +30,7 @@ import (
...
@@ -30,6 +30,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/cobra"
kubeadmconstants
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubeadmconstants
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
testutil
"k8s.io/kubernetes/cmd/kubeadm/test"
testutil
"k8s.io/kubernetes/cmd/kubeadm/test"
certstestutil
"k8s.io/kubernetes/cmd/kubeadm/test/certs"
certstestutil
"k8s.io/kubernetes/cmd/kubeadm/test/certs"
...
@@ -219,3 +220,16 @@ func TestRunRenewCommands(t *testing.T) {
...
@@ -219,3 +220,16 @@ func TestRunRenewCommands(t *testing.T) {
})
})
}
}
}
}
func
TestRenewUsingCSR
(
t
*
testing
.
T
)
{
tmpDir
:=
testutil
.
SetupTempDir
(
t
)
defer
os
.
RemoveAll
(
tmpDir
)
cert
:=
&
certs
.
KubeadmCertEtcdServer
renewCmds
:=
getRenewSubCommands
()
cmdtestutil
.
RunSubCommand
(
t
,
renewCmds
,
cert
.
Name
,
"--csr-only"
,
"--csr-dir="
+
tmpDir
)
if
_
,
_
,
err
:=
pkiutil
.
TryLoadCSRAndKeyFromDisk
(
tmpDir
,
cert
.
BaseName
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't load certificate %q: %v"
,
cert
.
BaseName
,
err
)
}
}
cmd/kubeadm/app/cmd/options/certs.go
View file @
5fc1a9a8
...
@@ -22,3 +22,13 @@ import "github.com/spf13/pflag"
...
@@ -22,3 +22,13 @@ import "github.com/spf13/pflag"
func
AddCertificateDirFlag
(
fs
*
pflag
.
FlagSet
,
certsDir
*
string
)
{
func
AddCertificateDirFlag
(
fs
*
pflag
.
FlagSet
,
certsDir
*
string
)
{
fs
.
StringVar
(
certsDir
,
CertificatesDir
,
*
certsDir
,
"The path where to save the certificates"
)
fs
.
StringVar
(
certsDir
,
CertificatesDir
,
*
certsDir
,
"The path where to save the certificates"
)
}
}
// AddCSRFlag adds the --csr-only flag to the given flagset
func
AddCSRFlag
(
fs
*
pflag
.
FlagSet
,
csr
*
bool
)
{
fs
.
BoolVar
(
csr
,
CSROnly
,
*
csr
,
"Create CSRs instead of generating certificates"
)
}
// AddCSRDirFlag adds the --csr-dir flag to the given flagset
func
AddCSRDirFlag
(
fs
*
pflag
.
FlagSet
,
csrDir
*
string
)
{
fs
.
StringVar
(
csrDir
,
CSRDir
,
*
csrDir
,
"The path to output the CSRs and private keys to"
)
}
cmd/kubeadm/app/cmd/options/constant.go
View file @
5fc1a9a8
...
@@ -78,3 +78,9 @@ const SchedulerExtraArgs = "scheduler-extra-args"
...
@@ -78,3 +78,9 @@ const SchedulerExtraArgs = "scheduler-extra-args"
// SkipTokenPrint flag instruct kubeadm to skip printing of the default bootstrap token generated by 'kubeadm init'.
// SkipTokenPrint flag instruct kubeadm to skip printing of the default bootstrap token generated by 'kubeadm init'.
const
SkipTokenPrint
=
"skip-token-print"
const
SkipTokenPrint
=
"skip-token-print"
// CSROnly flag instructs kubeadm to create CSRs instead of automatically creating or renewing certs
const
CSROnly
=
"csr-only"
// CSRDir flag sets the location for CSRs and flags to be output
const
CSRDir
=
"csr-dir"
cmd/kubeadm/app/cmd/phases/BUILD
View file @
5fc1a9a8
...
@@ -52,6 +52,7 @@ go_library(
...
@@ -52,6 +52,7 @@ go_library(
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/renstrom/dedent:go_default_library",
"//vendor/github.com/renstrom/dedent:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
],
],
...
@@ -59,10 +60,18 @@ go_library(
...
@@ -59,10 +60,18 @@ go_library(
go_test(
go_test(
name = "go_default_test",
name = "go_default_test",
srcs = ["util_test.go"],
srcs = [
"certs_test.go",
"util_test.go",
],
embed = [":go_default_library"],
embed = [":go_default_library"],
deps = [
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library",
"//cmd/kubeadm/app/cmd/phases/workflow:go_default_library",
"//cmd/kubeadm/app/phases/certs:go_default_library",
"//cmd/kubeadm/app/util/pkiutil:go_default_library",
"//cmd/kubeadm/test:go_default_library",
"//pkg/version:go_default_library",
"//pkg/version:go_default_library",
],
],
)
)
...
...
cmd/kubeadm/app/cmd/phases/certs.go
View file @
5fc1a9a8
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"strings"
"strings"
"github.com/pkg/errors"
"github.com/pkg/errors"
"github.com/spf13/pflag"
kubeadmapi
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapi
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmscheme
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
kubeadmscheme
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
kubeadmapiv1beta1
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
kubeadmapiv1beta1
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
...
@@ -47,6 +48,11 @@ var (
...
@@ -47,6 +48,11 @@ var (
`
+
cmdutil
.
AlphaDisclaimer
)
`
+
cmdutil
.
AlphaDisclaimer
)
)
)
var
(
csrOnly
bool
csrDir
string
)
// certsData defines the behavior that a runtime data struct passed to the certs phase should
// certsData defines the behavior that a runtime data struct passed to the certs phase should
// have. Please note that we are using an interface in order to make this phase reusable in different workflows
// have. Please note that we are using an interface in order to make this phase reusable in different workflows
// (and thus with different runtime data struct, all of them requested to be compliant to this interface)
// (and thus with different runtime data struct, all of them requested to be compliant to this interface)
...
@@ -65,9 +71,17 @@ func NewCertsPhase() workflow.Phase {
...
@@ -65,9 +71,17 @@ func NewCertsPhase() workflow.Phase {
Phases
:
newCertSubPhases
(),
Phases
:
newCertSubPhases
(),
Run
:
runCerts
,
Run
:
runCerts
,
InheritFlags
:
getCertPhaseFlags
(
"all"
),
InheritFlags
:
getCertPhaseFlags
(
"all"
),
LocalFlags
:
localFlags
(),
}
}
}
}
func
localFlags
()
*
pflag
.
FlagSet
{
set
:=
pflag
.
NewFlagSet
(
"csr"
,
pflag
.
ExitOnError
)
options
.
AddCSRFlag
(
set
,
&
csrOnly
)
options
.
AddCSRDirFlag
(
set
,
&
csrDir
)
return
set
}
// newCertSubPhases returns sub phases for certs phase
// newCertSubPhases returns sub phases for certs phase
func
newCertSubPhases
()
[]
workflow
.
Phase
{
func
newCertSubPhases
()
[]
workflow
.
Phase
{
subPhases
:=
[]
workflow
.
Phase
{}
subPhases
:=
[]
workflow
.
Phase
{}
...
@@ -109,6 +123,7 @@ func newCertSubPhase(certSpec *certsphase.KubeadmCert, run func(c workflow.RunDa
...
@@ -109,6 +123,7 @@ func newCertSubPhase(certSpec *certsphase.KubeadmCert, run func(c workflow.RunDa
),
),
Run
:
run
,
Run
:
run
,
InheritFlags
:
getCertPhaseFlags
(
certSpec
.
Name
),
InheritFlags
:
getCertPhaseFlags
(
certSpec
.
Name
),
LocalFlags
:
localFlags
(),
}
}
return
phase
return
phase
}
}
...
@@ -117,6 +132,8 @@ func getCertPhaseFlags(name string) []string {
...
@@ -117,6 +132,8 @@ func getCertPhaseFlags(name string) []string {
flags
:=
[]
string
{
flags
:=
[]
string
{
options
.
CertificatesDir
,
options
.
CertificatesDir
,
options
.
CfgPath
,
options
.
CfgPath
,
options
.
CSROnly
,
options
.
CSRDir
,
}
}
if
name
==
"all"
||
name
==
"apiserver"
{
if
name
==
"all"
||
name
==
"apiserver"
{
flags
=
append
(
flags
,
flags
=
append
(
flags
,
...
@@ -140,7 +157,8 @@ func getSANDescription(certSpec *certsphase.KubeadmCert) string {
...
@@ -140,7 +157,8 @@ func getSANDescription(certSpec *certsphase.KubeadmCert) string {
defaultInternalConfig
:=
&
kubeadmapi
.
InitConfiguration
{}
defaultInternalConfig
:=
&
kubeadmapi
.
InitConfiguration
{}
kubeadmscheme
.
Scheme
.
Default
(
defaultConfig
)
kubeadmscheme
.
Scheme
.
Default
(
defaultConfig
)
kubeadmscheme
.
Scheme
.
Convert
(
defaultConfig
,
defaultInternalConfig
,
nil
)
err
:=
kubeadmscheme
.
Scheme
.
Convert
(
defaultConfig
,
defaultInternalConfig
,
nil
)
kubeadmutil
.
CheckErr
(
err
)
certConfig
,
err
:=
certSpec
.
GetConfig
(
defaultInternalConfig
)
certConfig
,
err
:=
certSpec
.
GetConfig
(
defaultInternalConfig
)
kubeadmutil
.
CheckErr
(
err
)
kubeadmutil
.
CheckErr
(
err
)
...
@@ -236,6 +254,15 @@ func runCertPhase(cert *certsphase.KubeadmCert, caCert *certsphase.KubeadmCert)
...
@@ -236,6 +254,15 @@ func runCertPhase(cert *certsphase.KubeadmCert, caCert *certsphase.KubeadmCert)
return
nil
return
nil
}
}
if
csrOnly
{
fmt
.
Printf
(
"[certs] Generating CSR for %s instead of certificate
\n
"
,
cert
.
BaseName
)
if
csrDir
==
""
{
csrDir
=
data
.
CertificateWriteDir
()
}
return
certsphase
.
CreateCSR
(
cert
,
data
.
Cfg
(),
csrDir
)
}
// if using external etcd, skips etcd certificates generation
// if using external etcd, skips etcd certificates generation
if
data
.
Cfg
()
.
Etcd
.
External
!=
nil
&&
cert
.
CAName
==
"etcd-ca"
{
if
data
.
Cfg
()
.
Etcd
.
External
!=
nil
&&
cert
.
CAName
==
"etcd-ca"
{
fmt
.
Printf
(
"[certs] External etcd mode: Skipping %s certificate authority generation
\n
"
,
cert
.
BaseName
)
fmt
.
Printf
(
"[certs] External etcd mode: Skipping %s certificate authority generation
\n
"
,
cert
.
BaseName
)
...
...
cmd/kubeadm/app/cmd/phases/certs_test.go
0 → 100644
View file @
5fc1a9a8
/*
Copyright 2018 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
phases
import
(
"os"
"testing"
kubeadmapi
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
testutil
"k8s.io/kubernetes/cmd/kubeadm/test"
)
type
testCertsData
struct
{
cfg
*
kubeadmapi
.
InitConfiguration
}
func
(
t
*
testCertsData
)
Cfg
()
*
kubeadmapi
.
InitConfiguration
{
return
t
.
cfg
}
func
(
t
*
testCertsData
)
ExternalCA
()
bool
{
return
false
}
func
(
t
*
testCertsData
)
CertificateDir
()
string
{
return
t
.
cfg
.
CertificatesDir
}
func
(
t
*
testCertsData
)
CertificateWriteDir
()
string
{
return
t
.
cfg
.
CertificatesDir
}
func
TestCertsWithCSRs
(
t
*
testing
.
T
)
{
csrDir
:=
testutil
.
SetupTempDir
(
t
)
defer
os
.
RemoveAll
(
csrDir
)
certDir
:=
testutil
.
SetupTempDir
(
t
)
defer
os
.
RemoveAll
(
certDir
)
cert
:=
&
certs
.
KubeadmCertAPIServer
certsData
:=
&
testCertsData
{
cfg
:
testutil
.
GetDefaultInternalConfig
(
t
),
}
certsData
.
cfg
.
CertificatesDir
=
certDir
// global vars
csrOnly
=
true
csrDir
=
certDir
phase
:=
NewCertsPhase
()
// find the api cert phase
var
apiServerPhase
*
workflow
.
Phase
for
_
,
phase
:=
range
phase
.
Phases
{
if
phase
.
Name
==
cert
.
Name
{
apiServerPhase
=
&
phase
break
}
}
if
apiServerPhase
==
nil
{
t
.
Fatalf
(
"couldn't find apiserver phase"
)
}
err
:=
apiServerPhase
.
Run
(
certsData
)
if
err
!=
nil
{
t
.
Fatalf
(
"couldn't run API server phase: %v"
,
err
)
}
if
_
,
_
,
err
:=
pkiutil
.
TryLoadCSRAndKeyFromDisk
(
csrDir
,
cert
.
BaseName
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't load certificate %q: %v"
,
cert
.
BaseName
,
err
)
}
}
cmd/kubeadm/app/phases/certs/BUILD
View file @
5fc1a9a8
...
@@ -21,6 +21,7 @@ go_test(
...
@@ -21,6 +21,7 @@ go_test(
"//cmd/kubeadm/test/certs:go_default_library",
"//cmd/kubeadm/test/certs:go_default_library",
"//staging/src/k8s.io/client-go/util/cert:go_default_library",
"//staging/src/k8s.io/client-go/util/cert:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
],
],
)
)
...
...
cmd/kubeadm/app/phases/certs/certs.go
View file @
5fc1a9a8
...
@@ -130,6 +130,25 @@ func CreateCACertAndKeyFiles(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfigur
...
@@ -130,6 +130,25 @@ func CreateCACertAndKeyFiles(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfigur
)
)
}
}
// NewCSR will generate a new CSR and accompanying key
func
NewCSR
(
certSpec
*
KubeadmCert
,
cfg
*
kubeadmapi
.
InitConfiguration
)
(
*
x509
.
CertificateRequest
,
*
rsa
.
PrivateKey
,
error
)
{
certConfig
,
err
:=
certSpec
.
GetConfig
(
cfg
)
if
err
!=
nil
{
return
nil
,
nil
,
fmt
.
Errorf
(
"failed to retrieve cert configuration: %v"
,
err
)
}
return
pkiutil
.
NewCSRAndKey
(
certConfig
)
}
// CreateCSR creates a certificate signing request
func
CreateCSR
(
certSpec
*
KubeadmCert
,
cfg
*
kubeadmapi
.
InitConfiguration
,
path
string
)
error
{
csr
,
key
,
err
:=
NewCSR
(
certSpec
,
cfg
)
if
err
!=
nil
{
return
err
}
return
writeCSRFilesIfNotExist
(
path
,
certSpec
.
BaseName
,
csr
,
key
)
}
// CreateCertAndKeyFilesWithCA loads the given certificate authority from disk, then generates and writes out the given certificate and key.
// CreateCertAndKeyFilesWithCA loads the given certificate authority from disk, then generates and writes out the given certificate and key.
// The certSpec and caCertSpec should both be one of the variables from this package.
// The certSpec and caCertSpec should both be one of the variables from this package.
func
CreateCertAndKeyFilesWithCA
(
certSpec
*
KubeadmCert
,
caCertSpec
*
KubeadmCert
,
cfg
*
kubeadmapi
.
InitConfiguration
)
error
{
func
CreateCertAndKeyFilesWithCA
(
certSpec
*
KubeadmCert
,
caCertSpec
*
KubeadmCert
,
cfg
*
kubeadmapi
.
InitConfiguration
)
error
{
...
@@ -276,6 +295,33 @@ func writeKeyFilesIfNotExist(pkiDir string, baseName string, key *rsa.PrivateKey
...
@@ -276,6 +295,33 @@ func writeKeyFilesIfNotExist(pkiDir string, baseName string, key *rsa.PrivateKey
return
nil
return
nil
}
}
// writeCertificateAuthorithyFilesIfNotExist write a new CSR to the given path.
// If there already is a CSR file at the given path; kubeadm tries to load it and check if it's a valid certificate.
// otherwise this function returns an error.
func
writeCSRFilesIfNotExist
(
csrDir
string
,
baseName
string
,
csr
*
x509
.
CertificateRequest
,
key
*
rsa
.
PrivateKey
)
error
{
if
pkiutil
.
CSROrKeyExist
(
csrDir
,
baseName
)
{
_
,
_
,
err
:=
pkiutil
.
TryLoadCSRAndKeyFromDisk
(
csrDir
,
baseName
)
if
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"%s CSR existed but it could not be loaded properly"
,
baseName
)
}
fmt
.
Printf
(
"[certs] Using the existing %q CSR
\n
"
,
baseName
)
}
else
{
// Write .key and .csr files to disk
fmt
.
Printf
(
"[certs] Generating %q key and CSR
\n
"
,
baseName
)
if
err
:=
pkiutil
.
WriteKey
(
csrDir
,
baseName
,
key
);
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failure while saving %s key"
,
baseName
)
}
if
err
:=
pkiutil
.
WriteCSR
(
csrDir
,
baseName
,
csr
);
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failure while saving %s CSR"
,
baseName
)
}
}
return
nil
}
type
certKeyLocation
struct
{
type
certKeyLocation
struct
{
pkiDir
string
pkiDir
string
caBaseName
string
caBaseName
string
...
...
cmd/kubeadm/app/phases/certs/certs_test.go
View file @
5fc1a9a8
...
@@ -18,13 +18,16 @@ package certs
...
@@ -18,13 +18,16 @@ package certs
import
(
import
(
"crypto/rsa"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"crypto/x509"
"io/ioutil"
"os"
"os"
"path"
"path"
"path/filepath"
"path/filepath"
"testing"
"testing"
"github.com/pkg/errors"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
certutil
"k8s.io/client-go/util/cert"
certutil
"k8s.io/client-go/util/cert"
kubeadmapi
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapi
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
...
@@ -55,6 +58,18 @@ func createTestCert(t *testing.T, caCert *x509.Certificate, caKey *rsa.PrivateKe
...
@@ -55,6 +58,18 @@ func createTestCert(t *testing.T, caCert *x509.Certificate, caKey *rsa.PrivateKe
return
cert
,
key
return
cert
,
key
}
}
func
createTestCSR
(
t
*
testing
.
T
)
(
*
x509
.
CertificateRequest
,
*
rsa
.
PrivateKey
)
{
csr
,
key
,
err
:=
pkiutil
.
NewCSRAndKey
(
&
certutil
.
Config
{
CommonName
:
"testCert"
,
})
if
err
!=
nil
{
t
.
Fatalf
(
"couldn't create test cert: %v"
,
err
)
}
return
csr
,
key
}
func
TestWriteCertificateAuthorithyFilesIfNotExist
(
t
*
testing
.
T
)
{
func
TestWriteCertificateAuthorithyFilesIfNotExist
(
t
*
testing
.
T
)
{
setupCert
,
setupKey
:=
createCACert
(
t
)
setupCert
,
setupKey
:=
createCACert
(
t
)
caCert
,
caKey
:=
createCACert
(
t
)
caCert
,
caKey
:=
createCACert
(
t
)
...
@@ -209,6 +224,75 @@ func TestWriteCertificateFilesIfNotExist(t *testing.T) {
...
@@ -209,6 +224,75 @@ func TestWriteCertificateFilesIfNotExist(t *testing.T) {
}
}
}
}
func
TestWriteCSRFilesIfNotExist
(
t
*
testing
.
T
)
{
csr
,
key
:=
createTestCSR
(
t
)
csr2
,
key2
:=
createTestCSR
(
t
)
var
tests
=
[]
struct
{
name
string
setupFunc
func
(
csrPath
string
)
error
expectedError
bool
expectedCSR
*
x509
.
CertificateRequest
}{
{
name
:
"no files exist"
,
expectedCSR
:
csr
,
},
{
name
:
"other key exists"
,
setupFunc
:
func
(
csrPath
string
)
error
{
if
err
:=
pkiutil
.
WriteCSR
(
csrPath
,
"dummy"
,
csr2
);
err
!=
nil
{
return
err
}
return
pkiutil
.
WriteKey
(
csrPath
,
"dummy"
,
key2
)
},
expectedCSR
:
csr2
,
},
{
name
:
"existing CSR is garbage"
,
setupFunc
:
func
(
csrPath
string
)
error
{
return
ioutil
.
WriteFile
(
path
.
Join
(
csrPath
,
"dummy.csr"
),
[]
byte
(
"a--bunch--of-garbage"
),
os
.
ModePerm
)
},
expectedError
:
true
,
},
}
for
_
,
test
:=
range
tests
{
t
.
Run
(
test
.
name
,
func
(
t
*
testing
.
T
)
{
tmpdir
:=
testutil
.
SetupTempDir
(
t
)
defer
os
.
RemoveAll
(
tmpdir
)
if
test
.
setupFunc
!=
nil
{
if
err
:=
test
.
setupFunc
(
tmpdir
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't set up test: %v"
,
err
)
}
}
if
err
:=
writeCSRFilesIfNotExist
(
tmpdir
,
"dummy"
,
csr
,
key
);
err
!=
nil
{
if
test
.
expectedError
{
return
}
t
.
Fatalf
(
"unexpected error %v: "
,
err
)
}
if
test
.
expectedError
{
t
.
Fatal
(
"Expected error, but got none"
)
}
parsedCSR
,
_
,
err
:=
pkiutil
.
TryLoadCSRAndKeyFromDisk
(
tmpdir
,
"dummy"
)
if
err
!=
nil
{
t
.
Fatalf
(
"couldn't load csr and key: %v"
,
err
)
}
if
sha256
.
Sum256
(
test
.
expectedCSR
.
Raw
)
!=
sha256
.
Sum256
(
parsedCSR
.
Raw
)
{
t
.
Error
(
"expected csr's fingerprint does not match "
)
}
})
}
}
func
TestWriteKeyFilesIfNotExist
(
t
*
testing
.
T
)
{
func
TestWriteKeyFilesIfNotExist
(
t
*
testing
.
T
)
{
setupKey
,
_
:=
NewServiceAccountSigningKey
()
setupKey
,
_
:=
NewServiceAccountSigningKey
()
...
@@ -606,6 +690,38 @@ func TestValidateMethods(t *testing.T) {
...
@@ -606,6 +690,38 @@ func TestValidateMethods(t *testing.T) {
}
}
}
}
func
TestNewCSR
(
t
*
testing
.
T
)
{
kubeadmCert
:=
KubeadmCertAPIServer
cfg
:=
testutil
.
GetDefaultInternalConfig
(
t
)
certConfig
,
err
:=
kubeadmCert
.
GetConfig
(
cfg
)
if
err
!=
nil
{
t
.
Fatalf
(
"couldn't get cert config: %v"
,
err
)
}
csr
,
_
,
err
:=
NewCSR
(
&
kubeadmCert
,
cfg
)
if
err
!=
nil
{
t
.
Errorf
(
"invalid signature on CSR: %v"
,
err
)
}
assert
.
ElementsMatch
(
t
,
certConfig
.
Organization
,
csr
.
Subject
.
Organization
,
"organizations not equal"
)
if
csr
.
Subject
.
CommonName
!=
certConfig
.
CommonName
{
t
.
Errorf
(
"expected common name %q, got %q"
,
certConfig
.
CommonName
,
csr
.
Subject
.
CommonName
)
}
assert
.
ElementsMatch
(
t
,
certConfig
.
AltNames
.
DNSNames
,
csr
.
DNSNames
,
"dns names not equal"
)
assert
.
Len
(
t
,
csr
.
IPAddresses
,
len
(
certConfig
.
AltNames
.
IPs
))
for
i
,
ip
:=
range
csr
.
IPAddresses
{
if
!
ip
.
Equal
(
certConfig
.
AltNames
.
IPs
[
i
])
{
t
.
Errorf
(
"[%d]: %v != %v"
,
i
,
ip
,
certConfig
.
AltNames
.
IPs
[
i
])
}
}
}
type
pkiFiles
map
[
string
]
interface
{}
type
pkiFiles
map
[
string
]
interface
{}
func
writePKIFiles
(
t
*
testing
.
T
,
dir
string
,
files
pkiFiles
)
{
func
writePKIFiles
(
t
*
testing
.
T
,
dir
string
,
files
pkiFiles
)
{
...
...
cmd/kubeadm/app/util/pkiutil/pki_helpers.go
View file @
5fc1a9a8
...
@@ -17,9 +17,14 @@ limitations under the License.
...
@@ -17,9 +17,14 @@ limitations under the License.
package
pkiutil
package
pkiutil
import
(
import
(
"crypto"
cryptorand
"crypto/rand"
"crypto/rsa"
"crypto/rsa"
"crypto/x509"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"fmt"
"io/ioutil"
"net"
"net"
"os"
"os"
"path/filepath"
"path/filepath"
...
@@ -65,6 +70,21 @@ func NewCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey, config *cert
...
@@ -65,6 +70,21 @@ func NewCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey, config *cert
return
cert
,
key
,
nil
return
cert
,
key
,
nil
}
}
// NewCSRAndKey generates a new key and CSR and that could be signed to create the given certificate
func
NewCSRAndKey
(
config
*
certutil
.
Config
)
(
*
x509
.
CertificateRequest
,
*
rsa
.
PrivateKey
,
error
)
{
key
,
err
:=
certutil
.
NewPrivateKey
()
if
err
!=
nil
{
return
nil
,
nil
,
errors
.
Wrap
(
err
,
"unable to create private key"
)
}
csr
,
err
:=
NewCSR
(
*
config
,
key
)
if
err
!=
nil
{
return
nil
,
nil
,
errors
.
Wrap
(
err
,
"unable to generate CSR"
)
}
return
csr
,
key
,
nil
}
// HasServerAuth returns true if the given certificate is a ServerAuth
// HasServerAuth returns true if the given certificate is a ServerAuth
func
HasServerAuth
(
cert
*
x509
.
Certificate
)
bool
{
func
HasServerAuth
(
cert
*
x509
.
Certificate
)
bool
{
for
i
:=
range
cert
.
ExtKeyUsage
{
for
i
:=
range
cert
.
ExtKeyUsage
{
...
@@ -78,7 +98,7 @@ func HasServerAuth(cert *x509.Certificate) bool {
...
@@ -78,7 +98,7 @@ func HasServerAuth(cert *x509.Certificate) bool {
// WriteCertAndKey stores certificate and key at the specified location
// WriteCertAndKey stores certificate and key at the specified location
func
WriteCertAndKey
(
pkiPath
string
,
name
string
,
cert
*
x509
.
Certificate
,
key
*
rsa
.
PrivateKey
)
error
{
func
WriteCertAndKey
(
pkiPath
string
,
name
string
,
cert
*
x509
.
Certificate
,
key
*
rsa
.
PrivateKey
)
error
{
if
err
:=
WriteKey
(
pkiPath
,
name
,
key
);
err
!=
nil
{
if
err
:=
WriteKey
(
pkiPath
,
name
,
key
);
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"couldn't write key"
)
}
}
return
WriteCert
(
pkiPath
,
name
,
cert
)
return
WriteCert
(
pkiPath
,
name
,
cert
)
...
@@ -112,6 +132,27 @@ func WriteKey(pkiPath, name string, key *rsa.PrivateKey) error {
...
@@ -112,6 +132,27 @@ func WriteKey(pkiPath, name string, key *rsa.PrivateKey) error {
return
nil
return
nil
}
}
// WriteCSR writes the pem-encoded CSR data to csrPath.
// The CSR file will be created with file mode 0644.
// If the CSR file already exists, it will be overwritten.
// The parent directory of the csrPath will be created as needed with file mode 0755.
func
WriteCSR
(
csrDir
,
name
string
,
csr
*
x509
.
CertificateRequest
)
error
{
if
csr
==
nil
{
return
errors
.
New
(
"certificate request cannot be nil when writing to file"
)
}
csrPath
:=
pathForCSR
(
csrDir
,
name
)
if
err
:=
os
.
MkdirAll
(
filepath
.
Dir
(
csrPath
),
os
.
FileMode
(
0755
));
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"failed to make directory %s"
,
filepath
.
Dir
(
csrPath
))
}
if
err
:=
ioutil
.
WriteFile
(
csrPath
,
EncodeCSRPEM
(
csr
),
os
.
FileMode
(
0644
));
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"unable to write CSR to file %s"
,
csrPath
)
}
return
nil
}
// WritePublicKey stores the given public key at the given location
// WritePublicKey stores the given public key at the given location
func
WritePublicKey
(
pkiPath
,
name
string
,
key
*
rsa
.
PublicKey
)
error
{
func
WritePublicKey
(
pkiPath
,
name
string
,
key
*
rsa
.
PublicKey
)
error
{
if
key
==
nil
{
if
key
==
nil
{
...
@@ -145,16 +186,27 @@ func CertOrKeyExist(pkiPath, name string) bool {
...
@@ -145,16 +186,27 @@ func CertOrKeyExist(pkiPath, name string) bool {
return
true
return
true
}
}
// CSROrKeyExist returns true if one of the CSR or key exists
func
CSROrKeyExist
(
csrDir
,
name
string
)
bool
{
csrPath
:=
pathForCSR
(
csrDir
,
name
)
keyPath
:=
pathForKey
(
csrDir
,
name
)
_
,
csrErr
:=
os
.
Stat
(
csrPath
)
_
,
keyErr
:=
os
.
Stat
(
keyPath
)
return
!
(
os
.
IsNotExist
(
csrErr
)
&&
os
.
IsNotExist
(
keyErr
))
}
// TryLoadCertAndKeyFromDisk tries to load a cert and a key from the disk and validates that they are valid
// TryLoadCertAndKeyFromDisk tries to load a cert and a key from the disk and validates that they are valid
func
TryLoadCertAndKeyFromDisk
(
pkiPath
,
name
string
)
(
*
x509
.
Certificate
,
*
rsa
.
PrivateKey
,
error
)
{
func
TryLoadCertAndKeyFromDisk
(
pkiPath
,
name
string
)
(
*
x509
.
Certificate
,
*
rsa
.
PrivateKey
,
error
)
{
cert
,
err
:=
TryLoadCertFromDisk
(
pkiPath
,
name
)
cert
,
err
:=
TryLoadCertFromDisk
(
pkiPath
,
name
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
ors
.
Wrap
(
err
,
"failed to load certificate"
)
}
}
key
,
err
:=
TryLoadKeyFromDisk
(
pkiPath
,
name
)
key
,
err
:=
TryLoadKeyFromDisk
(
pkiPath
,
name
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
ors
.
Wrap
(
err
,
"failed to load key"
)
}
}
return
cert
,
key
,
nil
return
cert
,
key
,
nil
...
@@ -207,6 +259,23 @@ func TryLoadKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, error) {
...
@@ -207,6 +259,23 @@ func TryLoadKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, error) {
return
key
,
nil
return
key
,
nil
}
}
// TryLoadCSRAndKeyFromDisk tries to load the CSR and key from the disk
func
TryLoadCSRAndKeyFromDisk
(
pkiPath
,
name
string
)
(
*
x509
.
CertificateRequest
,
*
rsa
.
PrivateKey
,
error
)
{
csrPath
:=
pathForCSR
(
pkiPath
,
name
)
csr
,
err
:=
CertificateRequestFromFile
(
csrPath
)
if
err
!=
nil
{
return
nil
,
nil
,
errors
.
Wrapf
(
err
,
"couldn't load the certificate request %s"
,
csrPath
)
}
key
,
err
:=
TryLoadKeyFromDisk
(
pkiPath
,
name
)
if
err
!=
nil
{
return
nil
,
nil
,
errors
.
Wrap
(
err
,
"couldn't load key file"
)
}
return
csr
,
key
,
nil
}
// TryLoadPrivatePublicKeyFromDisk tries to load the key from the disk and validates that it is valid
// TryLoadPrivatePublicKeyFromDisk tries to load the key from the disk and validates that it is valid
func
TryLoadPrivatePublicKeyFromDisk
(
pkiPath
,
name
string
)
(
*
rsa
.
PrivateKey
,
*
rsa
.
PublicKey
,
error
)
{
func
TryLoadPrivatePublicKeyFromDisk
(
pkiPath
,
name
string
)
(
*
rsa
.
PrivateKey
,
*
rsa
.
PublicKey
,
error
)
{
privateKeyPath
:=
pathForKey
(
pkiPath
,
name
)
privateKeyPath
:=
pathForKey
(
pkiPath
,
name
)
...
@@ -253,6 +322,10 @@ func pathForPublicKey(pkiPath, name string) string {
...
@@ -253,6 +322,10 @@ func pathForPublicKey(pkiPath, name string) string {
return
filepath
.
Join
(
pkiPath
,
fmt
.
Sprintf
(
"%s.pub"
,
name
))
return
filepath
.
Join
(
pkiPath
,
fmt
.
Sprintf
(
"%s.pub"
,
name
))
}
}
func
pathForCSR
(
pkiPath
,
name
string
)
string
{
return
filepath
.
Join
(
pkiPath
,
fmt
.
Sprintf
(
"%s.csr"
,
name
))
}
// GetAPIServerAltNames builds an AltNames object for to be used when generating apiserver certificate
// GetAPIServerAltNames builds an AltNames object for to be used when generating apiserver certificate
func
GetAPIServerAltNames
(
cfg
*
kubeadmapi
.
InitConfiguration
)
(
*
certutil
.
AltNames
,
error
)
{
func
GetAPIServerAltNames
(
cfg
*
kubeadmapi
.
InitConfiguration
)
(
*
certutil
.
AltNames
,
error
)
{
// advertise address
// advertise address
...
@@ -373,3 +446,61 @@ func appendSANsToAltNames(altNames *certutil.AltNames, SANs []string, certName s
...
@@ -373,3 +446,61 @@ func appendSANsToAltNames(altNames *certutil.AltNames, SANs []string, certName s
}
}
}
}
}
}
// EncodeCSRPEM returns PEM-encoded CSR data
func
EncodeCSRPEM
(
csr
*
x509
.
CertificateRequest
)
[]
byte
{
block
:=
pem
.
Block
{
Type
:
certutil
.
CertificateRequestBlockType
,
Bytes
:
csr
.
Raw
,
}
return
pem
.
EncodeToMemory
(
&
block
)
}
func
parseCSRPEM
(
pemCSR
[]
byte
)
(
*
x509
.
CertificateRequest
,
error
)
{
block
,
_
:=
pem
.
Decode
(
pemCSR
)
if
block
==
nil
{
return
nil
,
fmt
.
Errorf
(
"data doesn't contain a valid certificate request"
)
}
if
block
.
Type
!=
certutil
.
CertificateRequestBlockType
{
var
block
*
pem
.
Block
return
nil
,
fmt
.
Errorf
(
"expected block type %q, but PEM had type %v"
,
certutil
.
CertificateRequestBlockType
,
block
.
Type
)
}
return
x509
.
ParseCertificateRequest
(
block
.
Bytes
)
}
// CertificateRequestFromFile returns the CertificateRequest from a given PEM-encoded file.
// Returns an error if the file could not be read or if the CSR could not be parsed.
func
CertificateRequestFromFile
(
file
string
)
(
*
x509
.
CertificateRequest
,
error
)
{
pemBlock
,
err
:=
ioutil
.
ReadFile
(
file
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"failed to read file"
)
}
csr
,
err
:=
parseCSRPEM
(
pemBlock
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error reading certificate request file %s: %v"
,
file
,
err
)
}
return
csr
,
nil
}
// NewCSR creates a new CSR
func
NewCSR
(
cfg
certutil
.
Config
,
key
crypto
.
Signer
)
(
*
x509
.
CertificateRequest
,
error
)
{
template
:=
&
x509
.
CertificateRequest
{
Subject
:
pkix
.
Name
{
CommonName
:
cfg
.
CommonName
,
Organization
:
cfg
.
Organization
,
},
DNSNames
:
cfg
.
AltNames
.
DNSNames
,
IPAddresses
:
cfg
.
AltNames
.
IPs
,
}
csrBytes
,
err
:=
x509
.
CreateCertificateRequest
(
cryptorand
.
Reader
,
template
,
key
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"failed to create a CSR"
)
}
return
x509
.
ParseCertificateRequest
(
csrBytes
)
}
cmd/kubeadm/app/util/pkiutil/pki_helpers_test.go
View file @
5fc1a9a8
...
@@ -29,6 +29,24 @@ import (
...
@@ -29,6 +29,24 @@ import (
kubeadmapi
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapi
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
)
)
// certificateRequest is an x509 certificate request in PEM encoded format
// openssl req -new -key rsa2048.pem -sha256 -nodes -out x509certrequest.pem -subj "/C=US/CN=not-valid"
const
certificateRequest
=
`-----BEGIN CERTIFICATE REQUEST-----
MIICZjCCAU4CAQAwITELMAkGA1UEBhMCVVMxEjAQBgNVBAMMCW5vdC12YWxpZDCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdoBxV0SbSS+7XrgVDF/P4x
tqyun+DLxeRF5265ZOFRJDXCJgYH7wKlxlkEaHZQhnNmnqFiy96MHSKaiQmlkEm4
EhlqTf38yEWx+t98A0CDbHsIPZ0/+MPCjb2kf+OfBXJJl908io0grs02jxN9lceL
RFrKT6vaB+6i7LxbPQcOmjF7OUqWS6S2qSpShw2GY+mJz4HM7OFb9RcN4izh+GF6
7hajYgt7pAFyWF1ua/H98Ysn4FVgIYk30rHCNBkQpJnna7EyGYuj08VuFa088W9g
c/DCpL+VgBDwTel9tfeMxRAoLIPF9iJ8Ftr7dsRZ/Y/SnxfUJo2ed8y7dgIiLuEC
AwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQCOjPB/4LKa2G7LarMMLAeNqvWF9SIG
y2VGQoTn9D5blXMvnfzWSYgU6nBzf/E/32q26OwiCriuOPXfxM/cxEMOJ62u7b50
OR52JFvQdONsCZaLgylGWppl0YeqylbTosHjsWJNlp+zjXcQHjCQ9OoLgfmrwYyD
2MsYJR4p7JZ2ZN8FF1hgMUrDzypZ0NSBKAiQMU9TFhxgyk75RNDtmX+2K35zqLyr
0otimyYwPCGPD2GHwNfvu1oP0A+/cT+rCPz6AlXhWEbz2JkLo6/muRfRl0QSRgHE
Q3+eWlA1YdqEBwvp3NEQI9BtMnzxJVWA5dvYluMNllsV/q8s2IEEAFG9
-----END CERTIFICATE REQUEST-----`
func
TestNewCertificateAuthority
(
t
*
testing
.
T
)
{
func
TestNewCertificateAuthority
(
t
*
testing
.
T
)
{
cert
,
key
,
err
:=
NewCertificateAuthority
(
&
certutil
.
Config
{
CommonName
:
"kubernetes"
})
cert
,
key
,
err
:=
NewCertificateAuthority
(
&
certutil
.
Config
{
CommonName
:
"kubernetes"
})
...
@@ -435,6 +453,13 @@ func TestPathForPublicKey(t *testing.T) {
...
@@ -435,6 +453,13 @@ func TestPathForPublicKey(t *testing.T) {
}
}
}
}
func
TestPathForCSR
(
t
*
testing
.
T
)
{
csrPath
:=
pathForCSR
(
"/foo"
,
"bar"
)
if
csrPath
!=
"/foo/bar.csr"
{
t
.
Errorf
(
"unexpected certificate path: %s"
,
csrPath
)
}
}
func
TestGetAPIServerAltNames
(
t
*
testing
.
T
)
{
func
TestGetAPIServerAltNames
(
t
*
testing
.
T
)
{
var
tests
=
[]
struct
{
var
tests
=
[]
struct
{
...
@@ -444,7 +469,7 @@ func TestGetAPIServerAltNames(t *testing.T) {
...
@@ -444,7 +469,7 @@ func TestGetAPIServerAltNames(t *testing.T) {
expectedIPAddresses
[]
string
expectedIPAddresses
[]
string
}{
}{
{
{
name
:
"
ControlPlaneEndpoint DNS
"
,
name
:
""
,
cfg
:
&
kubeadmapi
.
InitConfiguration
{
cfg
:
&
kubeadmapi
.
InitConfiguration
{
LocalAPIEndpoint
:
kubeadmapi
.
APIEndpoint
{
AdvertiseAddress
:
"1.2.3.4"
},
LocalAPIEndpoint
:
kubeadmapi
.
APIEndpoint
{
AdvertiseAddress
:
"1.2.3.4"
},
ClusterConfiguration
:
kubeadmapi
.
ClusterConfiguration
{
ClusterConfiguration
:
kubeadmapi
.
ClusterConfiguration
{
...
...
cmd/kubeadm/test/cmd/BUILD
View file @
5fc1a9a8
...
@@ -33,6 +33,9 @@ go_test(
...
@@ -33,6 +33,9 @@ go_test(
"skip",
"skip",
],
],
deps = [
deps = [
"//cmd/kubeadm/app/phases/certs:go_default_library",
"//cmd/kubeadm/app/util/pkiutil:go_default_library",
"//cmd/kubeadm/test:go_default_library",
"//vendor/github.com/renstrom/dedent:go_default_library",
"//vendor/github.com/renstrom/dedent:go_default_library",
"//vendor/sigs.k8s.io/yaml:go_default_library",
"//vendor/sigs.k8s.io/yaml:go_default_library",
],
],
...
...
cmd/kubeadm/test/cmd/init_test.go
View file @
5fc1a9a8
...
@@ -20,6 +20,9 @@ import (
...
@@ -20,6 +20,9 @@ import (
"testing"
"testing"
"github.com/renstrom/dedent"
"github.com/renstrom/dedent"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
testutil
"k8s.io/kubernetes/cmd/kubeadm/test"
)
)
func
runKubeadmInit
(
args
...
string
)
(
string
,
string
,
error
)
{
func
runKubeadmInit
(
args
...
string
)
(
string
,
string
,
error
)
{
...
@@ -191,6 +194,33 @@ func TestCmdInitConfig(t *testing.T) {
...
@@ -191,6 +194,33 @@ func TestCmdInitConfig(t *testing.T) {
}
}
}
}
func
TestCmdInitCertPhaseCSR
(
t
*
testing
.
T
)
{
if
*
kubeadmCmdSkip
{
t
.
Log
(
"kubeadm cmd tests being skipped"
)
t
.
Skip
()
}
csrDir
:=
testutil
.
SetupTempDir
(
t
)
cert
:=
&
certs
.
KubeadmCertKubeletClient
kubeadmPath
:=
getKubeadmPath
()
_
,
_
,
err
:=
RunCmd
(
kubeadmPath
,
"init"
,
"phase"
,
"certs"
,
cert
.
BaseName
,
"--csr-only"
,
"--csr-dir="
+
csrDir
,
)
if
err
!=
nil
{
t
.
Fatalf
(
"couldn't run kubeadm: %v"
,
err
)
}
if
_
,
_
,
err
:=
pkiutil
.
TryLoadCSRAndKeyFromDisk
(
csrDir
,
cert
.
BaseName
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't load certificate %q: %v"
,
cert
.
BaseName
,
err
)
}
}
func
TestCmdInitAPIPort
(
t
*
testing
.
T
)
{
func
TestCmdInitAPIPort
(
t
*
testing
.
T
)
{
if
*
kubeadmCmdSkip
{
if
*
kubeadmCmdSkip
{
t
.
Log
(
"kubeadm cmd tests being skipped"
)
t
.
Log
(
"kubeadm cmd tests being skipped"
)
...
...
cmd/kubeadm/test/cmd/util.go
View file @
5fc1a9a8
...
@@ -18,24 +18,30 @@ package kubeadm
...
@@ -18,24 +18,30 @@ package kubeadm
import
(
import
(
"bytes"
"bytes"
"github.com/pkg/errors"
"os/exec"
"os/exec"
"testing"
"testing"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/cobra"
)
)
// Forked from test/e2e/framework because the e2e framework is quite bloated
// Forked from test/e2e/framework because the e2e framework is quite bloated
// for our purposes here, and modified to remove undesired logging.
// for our purposes here, and modified to remove undesired logging.
// RunCmd is a utility function for kubeadm testing that executes a specified command
func
runCmdNoWrap
(
command
string
,
args
...
string
)
(
string
,
string
,
error
)
{
func
RunCmd
(
command
string
,
args
...
string
)
(
string
,
string
,
error
)
{
var
bout
,
berr
bytes
.
Buffer
var
bout
,
berr
bytes
.
Buffer
cmd
:=
exec
.
Command
(
command
,
args
...
)
cmd
:=
exec
.
Command
(
command
,
args
...
)
cmd
.
Stdout
=
&
bout
cmd
.
Stdout
=
&
bout
cmd
.
Stderr
=
&
berr
cmd
.
Stderr
=
&
berr
err
:=
cmd
.
Run
()
err
:=
cmd
.
Run
()
stdout
,
stderr
:=
bout
.
String
(),
berr
.
String
()
stdout
,
stderr
:=
bout
.
String
(),
berr
.
String
()
return
stdout
,
stderr
,
err
}
// RunCmd is a utility function for kubeadm testing that executes a specified command
func
RunCmd
(
command
string
,
args
...
string
)
(
string
,
string
,
error
)
{
stdout
,
stderr
,
err
:=
runCmdNoWrap
(
command
,
args
...
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
""
,
errors
.
Wrapf
(
err
,
"error running %s %v;
\n
stdout %q,
\n
stderr %q,
\n
got error"
,
return
""
,
""
,
errors
.
Wrapf
(
err
,
"error running %s %v;
\n
stdout %q,
\n
stderr %q,
\n
got error"
,
command
,
args
,
stdout
,
stderr
)
command
,
args
,
stdout
,
stderr
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment