Merge pull request #41603 from luxas/kubeadm_reorder_kubeconfig

Automatic merge from submit-queue (batch tested with PRs 41043, 39058, 41021, 41603, 41414)

kubeadm: Make a separate util package for kubeconfig logic

**What this PR does / why we need it**:

There are a lot of packages that need to consume kubeconfig logic, so it should be in a central place.
Having it in `kubeadmutil` is suboptimal, because then it get mixed with everything else.

This splits that logic out to a generic place so it then also can be consumed in https://github.com/kubernetes/kubernetes/pull/41417, from where it's broken out.

 - Move {admin,kubelet}.conf out as constants
 - Make a separate util package for kubeconfig logic

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #

**Special notes for your reviewer**:

**Release note**:

```release-note
NONE
```
pull/6/head
Kubernetes Submit Queue 2017-02-19 00:58:46 -08:00 committed by GitHub
commit f69570c92e
22 changed files with 204 additions and 161 deletions

View File

@ -36,6 +36,7 @@ go_library(
"//cmd/kubeadm/app/phases/token:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library",
"//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//cmd/kubeadm/app/util/token:go_default_library",
"//pkg/bootstrap/api:go_default_library",
"//pkg/kubectl:go_default_library",
@ -64,7 +65,7 @@ go_test(
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library",
],
)

View File

@ -218,7 +218,7 @@ func (i *Init) Run(out io.Writer) error {
return err
}
client, err := kubemaster.CreateClientAndWaitForAPI(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfigphase.AdminKubeConfigFileName))
client, err := kubemaster.CreateClientAndWaitForAPI(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeadmconstants.AdminKubeConfigFileName))
if err != nil {
return err
}

View File

@ -34,9 +34,9 @@ import (
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/discovery"
kubenode "k8s.io/kubernetes/cmd/kubeadm/app/node"
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
)
var (
@ -139,8 +139,8 @@ func (j *Join) Run(out io.Writer) error {
return err
}
kubeconfigFile := filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfigphase.KubeletKubeConfigFileName)
if err := kubeconfigphase.WriteKubeconfigToDisk(kubeconfigFile, cfg); err != nil {
kubeconfigFile := filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)
if err := kubeconfigutil.WriteToDisk(kubeconfigFile, cfg); err != nil {
return err
}

View File

