Add generated file
This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
57
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/BUILD
generated
vendored
Normal file
57
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/BUILD
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"kubeconfig.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["kubeconfig_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/test:go_default_library",
|
||||
"//cmd/kubeadm/test/certs:go_default_library",
|
||||
"//cmd/kubeadm/test/kubeconfig:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
],
|
||||
)
|
35
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/doc.go
generated
vendored
Normal file
35
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/doc.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
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 kubeconfig
|
||||
|
||||
/*
|
||||
|
||||
PHASE: KUBECONFIG
|
||||
|
||||
INPUTS:
|
||||
From MasterConfiguration
|
||||
The Master API Server endpoint (AdvertiseAddress + BindPort) is required so the KubeConfig file knows where to find the master
|
||||
The KubernetesDir path is required for knowing where to put the KubeConfig files
|
||||
The PKIPath is required for knowing where all certificates should be stored
|
||||
|
||||
OUTPUTS:
|
||||
Files to KubernetesDir (default /etc/kubernetes):
|
||||
- admin.conf
|
||||
- kubelet.conf
|
||||
- scheduler.conf
|
||||
- controller-manager.conf
|
||||
*/
|
343
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go
generated
vendored
Normal file
343
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go
generated
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
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 kubeconfig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"crypto/rsa"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
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"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
)
|
||||
|
||||
// clientCertAuth struct holds info required to build a client certificate to provide authentication info in a kubeconfig object
|
||||
type clientCertAuth struct {
|
||||
CAKey *rsa.PrivateKey
|
||||
Organizations []string
|
||||
}
|
||||
|
||||
// tokenAuth struct holds info required to use a token to provide authentication info in a kubeconfig object
|
||||
type tokenAuth struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
// kubeConfigSpec struct holds info required to build a KubeConfig object
|
||||
type kubeConfigSpec struct {
|
||||
CACert *x509.Certificate
|
||||
APIServer string
|
||||
ClientName string
|
||||
TokenAuth *tokenAuth
|
||||
ClientCertAuth *clientCertAuth
|
||||
}
|
||||
|
||||
// CreateInitKubeConfigFiles will create and write to disk all kubeconfig files necessary in the kubeadm init phase
|
||||
// to establish the control plane, including also the admin kubeconfig file.
|
||||
// If kubeconfig files already exists, they are used only if evaluated equal; otherwise an error is returned.
|
||||
func CreateInitKubeConfigFiles(outDir string, cfg *kubeadmapi.MasterConfiguration) error {
|
||||
glog.V(1).Infoln("creating all kubeconfig files")
|
||||
return createKubeConfigFiles(
|
||||
outDir,
|
||||
cfg,
|
||||
kubeadmconstants.AdminKubeConfigFileName,
|
||||
kubeadmconstants.KubeletKubeConfigFileName,
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName,
|
||||
kubeadmconstants.SchedulerKubeConfigFileName,
|
||||
)
|
||||
}
|
||||
|
||||
// CreateAdminKubeConfigFile create a kubeconfig file for the admin to use and for kubeadm itself.
|
||||
// If the kubeconfig file already exists, it is used only if evaluated equal; otherwise an error is returned.
|
||||
func CreateAdminKubeConfigFile(outDir string, cfg *kubeadmapi.MasterConfiguration) error {
|
||||
glog.V(1).Infoln("create a kubeconfig file for the admin and for kubeadm itself")
|
||||
return createKubeConfigFiles(outDir, cfg, kubeadmconstants.AdminKubeConfigFileName)
|
||||
}
|
||||
|
||||
// CreateKubeletKubeConfigFile create a kubeconfig file for the Kubelet to use.
|
||||
// If the kubeconfig file already exists, it is used only if evaluated equal; otherwise an error is returned.
|
||||
func CreateKubeletKubeConfigFile(outDir string, cfg *kubeadmapi.MasterConfiguration) error {
|
||||
glog.V(1).Infoln("creating a kubeconfig file for the Kubelet")
|
||||
return createKubeConfigFiles(outDir, cfg, kubeadmconstants.KubeletKubeConfigFileName)
|
||||
}
|
||||
|
||||
// CreateControllerManagerKubeConfigFile create a kubeconfig file for the ControllerManager to use.
|
||||
// If the kubeconfig file already exists, it is used only if evaluated equal; otherwise an error is returned.
|
||||
func CreateControllerManagerKubeConfigFile(outDir string, cfg *kubeadmapi.MasterConfiguration) error {
|
||||
glog.V(1).Infoln("creating kubeconfig file for the ControllerManager")
|
||||
return createKubeConfigFiles(outDir, cfg, kubeadmconstants.ControllerManagerKubeConfigFileName)
|
||||
}
|
||||
|
||||
// CreateSchedulerKubeConfigFile create a create a kubeconfig file for the Scheduler to use.
|
||||
// If the kubeconfig file already exists, it is used only if evaluated equal; otherwise an error is returned.
|
||||
func CreateSchedulerKubeConfigFile(outDir string, cfg *kubeadmapi.MasterConfiguration) error {
|
||||
glog.V(1).Infoln("creating kubeconfig file for Scheduler")
|
||||
return createKubeConfigFiles(outDir, cfg, kubeadmconstants.SchedulerKubeConfigFileName)
|
||||
}
|
||||
|
||||
// createKubeConfigFiles creates all the requested kubeconfig files.
|
||||
// If kubeconfig files already exists, they are used only if evaluated equal; otherwise an error is returned.
|
||||
func createKubeConfigFiles(outDir string, cfg *kubeadmapi.MasterConfiguration, kubeConfigFileNames ...string) error {
|
||||
|
||||
// gets the KubeConfigSpecs, actualized for the current MasterConfiguration
|
||||
specs, err := getKubeConfigSpecs(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, kubeConfigFileName := range kubeConfigFileNames {
|
||||
// retrives the KubeConfigSpec for given kubeConfigFileName
|
||||
spec, exists := specs[kubeConfigFileName]
|
||||
if !exists {
|
||||
return fmt.Errorf("couldn't retrive KubeConfigSpec for %s", kubeConfigFileName)
|
||||
}
|
||||
|
||||
// builds the KubeConfig object
|
||||
config, err := buildKubeConfigFromSpec(spec, cfg.ClusterName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// writes the KubeConfig to disk if it not exists
|
||||
if err = createKubeConfigFileIfNotExists(outDir, kubeConfigFileName, config); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getKubeConfigSpecs returns all KubeConfigSpecs actualized to the context of the current MasterConfiguration
|
||||
// NB. this methods holds the information about how kubeadm creates kubeconfig files.
|
||||
func getKubeConfigSpecs(cfg *kubeadmapi.MasterConfiguration) (map[string]*kubeConfigSpec, error) {
|
||||
|
||||
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err)
|
||||
}
|
||||
|
||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(&cfg.API)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var kubeConfigSpec = map[string]*kubeConfigSpec{
|
||||
kubeadmconstants.AdminKubeConfigFileName: {
|
||||
CACert: caCert,
|
||||
APIServer: masterEndpoint,
|
||||
ClientName: "kubernetes-admin",
|
||||
ClientCertAuth: &clientCertAuth{
|
||||
CAKey: caKey,
|
||||
Organizations: []string{kubeadmconstants.MastersGroup},
|
||||
},
|
||||
},
|
||||
kubeadmconstants.KubeletKubeConfigFileName: {
|
||||
CACert: caCert,
|
||||
APIServer: masterEndpoint,
|
||||
ClientName: fmt.Sprintf("system:node:%s", cfg.NodeRegistration.Name),
|
||||
ClientCertAuth: &clientCertAuth{
|
||||
CAKey: caKey,
|
||||
Organizations: []string{kubeadmconstants.NodesGroup},
|
||||
},
|
||||
},
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName: {
|
||||
CACert: caCert,
|
||||
APIServer: masterEndpoint,
|
||||
ClientName: kubeadmconstants.ControllerManagerUser,
|
||||
ClientCertAuth: &clientCertAuth{
|
||||
CAKey: caKey,
|
||||
},
|
||||
},
|
||||
kubeadmconstants.SchedulerKubeConfigFileName: {
|
||||
CACert: caCert,
|
||||
APIServer: masterEndpoint,
|
||||
ClientName: kubeadmconstants.SchedulerUser,
|
||||
ClientCertAuth: &clientCertAuth{
|
||||
CAKey: caKey,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return kubeConfigSpec, nil
|
||||
}
|
||||
|
||||
// buildKubeConfigFromSpec creates a kubeconfig object for the given kubeConfigSpec
|
||||
func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientcmdapi.Config, error) {
|
||||
|
||||
// If this kubeconfig should use token
|
||||
if spec.TokenAuth != nil {
|
||||
// create a kubeconfig with a token
|
||||
return kubeconfigutil.CreateWithToken(
|
||||
spec.APIServer,
|
||||
clustername,
|
||||
spec.ClientName,
|
||||
certutil.EncodeCertPEM(spec.CACert),
|
||||
spec.TokenAuth.Token,
|
||||
), nil
|
||||
}
|
||||
|
||||
// otherwise, create a client certs
|
||||
clientCertConfig := certutil.Config{
|
||||
CommonName: spec.ClientName,
|
||||
Organization: spec.ClientCertAuth.Organizations,
|
||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
}
|
||||
clientCert, clientKey, err := pkiutil.NewCertAndKey(spec.CACert, spec.ClientCertAuth.CAKey, clientCertConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failure while creating %s client certificate: %v", spec.ClientName, err)
|
||||
}
|
||||
|
||||
// create a kubeconfig with the client certs
|
||||
return kubeconfigutil.CreateWithCerts(
|
||||
spec.APIServer,
|
||||
clustername,
|
||||
spec.ClientName,
|
||||
certutil.EncodeCertPEM(spec.CACert),
|
||||
certutil.EncodePrivateKeyPEM(clientKey),
|
||||
certutil.EncodeCertPEM(clientCert),
|
||||
), nil
|
||||
}
|
||||
|
||||
// createKubeConfigFileIfNotExists saves the KubeConfig object into a file if there isn't any file at the given path.
|
||||
// If there already is a KubeConfig file at the given path; kubeadm tries to load it and check if the values in the
|
||||
// existing and the expected config equals. If they do; kubeadm will just skip writing the file as it's up-to-date,
|
||||
// but if a file exists but has old content or isn't a kubeconfig file, this function returns an error.
|
||||
func createKubeConfigFileIfNotExists(outDir, filename string, config *clientcmdapi.Config) error {
|
||||
kubeConfigFilePath := filepath.Join(outDir, filename)
|
||||
|
||||
// Check if the file exist, and if it doesn't, just write it to disk
|
||||
if _, err := os.Stat(kubeConfigFilePath); os.IsNotExist(err) {
|
||||
err = kubeconfigutil.WriteToDisk(kubeConfigFilePath, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to save kubeconfig file %s on disk: %v", kubeConfigFilePath, err)
|
||||
}
|
||||
|
||||
fmt.Printf("[kubeconfig] Wrote KubeConfig file to disk: %q\n", kubeConfigFilePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// The kubeconfig already exists, let's check if it has got the same CA and server URL
|
||||
currentConfig, err := clientcmd.LoadFromFile(kubeConfigFilePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load kubeconfig file %s that already exists on disk: %v", kubeConfigFilePath, err)
|
||||
}
|
||||
|
||||
expectedCtx := config.CurrentContext
|
||||
expectedCluster := config.Contexts[expectedCtx].Cluster
|
||||
currentCtx := currentConfig.CurrentContext
|
||||
currentCluster := currentConfig.Contexts[currentCtx].Cluster
|
||||
|
||||
// If the current CA cert on disk doesn't match the expected CA cert, error out because we have a file, but it's stale
|
||||
if !bytes.Equal(currentConfig.Clusters[currentCluster].CertificateAuthorityData, config.Clusters[expectedCluster].CertificateAuthorityData) {
|
||||
return fmt.Errorf("a kubeconfig file %q exists already but has got the wrong CA cert", kubeConfigFilePath)
|
||||
}
|
||||
// If the current API Server location on disk doesn't match the expected API server, error out because we have a file, but it's stale
|
||||
if currentConfig.Clusters[currentCluster].Server != config.Clusters[expectedCluster].Server {
|
||||
return fmt.Errorf("a kubeconfig file %q exists already but has got the wrong API Server URL", kubeConfigFilePath)
|
||||
}
|
||||
|
||||
// kubeadm doesn't validate the existing kubeconfig file more than this (kubeadm trusts the client certs to be valid)
|
||||
// Basically, if we find a kubeconfig file with the same path; the same CA cert and the same server URL;
|
||||
// kubeadm thinks those files are equal and doesn't bother writing a new file
|
||||
fmt.Printf("[kubeconfig] Using existing up-to-date KubeConfig file: %q\n", kubeConfigFilePath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteKubeConfigWithClientCert writes a kubeconfig file - with a client certificate as authentication info - to the given writer.
|
||||
func WriteKubeConfigWithClientCert(out io.Writer, cfg *kubeadmapi.MasterConfiguration, clientName string, organizations []string) error {
|
||||
|
||||
// creates the KubeConfigSpecs, actualized for the current MasterConfiguration
|
||||
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err)
|
||||
}
|
||||
|
||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(&cfg.API)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
spec := &kubeConfigSpec{
|
||||
ClientName: clientName,
|
||||
APIServer: masterEndpoint,
|
||||
CACert: caCert,
|
||||
ClientCertAuth: &clientCertAuth{
|
||||
CAKey: caKey,
|
||||
Organizations: organizations,
|
||||
},
|
||||
}
|
||||
|
||||
return writeKubeConfigFromSpec(out, spec, cfg.ClusterName)
|
||||
}
|
||||
|
||||
// WriteKubeConfigWithToken writes a kubeconfig file - with a token as client authentication info - to the given writer.
|
||||
func WriteKubeConfigWithToken(out io.Writer, cfg *kubeadmapi.MasterConfiguration, clientName, token string) error {
|
||||
|
||||
// creates the KubeConfigSpecs, actualized for the current MasterConfiguration
|
||||
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err)
|
||||
}
|
||||
|
||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(&cfg.API)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
spec := &kubeConfigSpec{
|
||||
ClientName: clientName,
|
||||
APIServer: masterEndpoint,
|
||||
CACert: caCert,
|
||||
TokenAuth: &tokenAuth{
|
||||
Token: token,
|
||||
},
|
||||
}
|
||||
|
||||
return writeKubeConfigFromSpec(out, spec, cfg.ClusterName)
|
||||
}
|
||||
|
||||
// writeKubeConfigFromSpec creates a kubeconfig object from a kubeConfigSpec and writes it to the given writer.
|
||||
func writeKubeConfigFromSpec(out io.Writer, spec *kubeConfigSpec, clustername string) error {
|
||||
|
||||
// builds the KubeConfig object
|
||||
config, err := buildKubeConfigFromSpec(spec, clustername)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// writes the KubeConfig to disk if it not exists
|
||||
configBytes, err := clientcmd.Write(*config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failure while serializing admin kubeconfig: %v", err)
|
||||
}
|
||||
|
||||
fmt.Fprintln(out, string(configBytes))
|
||||
return nil
|
||||
}
|
466
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go
generated
vendored
Normal file
466
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go
generated
vendored
Normal file
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
Copyright 2017 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 kubeconfig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
|
||||
pkiutil "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
||||
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
||||
certstestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs"
|
||||
kubeconfigtestutil "k8s.io/kubernetes/cmd/kubeadm/test/kubeconfig"
|
||||
)
|
||||
|
||||
func TestGetKubeConfigSpecsFailsIfCADoesntExists(t *testing.T) {
|
||||
// Create temp folder for the test case (without a CA)
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Creates a Master Configuration pointing to the pkidir folder
|
||||
cfg := &kubeadmapi.MasterConfiguration{
|
||||
CertificatesDir: tmpdir,
|
||||
}
|
||||
|
||||
// Executes getKubeConfigSpecs
|
||||
if _, err := getKubeConfigSpecs(cfg); err == nil {
|
||||
t.Error("getKubeConfigSpecs didnt failed when expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetKubeConfigSpecs(t *testing.T) {
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Adds a pki folder with a ca certs to the temp folder
|
||||
pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir)
|
||||
|
||||
// Creates Master Configurations pointing to the pkidir folder
|
||||
cfgs := []*kubeadmapi.MasterConfiguration{
|
||||
{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
|
||||
CertificatesDir: pkidir,
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
|
||||
},
|
||||
{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234},
|
||||
CertificatesDir: pkidir,
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
|
||||
},
|
||||
{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234},
|
||||
CertificatesDir: pkidir,
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
|
||||
},
|
||||
{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234},
|
||||
CertificatesDir: pkidir,
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
|
||||
},
|
||||
{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234},
|
||||
CertificatesDir: pkidir,
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, cfg := range cfgs {
|
||||
var assertions = []struct {
|
||||
kubeConfigFile string
|
||||
clientName string
|
||||
organizations []string
|
||||
}{
|
||||
{
|
||||
kubeConfigFile: kubeadmconstants.AdminKubeConfigFileName,
|
||||
clientName: "kubernetes-admin",
|
||||
organizations: []string{kubeadmconstants.MastersGroup},
|
||||
},
|
||||
{
|
||||
kubeConfigFile: kubeadmconstants.KubeletKubeConfigFileName,
|
||||
clientName: fmt.Sprintf("system:node:%s", cfg.NodeRegistration.Name),
|
||||
organizations: []string{kubeadmconstants.NodesGroup},
|
||||
},
|
||||
{
|
||||
kubeConfigFile: kubeadmconstants.ControllerManagerKubeConfigFileName,
|
||||
clientName: kubeadmconstants.ControllerManagerUser,
|
||||
},
|
||||
{
|
||||
kubeConfigFile: kubeadmconstants.SchedulerKubeConfigFileName,
|
||||
clientName: kubeadmconstants.SchedulerUser,
|
||||
},
|
||||
}
|
||||
|
||||
for _, assertion := range assertions {
|
||||
// Executes getKubeConfigSpecs
|
||||
specs, err := getKubeConfigSpecs(cfg)
|
||||
if err != nil {
|
||||
t.Fatal("getKubeConfigSpecs failed!")
|
||||
}
|
||||
|
||||
var spec *kubeConfigSpec
|
||||
var ok bool
|
||||
|
||||
// assert the spec for the kubeConfigFile exists
|
||||
if spec, ok = specs[assertion.kubeConfigFile]; !ok {
|
||||
t.Errorf("getKubeConfigSpecs didn't create spec for %s ", assertion.kubeConfigFile)
|
||||
continue
|
||||
}
|
||||
|
||||
// Assert clientName
|
||||
if spec.ClientName != assertion.clientName {
|
||||
t.Errorf("getKubeConfigSpecs for %s clientName is %s, expected %s", assertion.kubeConfigFile, spec.ClientName, assertion.clientName)
|
||||
}
|
||||
|
||||
// Assert Organizations
|
||||
if spec.ClientCertAuth == nil || !reflect.DeepEqual(spec.ClientCertAuth.Organizations, assertion.organizations) {
|
||||
t.Errorf("getKubeConfigSpecs for %s Organizations is %v, expected %v", assertion.kubeConfigFile, spec.ClientCertAuth.Organizations, assertion.organizations)
|
||||
}
|
||||
|
||||
// Asserts MasterConfiguration values injected into spec
|
||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(&cfg.API)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if spec.APIServer != masterEndpoint {
|
||||
t.Errorf("getKubeConfigSpecs didn't injected cfg.APIServer endpoint into spec for %s", assertion.kubeConfigFile)
|
||||
}
|
||||
|
||||
// Asserts CA certs and CA keys loaded into specs
|
||||
if spec.CACert == nil {
|
||||
t.Errorf("getKubeConfigSpecs didn't loaded CACert into spec for %s!", assertion.kubeConfigFile)
|
||||
}
|
||||
if spec.ClientCertAuth == nil || spec.ClientCertAuth.CAKey == nil {
|
||||
t.Errorf("getKubeConfigSpecs didn't loaded CAKey into spec for %s!", assertion.kubeConfigFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildKubeConfigFromSpecWithClientAuth(t *testing.T) {
|
||||
// Creates a CA
|
||||
caCert, caKey := certstestutil.SetupCertificateAuthorithy(t)
|
||||
|
||||
// Executes buildKubeConfigFromSpec passing a KubeConfigSpec with a ClientAuth
|
||||
config := setupdKubeConfigWithClientAuth(t, caCert, caKey, "https://1.2.3.4:1234", "myClientName", "test-cluster", "myOrg1", "myOrg2")
|
||||
|
||||
// Asserts spec data are propagated to the kubeconfig
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert)
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithClientCert(t, config, caCert, "myClientName", "myOrg1", "myOrg2")
|
||||
}
|
||||
|
||||
func TestBuildKubeConfigFromSpecWithTokenAuth(t *testing.T) {
|
||||
// Creates a CA
|
||||
caCert, _ := certstestutil.SetupCertificateAuthorithy(t)
|
||||
|
||||
// Executes buildKubeConfigFromSpec passing a KubeConfigSpec with a Token
|
||||
config := setupdKubeConfigWithTokenAuth(t, caCert, "https://1.2.3.4:1234", "myClientName", "123456", "test-cluster")
|
||||
|
||||
// Asserts spec data are propagated to the kubeconfig
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert)
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithToken(t, config, "myClientName", "123456")
|
||||
}
|
||||
|
||||
func TestCreateKubeConfigFileIfNotExists(t *testing.T) {
|
||||
|
||||
// Creates a CAs
|
||||
caCert, caKey := certstestutil.SetupCertificateAuthorithy(t)
|
||||
anotherCaCert, anotherCaKey := certstestutil.SetupCertificateAuthorithy(t)
|
||||
|
||||
// build kubeconfigs (to be used to test kubeconfigs equality/not equality)
|
||||
config := setupdKubeConfigWithClientAuth(t, caCert, caKey, "https://1.2.3.4:1234", "test-cluster", "myOrg1", "myOrg2")
|
||||
configWithAnotherClusterCa := setupdKubeConfigWithClientAuth(t, anotherCaCert, anotherCaKey, "https://1.2.3.4:1234", "test-cluster", "myOrg1", "myOrg2")
|
||||
configWithAnotherClusterAddress := setupdKubeConfigWithClientAuth(t, caCert, caKey, "https://3.4.5.6:3456", "myOrg1", "test-cluster", "myOrg2")
|
||||
|
||||
var tests = []struct {
|
||||
existingKubeConfig *clientcmdapi.Config
|
||||
kubeConfig *clientcmdapi.Config
|
||||
expectedError bool
|
||||
}{
|
||||
{ // if there is no existing KubeConfig, creates the kubeconfig
|
||||
kubeConfig: config,
|
||||
},
|
||||
{ // if KubeConfig is equal to the existingKubeConfig - refers to the same cluster -, use the existing (Test idempotency)
|
||||
existingKubeConfig: config,
|
||||
kubeConfig: config,
|
||||
},
|
||||
{ // if KubeConfig is not equal to the existingKubeConfig - refers to the another cluster (a cluster with another Ca) -, raise error
|
||||
existingKubeConfig: config,
|
||||
kubeConfig: configWithAnotherClusterCa,
|
||||
expectedError: true,
|
||||
},
|
||||
{ // if KubeConfig is not equal to the existingKubeConfig - refers to the another cluster (a cluster with another address) -, raise error
|
||||
existingKubeConfig: config,
|
||||
kubeConfig: configWithAnotherClusterAddress,
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Writes the existing kubeconfig file to disk
|
||||
if test.existingKubeConfig != nil {
|
||||
if err := createKubeConfigFileIfNotExists(tmpdir, "test.conf", test.existingKubeConfig); err != nil {
|
||||
t.Errorf("createKubeConfigFileIfNotExists failed")
|
||||
}
|
||||
}
|
||||
|
||||
// Writes the KubeConfig file to disk
|
||||
err := createKubeConfigFileIfNotExists(tmpdir, "test.conf", test.kubeConfig)
|
||||
if test.expectedError && err == nil {
|
||||
t.Errorf("createKubeConfigFileIfNotExists didn't failed when expected to fail")
|
||||
}
|
||||
if !test.expectedError && err != nil {
|
||||
t.Errorf("createKubeConfigFileIfNotExists failed")
|
||||
}
|
||||
|
||||
// Assert that the created file is there
|
||||
testutil.AssertFileExists(t, tmpdir, "test.conf")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateKubeconfigFilesAndWrappers(t *testing.T) {
|
||||
var tests = []struct {
|
||||
createKubeConfigFunction func(outDir string, cfg *kubeadmapi.MasterConfiguration) error
|
||||
expectedFiles []string
|
||||
expectedError bool
|
||||
}{
|
||||
{ // Test createKubeConfigFiles fails for unknown kubeconfig is requested
|
||||
createKubeConfigFunction: func(outDir string, cfg *kubeadmapi.MasterConfiguration) error {
|
||||
return createKubeConfigFiles(outDir, cfg, "unknown.conf")
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{ // Test CreateInitKubeConfigFiles (wrapper to createKubeConfigFile)
|
||||
createKubeConfigFunction: CreateInitKubeConfigFiles,
|
||||
expectedFiles: []string{
|
||||
kubeadmconstants.AdminKubeConfigFileName,
|
||||
kubeadmconstants.KubeletKubeConfigFileName,
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName,
|
||||
kubeadmconstants.SchedulerKubeConfigFileName,
|
||||
},
|
||||
},
|
||||
{ // Test CreateAdminKubeConfigFile (wrapper to createKubeConfigFile)
|
||||
createKubeConfigFunction: CreateAdminKubeConfigFile,
|
||||
expectedFiles: []string{kubeadmconstants.AdminKubeConfigFileName},
|
||||
},
|
||||
{ // Test CreateKubeletKubeConfigFile (wrapper to createKubeConfigFile)
|
||||
createKubeConfigFunction: CreateKubeletKubeConfigFile,
|
||||
expectedFiles: []string{kubeadmconstants.KubeletKubeConfigFileName},
|
||||
},
|
||||
{ // Test CreateControllerManagerKubeConfigFile (wrapper to createKubeConfigFile)
|
||||
createKubeConfigFunction: CreateControllerManagerKubeConfigFile,
|
||||
expectedFiles: []string{kubeadmconstants.ControllerManagerKubeConfigFileName},
|
||||
},
|
||||
{ // Test createKubeConfigFile (wrapper to createKubeConfigFile)
|
||||
createKubeConfigFunction: CreateSchedulerKubeConfigFile,
|
||||
expectedFiles: []string{kubeadmconstants.SchedulerKubeConfigFileName},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Adds a pki folder with a ca certs to the temp folder
|
||||
pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir)
|
||||
|
||||
// Creates a Master Configuration pointing to the pkidir folder
|
||||
cfg := &kubeadmapi.MasterConfiguration{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
|
||||
CertificatesDir: pkidir,
|
||||
}
|
||||
|
||||
// Execs the createKubeConfigFunction
|
||||
err := test.createKubeConfigFunction(tmpdir, cfg)
|
||||
if test.expectedError && err == nil {
|
||||
t.Errorf("createKubeConfigFunction didn't failed when expected to fail")
|
||||
continue
|
||||
}
|
||||
if !test.expectedError && err != nil {
|
||||
t.Errorf("createKubeConfigFunction failed")
|
||||
continue
|
||||
}
|
||||
|
||||
// Assert expected files are there
|
||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteKubeConfigFailsIfCADoesntExists(t *testing.T) {
|
||||
|
||||
// Temporary folders for the test case (without a CA)
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Creates a Master Configuration pointing to the tmpdir folder
|
||||
cfg := &kubeadmapi.MasterConfiguration{
|
||||
CertificatesDir: tmpdir,
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
writeKubeConfigFunction func(out io.Writer) error
|
||||
}{
|
||||
{ // Test WriteKubeConfigWithClientCert
|
||||
writeKubeConfigFunction: func(out io.Writer) error {
|
||||
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"})
|
||||
},
|
||||
},
|
||||
{ // Test WriteKubeConfigWithToken
|
||||
writeKubeConfigFunction: func(out io.Writer) error {
|
||||
return WriteKubeConfigWithToken(out, cfg, "myUser", "12345")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
// executes writeKubeConfigFunction
|
||||
if err := test.writeKubeConfigFunction(buf); err == nil {
|
||||
t.Error("writeKubeConfigFunction didnt failed when expected")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteKubeConfig(t *testing.T) {
|
||||
|
||||
// Temporary folders for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Adds a pki folder with a ca cert to the temp folder
|
||||
pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir)
|
||||
|
||||
// Retrieves ca cert for assertions
|
||||
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkidir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't retrieve ca cert: %v", err)
|
||||
}
|
||||
|
||||
// Creates a Master Configuration pointing to the pkidir folder
|
||||
cfg := &kubeadmapi.MasterConfiguration{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
|
||||
CertificatesDir: pkidir,
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
writeKubeConfigFunction func(out io.Writer) error
|
||||
withClientCert bool
|
||||
withToken bool
|
||||
}{
|
||||
{ // Test WriteKubeConfigWithClientCert
|
||||
writeKubeConfigFunction: func(out io.Writer) error {
|
||||
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"})
|
||||
},
|
||||
withClientCert: true,
|
||||
},
|
||||
{ // Test WriteKubeConfigWithToken
|
||||
writeKubeConfigFunction: func(out io.Writer) error {
|
||||
return WriteKubeConfigWithToken(out, cfg, "myUser", "12345")
|
||||
},
|
||||
withToken: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
// executes writeKubeConfigFunction
|
||||
if err := test.writeKubeConfigFunction(buf); err != nil {
|
||||
t.Error("writeKubeConfigFunction failed")
|
||||
continue
|
||||
}
|
||||
|
||||
// reads kubeconfig written to stdout
|
||||
config, err := clientcmd.Load(buf.Bytes())
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't read kubeconfig file from buffer: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// checks that CLI flags are properly propagated
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert)
|
||||
|
||||
if test.withClientCert {
|
||||
// checks that kubeconfig files have expected client cert
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithClientCert(t, config, caCert, "myUser")
|
||||
}
|
||||
|
||||
if test.withToken {
|
||||
// checks that kubeconfig files have expected token
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithToken(t, config, "myUser", "12345")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setupdKubeConfigWithClientAuth is a test utility function that wraps buildKubeConfigFromSpec for building a KubeConfig object With ClientAuth
|
||||
func setupdKubeConfigWithClientAuth(t *testing.T, caCert *x509.Certificate, caKey *rsa.PrivateKey, APIServer, clientName, clustername string, organizations ...string) *clientcmdapi.Config {
|
||||
spec := &kubeConfigSpec{
|
||||
CACert: caCert,
|
||||
APIServer: APIServer,
|
||||
ClientName: clientName,
|
||||
ClientCertAuth: &clientCertAuth{
|
||||
CAKey: caKey,
|
||||
Organizations: organizations,
|
||||
},
|
||||
}
|
||||
|
||||
config, err := buildKubeConfigFromSpec(spec, clustername)
|
||||
if err != nil {
|
||||
t.Fatal("buildKubeConfigFromSpec failed!")
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// setupdKubeConfigWithClientAuth is a test utility function that wraps buildKubeConfigFromSpec for building a KubeConfig object With Token
|
||||
func setupdKubeConfigWithTokenAuth(t *testing.T, caCert *x509.Certificate, APIServer, clientName, token, clustername string) *clientcmdapi.Config {
|
||||
spec := &kubeConfigSpec{
|
||||
CACert: caCert,
|
||||
APIServer: APIServer,
|
||||
ClientName: clientName,
|
||||
TokenAuth: &tokenAuth{
|
||||
Token: token,
|
||||
},
|
||||
}
|
||||
|
||||
config, err := buildKubeConfigFromSpec(spec, clustername)
|
||||
if err != nil {
|
||||
t.Fatal("buildKubeConfigFromSpec failed!")
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
Reference in New Issue
Block a user