@ -27,7 +27,7 @@ import (
"github.com/spf13/cobra"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/util/initsystem"
@ -150,7 +150,7 @@ func drainAndRemoveNode(removeNode bool) error {
hostname = strings.ToLower(hostname)
// TODO: Use the "native" k8s client for this once we're confident the versioned is working
kubeConfigPath := filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.KubeletKubeConfigFileName)
kubeConfigPath := filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)
getNodesCmd := fmt.Sprintf("kubectl --kubeconfig %s get nodes | grep %s", kubeConfigPath, hostname)
output, err := exec.Command("sh", "-c", getNodesCmd).Output()
@ -221,8 +221,8 @@ func resetConfigDir(configPathDir, pkiPathDir string) {
}
filesToClean := []string{
filepath.Join(configPathDir, kubeconfig.AdminKubeConfigFileName),
filepath.Join(configPathDir, kubeconfig.KubeletKubeConfigFileName),
filepath.Join(configPathDir, kubeadmconstants.AdminKubeConfigFileName),
filepath.Join(configPathDir, kubeadmconstants.KubeletKubeConfigFileName),
}
fmt.Printf("[reset] Deleting files: %v\n", filesToClean)
for _, path := range filesToClean {

View File

@ -22,7 +22,7 @@ import (
"path/filepath"
"testing"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
)
@ -64,8 +64,8 @@ func TestConfigDirCleaner(t *testing.T) {
"manifests/etcd.yaml",
"manifests/kube-apiserver.yaml",
"pki/ca.pem",
kubeconfig.AdminKubeConfigFileName,
kubeconfig.KubeletKubeConfigFileName,
kubeadmconstants.AdminKubeConfigFileName,
kubeadmconstants.KubeletKubeConfigFileName,
},
verifyExists: []string{
"manifests",
@ -78,7 +78,7 @@ func TestConfigDirCleaner(t *testing.T) {
},
setupFiles: []string{
"pki/ca.pem",
kubeconfig.KubeletKubeConfigFileName,
kubeadmconstants.KubeletKubeConfigFileName,
},
verifyExists: []string{
"pki",
@ -96,8 +96,8 @@ func TestConfigDirCleaner(t *testing.T) {
"manifests/etcd.yaml",
"manifests/kube-apiserver.yaml",
"pki/ca.pem",
kubeconfig.AdminKubeConfigFileName,
kubeconfig.KubeletKubeConfigFileName,
kubeadmconstants.AdminKubeConfigFileName,
kubeadmconstants.KubeletKubeConfigFileName,
"cloud-config",
},
verifyExists: []string{
@ -116,8 +116,8 @@ func TestConfigDirCleaner(t *testing.T) {
"manifests/etcd.yaml",
"manifests/kube-apiserver.yaml",
"pki/ca.pem",
kubeconfig.AdminKubeConfigFileName,
kubeconfig.KubeletKubeConfigFileName,
kubeadmconstants.AdminKubeConfigFileName,
kubeadmconstants.KubeletKubeConfigFileName,
".cloud-config",
".mydir/.myfile",
},
@ -167,8 +167,8 @@ func TestConfigDirCleaner(t *testing.T) {
// Verify the files we cleanup implicitly in every test:
assertExists(t, tmpDir)
assertNotExists(t, filepath.Join(tmpDir, kubeconfig.AdminKubeConfigFileName))
assertNotExists(t, filepath.Join(tmpDir, kubeconfig.KubeletKubeConfigFileName))
assertNotExists(t, filepath.Join(tmpDir, kubeadmconstants.AdminKubeConfigFileName))
assertNotExists(t, filepath.Join(tmpDir, kubeadmconstants.KubeletKubeConfigFileName))
assertDirEmpty(t, filepath.Join(tmpDir, "manifests"))
assertDirEmpty(t, filepath.Join(tmpDir, "pki"))

View File

@ -32,10 +32,9 @@ import (
"k8s.io/client-go/pkg/api"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubemaster "k8s.io/kubernetes/cmd/kubeadm/app/master"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
tokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/token"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api"
"k8s.io/kubernetes/pkg/kubectl"
@ -131,7 +130,7 @@ func NewCmdTokenGenerate(out io.Writer) *cobra.Command {
// RunCreateToken generates a new bootstrap token and stores it as a secret on the server.
func RunCreateToken(out io.Writer, cmd *cobra.Command, tokenDuration time.Duration, token string) error {
client, err := kubemaster.CreateClientFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.AdminKubeConfigFileName))
client, err := kubeconfigutil.ClientSetFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeadmconstants.AdminKubeConfigFileName))
if err != nil {
return err
}
@ -164,7 +163,7 @@ func RunGenerateToken(out io.Writer) error {
// RunListTokens lists details on all existing bootstrap tokens on the server.
func RunListTokens(out io.Writer, errW io.Writer, cmd *cobra.Command) error {
client, err := kubemaster.CreateClientFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.AdminKubeConfigFileName))
client, err := kubeconfigutil.ClientSetFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeadmconstants.AdminKubeConfigFileName))
if err != nil {
return err
}
@ -223,7 +222,7 @@ func RunDeleteToken(out io.Writer, cmd *cobra.Command, tokenId string) error {
return err
}
client, err := kubemaster.CreateClientFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.AdminKubeConfigFileName))
client, err := kubeconfigutil.ClientSetFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeadmconstants.AdminKubeConfigFileName))
if err != nil {
return err
}

View File

@ -46,6 +46,9 @@ const (
FrontProxyClientCertName = "front-proxy-client.crt"
FrontProxyClientKeyName = "front-proxy-client.key"
AdminKubeConfigFileName = "admin.conf"
KubeletKubeConfigFileName = "kubelet.conf"
// TODO: These constants should actually come from pkg/kubeapiserver/authorizer, but we can't vendor that package in now
// because of all the other sub-packages that would get vendored. To fix this, a pkg/kubeapiserver/authorizer/modes package
// or similar should exist that only has these constants; then we can vendor it.

View File

@ -23,6 +23,7 @@ go_library(
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/images:go_default_library",
"//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//vendor:github.com/ghodss/yaml",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
@ -35,7 +36,6 @@ go_library(
"//vendor:k8s.io/client-go/pkg/api",
"//vendor:k8s.io/client-go/pkg/api/v1",
"//vendor:k8s.io/client-go/pkg/apis/extensions/v1beta1",
"//vendor:k8s.io/client-go/tools/clientcmd",
"//vendor:k8s.io/client-go/util/cert",
],
)

View File

@ -29,31 +29,14 @@ import (
"k8s.io/client-go/pkg/api"
"k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/tools/clientcmd"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
)
func CreateClientFromFile(path string) (*clientset.Clientset, error) {
adminKubeconfig, err := clientcmd.LoadFromFile(path)
if err != nil {
return nil, fmt.Errorf("failed to load admin kubeconfig [%v]", err)
}
adminClientConfig, err := clientcmd.NewDefaultClientConfig(*adminKubeconfig, &clientcmd.ConfigOverrides{}).ClientConfig()
if err != nil {
return nil, fmt.Errorf("failed to create API client configuration [%v]", err)
}
client, err := clientset.NewForConfig(adminClientConfig)
if err != nil {
return nil, fmt.Errorf("failed to create API client [%v]", err)
}
return client, nil
}
func CreateClientAndWaitForAPI(file string) (*clientset.Clientset, error) {
client, err := CreateClientFromFile(file)
client, err := kubeconfigutil.ClientSetFromFile(file)
if err != nil {
return nil, err
}

View File

@ -18,7 +18,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//cmd/kubeadm/app/util/token:go_default_library",
"//pkg/kubelet/util/csr:go_default_library",
"//vendor:github.com/square/go-jose",

View File

@ -29,7 +29,7 @@ import (
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
)
@ -98,7 +98,7 @@ func EstablishMasterConnection(c *kubeadmapi.TokenDiscovery, clusterInfo *kubead
// creates a set of clients for this endpoint
func createClients(caCert []byte, endpoint, token string, nodeName types.NodeName) (*apiClient, error) {
clientConfig := kubeconfigphase.MakeClientConfigWithToken(
clientConfig := kubeconfigutil.CreateWithToken(
endpoint,
"kubernetes",
fmt.Sprintf("kubelet-%s", nodeName),

View File

@ -5,15 +5,6 @@ licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = ["kubeconfig_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = ["//cmd/kubeadm/app/apis/kubeadm:go_default_library"],
)
go_library(
@ -26,6 +17,7 @@ go_library(
deps = [
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//vendor:k8s.io/client-go/tools/clientcmd",
"//vendor:k8s.io/client-go/tools/clientcmd/api",
"//vendor:k8s.io/client-go/util/cert",

View File

@ -21,7 +21,6 @@ import (
"crypto/rsa"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
"path/filepath"
@ -30,15 +29,7 @@ import (
certutil "k8s.io/client-go/util/cert"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
)
const (
KubernetesDirPermissions = 0700
KubeConfigFilePermissions = 0600
AdminKubeConfigFileName = "admin.conf"
AdminKubeConfigClientName = "kubernetes-admin"
KubeletKubeConfigFileName = "kubelet.conf"
KubeletKubeConfigClientName = "kubelet"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
)
// TODO: Make an integration test for this function that runs after the certificates phase
@ -56,36 +47,36 @@ func CreateAdminAndKubeletKubeConfig(masterEndpoint, pkiDir, outDir string) erro
// 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 {
if err != nil {
return fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err)
}
// User admin should have full access to the cluster
// TODO: Add test case that make sure this cert has the x509.ExtKeyUsageClientAuth flag
adminCertConfig := certutil.Config{
CommonName: AdminKubeConfigClientName,
CommonName: "kubernetes-admin",
Organization: []string{"system:masters"},
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
}
adminKubeConfigFilePath := filepath.Join(outDir, AdminKubeConfigFileName)
adminKubeConfigFilePath := filepath.Join(outDir, kubeadmconstants.AdminKubeConfigFileName)
if err := createKubeConfigFileForClient(masterEndpoint, adminKubeConfigFilePath, adminCertConfig, caCert, caKey); err != nil {
return fmt.Errorf("couldn't create config for %s: %v", AdminKubeConfigClientName, err)
return fmt.Errorf("couldn't create config for the admin: %v", err)
}
// TODO: The kubelet should have limited access to the cluster. Right now, this gives kubelet basically root access
// and we do need that in the bootstrap phase, but we should swap it out after the control plane is up
// TODO: Add test case that make sure this cert has the x509.ExtKeyUsageClientAuth flag
kubeletCertConfig := certutil.Config{
CommonName: KubeletKubeConfigClientName,
CommonName: "kubelet",
Organization: []string{"system:nodes"},
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
}
kubeletKubeConfigFilePath := filepath.Join(outDir, KubeletKubeConfigFileName)
kubeletKubeConfigFilePath := filepath.Join(outDir, kubeadmconstants.KubeletKubeConfigFileName)
if err := createKubeConfigFileForClient(masterEndpoint, kubeletKubeConfigFilePath, kubeletCertConfig, caCert, caKey); err != nil {
return fmt.Errorf("couldn't create a kubeconfig file for %s: %v", KubeletKubeConfigClientName, err)
return fmt.Errorf("couldn't create a kubeconfig file for the kubelet: %v", err)
}
// TODO make credentials for the controller-manager, scheduler and kube-proxy
// TODO make credentials for the controller-manager and scheduler
return nil
}
@ -95,7 +86,7 @@ func createKubeConfigFileForClient(masterEndpoint, kubeConfigFilePath string, co
return fmt.Errorf("failure while creating %s client certificate [%v]", config.CommonName, err)
}
kubeconfig := MakeClientConfigWithCerts(
kubeconfig := kubeconfigutil.CreateWithCerts(
masterEndpoint,
"kubernetes",
config.CommonName,
@ -108,30 +99,6 @@ func createKubeConfigFileForClient(masterEndpoint, kubeConfigFilePath string, co
return writeKubeconfigToDiskIfNotExists(kubeConfigFilePath, kubeconfig)
}
func WriteKubeconfigToDisk(filename string, kubeconfig *clientcmdapi.Config) error {
// Convert the KubeConfig object to a byte array
content, err := clientcmd.Write(*kubeconfig)
if err != nil {
return err
}
// Create the directory if it does not exist
dir := filepath.Dir(filename)
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err = os.MkdirAll(dir, KubernetesDirPermissions); err != nil {
return err
}
}
// No such kubeconfig file exists; write that kubeconfig down to disk then
if err := ioutil.WriteFile(filename, content, KubeConfigFilePermissions); err != nil {
return err
}
fmt.Printf("[kubeconfig] Wrote KubeConfig file to disk: %q\n", filename)
return nil
}
// writeKubeconfigToDiskIfNotExists saves the KubeConfig struct to disk 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,
@ -139,7 +106,7 @@ func WriteKubeconfigToDisk(filename string, kubeconfig *clientcmdapi.Config) err
func writeKubeconfigToDiskIfNotExists(filename string, expectedConfig *clientcmdapi.Config) error {
// Check if the file exist, and if it doesn't, just write it to disk
if _, err := os.Stat(filename); os.IsNotExist(err) {
return WriteKubeconfigToDisk(filename, expectedConfig)
return kubeconfigutil.WriteToDisk(filename, expectedConfig)
}
// The kubeconfig already exists, let's check if it has got the same CA and server URL
@ -168,47 +135,3 @@ func writeKubeconfigToDiskIfNotExists(filename string, expectedConfig *clientcmd
return nil
}
func createBasicClientConfig(serverURL string, clusterName string, userName string, caCert []byte) *clientcmdapi.Config {
config := clientcmdapi.NewConfig()
// Make a new cluster, specify the endpoint we'd like to talk to and the ca cert we're gonna use
cluster := clientcmdapi.NewCluster()
cluster.Server = serverURL
cluster.CertificateAuthorityData = caCert
// Specify a context where we're using that cluster and the username as the auth information
contextName := fmt.Sprintf("%s@%s", userName, clusterName)
context := clientcmdapi.NewContext()
context.Cluster = clusterName
context.AuthInfo = userName
// Lastly, apply the created objects above to the config
config.Clusters[clusterName] = cluster
config.Contexts[contextName] = context
config.CurrentContext = contextName
return config
}
// Creates a clientcmdapi.Config object with access to the API server with client certificates
func MakeClientConfigWithCerts(serverURL, clusterName, userName string, caCert []byte, clientKey []byte, clientCert []byte) *clientcmdapi.Config {
config := createBasicClientConfig(serverURL, clusterName, userName, caCert)
authInfo := clientcmdapi.NewAuthInfo()
authInfo.ClientKeyData = clientKey
authInfo.ClientCertificateData = clientCert
config.AuthInfos[userName] = authInfo
return config
}
// Creates a clientcmdapi.Config object with access to the API server with a token
func MakeClientConfigWithToken(serverURL, clusterName, userName string, caCert []byte, token string) *clientcmdapi.Config {
config := createBasicClientConfig(serverURL, clusterName, userName, caCert)
authInfo := clientcmdapi.NewAuthInfo()
authInfo.Token = token
config.AuthInfos[userName] = authInfo
return config
}

View File

@ -15,7 +15,6 @@ go_library(
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//pkg/api/validation:go_default_library",
"//pkg/util/initsystem:go_default_library",
"//pkg/util/node:go_default_library",

View File

@ -30,7 +30,6 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/util/initsystem"
"k8s.io/kubernetes/pkg/util/node"
@ -386,7 +385,7 @@ func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error {
DirAvailableCheck{Path: filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")},
DirAvailableCheck{Path: "/var/lib/kubelet"},
FileAvailableCheck{Path: filepath.Join(kubeadmapi.GlobalEnvParams.HostPKIPath, kubeadmconstants.CACertName)},
FileAvailableCheck{Path: filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.KubeletKubeConfigFileName)},
FileAvailableCheck{Path: filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)},
FileContentCheck{Path: bridgenf, Content: []byte{'1'}},
InPathCheck{executable: "ip", mandatory: true},
InPathCheck{executable: "iptables", mandatory: true},

View File

@ -42,6 +42,7 @@ filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//cmd/kubeadm/app/util/kubeconfig:all-srcs",
"//cmd/kubeadm/app/util/token:all-srcs",
],
tags = ["automanaged"],

View File

@ -0,0 +1,41 @@
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 = ["kubeconfig_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = ["//cmd/kubeadm/app/apis/kubeadm:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = ["kubeconfig.go"],
tags = ["automanaged"],
deps = [
"//vendor:k8s.io/client-go/kubernetes",
"//vendor:k8s.io/client-go/tools/clientcmd",
"//vendor:k8s.io/client-go/tools/clientcmd/api",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,101 @@
/*
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 (
"fmt"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)
// CreateBasic creates a basic, general KubeConfig object that then can be extended
func CreateBasic(serverURL string, clusterName string, userName string, caCert []byte) *clientcmdapi.Config {
// Use the cluster and the username as the context name
contextName := fmt.Sprintf("%s@%s", userName, clusterName)
return &clientcmdapi.Config{
Clusters: map[string]*clientcmdapi.Cluster{
clusterName: {
Server: serverURL,
CertificateAuthorityData: caCert,
},
},
Contexts: map[string]*clientcmdapi.Context{
contextName: {
Cluster: clusterName,
AuthInfo: userName,
},
},
AuthInfos: map[string]*clientcmdapi.AuthInfo{},
CurrentContext: contextName,
}
}
// CreateWithCerts creates a KubeConfig object with access to the API server with client certificates
func CreateWithCerts(serverURL, clusterName, userName string, caCert []byte, clientKey []byte, clientCert []byte) *clientcmdapi.Config {
config := CreateBasic(serverURL, clusterName, userName, caCert)
config.AuthInfos[userName] = &clientcmdapi.AuthInfo{
ClientKeyData: clientKey,
ClientCertificateData: clientCert,
}
return config
}
// CreateWithToken creates a KubeConfig object with access to the API server with a token
func CreateWithToken(serverURL, clusterName, userName string, caCert []byte, token string) *clientcmdapi.Config {
config := CreateBasic(serverURL, clusterName, userName, caCert)
config.AuthInfos[userName] = &clientcmdapi.AuthInfo{
Token: token,
}
return config
}
// ClientSetFromFile returns a ready-to-use client from a KubeConfig file
func ClientSetFromFile(path string) (*clientset.Clientset, error) {
config, err := clientcmd.LoadFromFile(path)
if err != nil {
return nil, fmt.Errorf("failed to load admin kubeconfig [%v]", err)
}
return KubeConfigToClientSet(config)
}
// KubeConfigToClientSet converts a KubeConfig object to a client
func KubeConfigToClientSet(config *clientcmdapi.Config) (*clientset.Clientset, error) {
clientConfig, err := clientcmd.NewDefaultClientConfig(*config, &clientcmd.ConfigOverrides{}).ClientConfig()
if err != nil {
return nil, fmt.Errorf("failed to create API client configuration from kubeconfig: %v", err)
}
client, err := clientset.NewForConfig(clientConfig)
if err != nil {
return nil, fmt.Errorf("failed to create API client: %v", err)
}
return client, nil
}
// WriteToDisk writes a KubeConfig object down to disk with mode 0600
func WriteToDisk(filename string, kubeconfig *clientcmdapi.Config) error {
err := clientcmd.WriteToFile(*kubeconfig, filename)
if err != nil {
return err
}
fmt.Printf("[kubeconfig] Wrote KubeConfig file to disk: %q\n", filename)
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors.
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.
@ -82,7 +82,7 @@ type configClientWithToken struct {
token string
}
func TestMakeClientConfigWithCerts(t *testing.T) {
func TestCreateWithCerts(t *testing.T) {
var createBasicTest = []struct {
cc configClient
ccWithCerts configClientWithCerts
@ -92,7 +92,7 @@ func TestMakeClientConfigWithCerts(t *testing.T) {
{configClient{clusterName: "kubernetes"}, configClientWithCerts{}, ""},
}
for _, rt := range createBasicTest {
cwc := MakeClientConfigWithCerts(
cwc := CreateWithCerts(
rt.cc.serverURL,
rt.cc.clusterName,
rt.cc.userName,
@ -102,7 +102,7 @@ func TestMakeClientConfigWithCerts(t *testing.T) {
)
if cwc.Kind != rt.expected {
t.Errorf(
"failed MakeClientConfigWithCerts:\n\texpected: %s\n\t actual: %s",
"failed CreateWithCerts:\n\texpected: %s\n\t actual: %s",
rt.expected,
cwc.Kind,
)
@ -110,7 +110,7 @@ func TestMakeClientConfigWithCerts(t *testing.T) {
}
}
func TestMakeClientConfigWithToken(t *testing.T) {
func TestCreateWithToken(t *testing.T) {
var createBasicTest = []struct {
cc configClient
ccWithToken configClientWithToken
@ -120,7 +120,7 @@ func TestMakeClientConfigWithToken(t *testing.T) {
{configClient{clusterName: "kubernetes"}, configClientWithToken{}, ""},
}
for _, rt := range createBasicTest {
cwc := MakeClientConfigWithToken(
cwc := CreateWithToken(
rt.cc.serverURL,
rt.cc.clusterName,
rt.cc.userName,
@ -129,7 +129,7 @@ func TestMakeClientConfigWithToken(t *testing.T) {
)
if cwc.Kind != rt.expected {
t.Errorf(
"failed MakeClientConfigWithCerts:\n\texpected: %s\n\t actual: %s",
"failed CreateWithToken:\n\texpected: %s\n\t actual: %s",
rt.expected,
cwc.Kind,
)
@ -161,7 +161,7 @@ func TestWriteKubeconfigToDisk(t *testing.T) {
{"test2", configClient{clusterName: "kubernetes", userName: "user2", serverURL: "localhost:8080"}, configClientWithToken{token: "cba"}, nil, []byte(configOut2)},
}
for _, rt := range writeConfig {
c := MakeClientConfigWithToken(
c := CreateWithToken(
rt.cc.serverURL,
rt.cc.clusterName,
rt.cc.userName,
@ -169,10 +169,10 @@ func TestWriteKubeconfigToDisk(t *testing.T) {
rt.ccWithToken.token,
)
configPath := filepath.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, fmt.Sprintf("%s.conf", rt.name))
err := WriteKubeconfigToDisk(configPath, c)
err := WriteToDisk(configPath, c)
if err != rt.expected {
t.Errorf(
"failed WriteKubeconfigToDisk with an error:\n\texpected: %s\n\t actual: %s",
"failed WriteToDisk with an error:\n\texpected: %s\n\t actual: %s",
rt.expected,
err,
)
@ -180,7 +180,7 @@ func TestWriteKubeconfigToDisk(t *testing.T) {
newFile, _ := ioutil.ReadFile(configPath)
if !bytes.Equal(newFile, rt.file) {
t.Errorf(
"failed WriteKubeconfigToDisk config write:\n\texpected: %s\n\t actual: %s",
"failed WriteToDisk config write:\n\texpected: %s\n\t actual: %s",
rt.file,
newFile,
)

View File

@ -13,7 +13,7 @@ go_library(
srcs = ["init.go"],
tags = ["automanaged"],
deps = [
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//federation/pkg/kubefed/util:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",

View File

@ -46,7 +46,7 @@ import (
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
certutil "k8s.io/client-go/util/cert"
triple "k8s.io/client-go/util/cert/triple"
kubeadmkubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
"k8s.io/kubernetes/federation/pkg/kubefed/util"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
@ -513,7 +513,7 @@ func createAPIServerCredentialsSecret(clientset *client.Clientset, namespace, cr
}
func createControllerManagerKubeconfigSecret(clientset *client.Clientset, namespace, name, svcName, kubeconfigName string, entKeyPairs *entityKeyPairs, dryRun bool) (*api.Secret, error) {
config := kubeadmkubeconfigphase.MakeClientConfigWithCerts(
config := kubeconfigutil.CreateWithCerts(
fmt.Sprintf("https://%s", svcName),
name,
ControllerManagerUser,

View File

@ -19,6 +19,7 @@ cmd/kubeadm
cmd/kubeadm/app/apis/kubeadm/install
cmd/kubeadm/app/phases/apiconfig
cmd/kubeadm/app/phases/certs
cmd/kubeadm/app/phases/kubeconfig
cmd/kubectl
cmd/kubelet
cmd/libs/go2idl/client-gen