mirror of https://github.com/k3s-io/k3s
Merge pull request #4967 from jlowdermilk/kubeconfig
Simplify generating kubeconfig with embeded cert datapull/6/head
commit
662189ebc2
|
@ -15,6 +15,12 @@ Sets a cluster entry in .kubeconfig
|
|||
|
||||
kubectl config set-cluster name [--server=server] [--certificate-authority=path/to/certficate/authority] [--api-version=apiversion] [--insecure-skip-tls-verify=true]
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--embed-certs=false: embed-certs for the cluster entry in .kubeconfig
|
||||
```
|
||||
|
||||
### Options inherrited from parent commands
|
||||
|
||||
```
|
||||
|
|
|
@ -28,6 +28,12 @@ Sets a user entry in .kubeconfig
|
|||
|
||||
kubectl config set-credentials name [--auth-path=authfile] [--client-certificate=certfile] [--client-key=keyfile] [--token=bearer_token] [--username=basic_user] [--password=basic_password]
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--embed-certs=false: embed client cert/key for the user entry in .kubeconfig
|
||||
```
|
||||
|
||||
### Options inherrited from parent commands
|
||||
|
||||
```
|
||||
|
|
|
@ -20,6 +20,12 @@ Sets a cluster entry in .kubeconfig
|
|||
only sets the certificate\-authority field on the e2e cluster entry without touching other values.
|
||||
|
||||
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-\-embed\-certs\fP=false
|
||||
embed\-certs for the cluster entry in .kubeconfig
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-alsologtostderr\fP=false
|
||||
|
|
|
@ -45,6 +45,12 @@ Basic auth flags:
|
|||
Bearer token and basic auth are mutually exclusive.
|
||||
|
||||
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-\-embed\-certs\fP=false
|
||||
embed client cert/key for the user entry in .kubeconfig
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-alsologtostderr\fP=false
|
||||
|
|
|
@ -81,6 +81,7 @@ const (
|
|||
FlagCertFile = "client-certificate"
|
||||
FlagKeyFile = "client-key"
|
||||
FlagCAFile = "certificate-authority"
|
||||
FlagEmbedCerts = "embed-certs"
|
||||
FlagBearerToken = "token"
|
||||
FlagUsername = "username"
|
||||
FlagPassword = "password"
|
||||
|
|
|
@ -167,6 +167,56 @@ func TestAdditionalAuth(t *testing.T) {
|
|||
test.run(t)
|
||||
}
|
||||
|
||||
func TestEmbedClientCert(t *testing.T) {
|
||||
fakeCertFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(fakeCertFile.Name())
|
||||
fakeData := []byte("fake-data")
|
||||
ioutil.WriteFile(fakeCertFile.Name(), fakeData, 0600)
|
||||
expectedConfig := newRedFederalCowHammerConfig()
|
||||
authInfo := clientcmdapi.NewAuthInfo()
|
||||
authInfo.ClientCertificateData = fakeData
|
||||
expectedConfig.AuthInfos["another-user"] = *authInfo
|
||||
|
||||
test := configCommandTest{
|
||||
args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=" + fakeCertFile.Name(), "--" + clientcmd.FlagEmbedCerts + "=true"},
|
||||
startingConfig: newRedFederalCowHammerConfig(),
|
||||
expectedConfig: expectedConfig,
|
||||
}
|
||||
|
||||
test.run(t)
|
||||
}
|
||||
|
||||
func TestEmbedClientKey(t *testing.T) {
|
||||
fakeKeyFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(fakeKeyFile.Name())
|
||||
fakeData := []byte("fake-data")
|
||||
ioutil.WriteFile(fakeKeyFile.Name(), fakeData, 0600)
|
||||
expectedConfig := newRedFederalCowHammerConfig()
|
||||
authInfo := clientcmdapi.NewAuthInfo()
|
||||
authInfo.ClientKeyData = fakeData
|
||||
expectedConfig.AuthInfos["another-user"] = *authInfo
|
||||
|
||||
test := configCommandTest{
|
||||
args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagKeyFile + "=" + fakeKeyFile.Name(), "--" + clientcmd.FlagEmbedCerts + "=true"},
|
||||
startingConfig: newRedFederalCowHammerConfig(),
|
||||
expectedConfig: expectedConfig,
|
||||
}
|
||||
|
||||
test.run(t)
|
||||
}
|
||||
|
||||
func TestEmbedNoKeyOrCertDisallowed(t *testing.T) {
|
||||
expectedConfig := newRedFederalCowHammerConfig()
|
||||
test := configCommandTest{
|
||||
args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagEmbedCerts + "=true"},
|
||||
startingConfig: newRedFederalCowHammerConfig(),
|
||||
expectedConfig: expectedConfig,
|
||||
expectedOutputs: []string{"--client-certificate", "--client-key", "embed"},
|
||||
}
|
||||
|
||||
test.run(t)
|
||||
}
|
||||
|
||||
func TestEmptyTokenAndCertAllowed(t *testing.T) {
|
||||
expectedConfig := newRedFederalCowHammerConfig()
|
||||
authInfo := clientcmdapi.NewAuthInfo()
|
||||
|
@ -375,6 +425,45 @@ func TestInsecureClearsCA(t *testing.T) {
|
|||
test.run(t)
|
||||
}
|
||||
|
||||
func TestCADataClearsCA(t *testing.T) {
|
||||
fakeCAFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(fakeCAFile.Name())
|
||||
fakeData := []byte("cadata")
|
||||
ioutil.WriteFile(fakeCAFile.Name(), fakeData, 0600)
|
||||
|
||||
clusterInfoWithCAData := clientcmdapi.NewCluster()
|
||||
clusterInfoWithCAData.CertificateAuthorityData = fakeData
|
||||
|
||||
clusterInfoWithCA := clientcmdapi.NewCluster()
|
||||
clusterInfoWithCA.CertificateAuthority = "cafile"
|
||||
|
||||
startingConfig := newRedFederalCowHammerConfig()
|
||||
startingConfig.Clusters["another-cluster"] = *clusterInfoWithCA
|
||||
|
||||
expectedConfig := newRedFederalCowHammerConfig()
|
||||
expectedConfig.Clusters["another-cluster"] = *clusterInfoWithCAData
|
||||
|
||||
test := configCommandTest{
|
||||
args: []string{"set-cluster", "another-cluster", "--" + clientcmd.FlagCAFile + "=" + fakeCAFile.Name(), "--" + clientcmd.FlagEmbedCerts + "=true"},
|
||||
startingConfig: startingConfig,
|
||||
expectedConfig: expectedConfig,
|
||||
}
|
||||
|
||||
test.run(t)
|
||||
}
|
||||
|
||||
func TestEmbedNoCADisallowed(t *testing.T) {
|
||||
expectedConfig := newRedFederalCowHammerConfig()
|
||||
test := configCommandTest{
|
||||
args: []string{"set-cluster", "another-cluster", "--" + clientcmd.FlagEmbedCerts + "=true"},
|
||||
startingConfig: newRedFederalCowHammerConfig(),
|
||||
expectedConfig: expectedConfig,
|
||||
expectedOutputs: []string{"--certificate-authority", "embed"},
|
||||
}
|
||||
|
||||
test.run(t)
|
||||
}
|
||||
|
||||
func TestCAAndInsecureDisallowed(t *testing.T) {
|
||||
test := configCommandTest{
|
||||
args: []string{"set-cluster", "another-cluster", "--" + clientcmd.FlagCAFile + "=cafile", "--" + clientcmd.FlagInsecure + "=true"},
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -38,6 +39,7 @@ type createAuthInfoOptions struct {
|
|||
token util.StringFlag
|
||||
username util.StringFlag
|
||||
password util.StringFlag
|
||||
embedCertData util.BoolFlag
|
||||
}
|
||||
|
||||
func NewCmdConfigSetAuthInfo(out io.Writer, pathOptions *pathOptions) *cobra.Command {
|
||||
|
@ -78,11 +80,12 @@ func NewCmdConfigSetAuthInfo(out io.Writer, pathOptions *pathOptions) *cobra.Com
|
|||
}
|
||||
|
||||
cmd.Flags().Var(&options.authPath, clientcmd.FlagAuthPath, clientcmd.FlagAuthPath+" for the user entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.clientCertificate, clientcmd.FlagCertFile, clientcmd.FlagCertFile+" for the user entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.clientKey, clientcmd.FlagKeyFile, clientcmd.FlagKeyFile+" for the user entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.clientCertificate, clientcmd.FlagCertFile, "path to "+clientcmd.FlagCertFile+" for the user entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.clientKey, clientcmd.FlagKeyFile, "path to "+clientcmd.FlagKeyFile+" for the user entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.token, clientcmd.FlagBearerToken, clientcmd.FlagBearerToken+" for the user entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.username, clientcmd.FlagUsername, clientcmd.FlagUsername+" for the user entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.password, clientcmd.FlagPassword, clientcmd.FlagPassword+" for the user entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.embedCertData, clientcmd.FlagEmbedCerts, "embed client cert/key for the user entry in .kubeconfig")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -120,15 +123,27 @@ func (o *createAuthInfoOptions) modifyAuthInfo(existingAuthInfo clientcmdapi.Aut
|
|||
}
|
||||
|
||||
if o.clientCertificate.Provided() {
|
||||
modifiedAuthInfo.ClientCertificate = o.clientCertificate.Value()
|
||||
if len(modifiedAuthInfo.ClientCertificate) > 0 {
|
||||
modifiedAuthInfo.ClientCertificateData = nil
|
||||
certPath := o.clientCertificate.Value()
|
||||
if o.embedCertData.Value() {
|
||||
modifiedAuthInfo.ClientCertificateData, _ = ioutil.ReadFile(certPath)
|
||||
modifiedAuthInfo.ClientCertificate = ""
|
||||
} else {
|
||||
modifiedAuthInfo.ClientCertificate = certPath
|
||||
if len(modifiedAuthInfo.ClientCertificate) > 0 {
|
||||
modifiedAuthInfo.ClientCertificateData = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if o.clientKey.Provided() {
|
||||
modifiedAuthInfo.ClientKey = o.clientKey.Value()
|
||||
if len(modifiedAuthInfo.ClientKey) > 0 {
|
||||
modifiedAuthInfo.ClientKeyData = nil
|
||||
keyPath := o.clientKey.Value()
|
||||
if o.embedCertData.Value() {
|
||||
modifiedAuthInfo.ClientKeyData, _ = ioutil.ReadFile(keyPath)
|
||||
modifiedAuthInfo.ClientKey = ""
|
||||
} else {
|
||||
modifiedAuthInfo.ClientKey = keyPath
|
||||
if len(modifiedAuthInfo.ClientKey) > 0 {
|
||||
modifiedAuthInfo.ClientKeyData = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,6 +200,23 @@ func (o createAuthInfoOptions) validate() error {
|
|||
if len(methods) > 1 {
|
||||
return fmt.Errorf("You cannot specify more than one authentication method at the same time: %v", strings.Join(methods, ", "))
|
||||
}
|
||||
if o.embedCertData.Value() {
|
||||
certPath := o.clientCertificate.Value()
|
||||
keyPath := o.clientKey.Value()
|
||||
if certPath == "" && keyPath == "" {
|
||||
return fmt.Errorf("You must specify a --%s or --%s to embed", clientcmd.FlagCertFile, clientcmd.FlagKeyFile)
|
||||
}
|
||||
if certPath != "" {
|
||||
if _, err := ioutil.ReadFile(certPath); err != nil {
|
||||
return fmt.Errorf("Error reading %s data from %s: %v", clientcmd.FlagCertFile, certPath, err)
|
||||
}
|
||||
}
|
||||
if keyPath != "" {
|
||||
if _, err := ioutil.ReadFile(keyPath); err != nil {
|
||||
return fmt.Errorf("Error reading %s data from %s: %v", clientcmd.FlagKeyFile, keyPath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
|
@ -35,6 +36,7 @@ type createClusterOptions struct {
|
|||
apiVersion util.StringFlag
|
||||
insecureSkipTLSVerify util.BoolFlag
|
||||
certificateAuthority util.StringFlag
|
||||
embedCAData util.BoolFlag
|
||||
}
|
||||
|
||||
func NewCmdConfigSetCluster(out io.Writer, pathOptions *pathOptions) *cobra.Command {
|
||||
|
@ -66,7 +68,8 @@ func NewCmdConfigSetCluster(out io.Writer, pathOptions *pathOptions) *cobra.Comm
|
|||
cmd.Flags().Var(&options.server, clientcmd.FlagAPIServer, clientcmd.FlagAPIServer+" for the cluster entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.apiVersion, clientcmd.FlagAPIVersion, clientcmd.FlagAPIVersion+" for the cluster entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.insecureSkipTLSVerify, clientcmd.FlagInsecure, clientcmd.FlagInsecure+" for the cluster entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.certificateAuthority, clientcmd.FlagCAFile, clientcmd.FlagCAFile+" for the cluster entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.certificateAuthority, clientcmd.FlagCAFile, "path to "+clientcmd.FlagCAFile+" for the cluster entry in .kubeconfig")
|
||||
cmd.Flags().Var(&options.embedCAData, clientcmd.FlagEmbedCerts, clientcmd.FlagEmbedCerts+" for the cluster entry in .kubeconfig")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -116,11 +119,18 @@ func (o *createClusterOptions) modifyCluster(existingCluster clientcmdapi.Cluste
|
|||
}
|
||||
}
|
||||
if o.certificateAuthority.Provided() {
|
||||
modifiedCluster.CertificateAuthority = o.certificateAuthority.Value()
|
||||
// Specifying a certificate authority file clears certificate authority data and insecure mode
|
||||
if modifiedCluster.CertificateAuthority != "" {
|
||||
modifiedCluster.CertificateAuthorityData = nil
|
||||
caPath := o.certificateAuthority.Value()
|
||||
if o.embedCAData.Value() {
|
||||
modifiedCluster.CertificateAuthorityData, _ = ioutil.ReadFile(caPath)
|
||||
modifiedCluster.InsecureSkipTLSVerify = false
|
||||
modifiedCluster.CertificateAuthority = ""
|
||||
} else {
|
||||
modifiedCluster.CertificateAuthority = caPath
|
||||
// Specifying a certificate authority file clears certificate authority data and insecure mode
|
||||
if caPath != "" {
|
||||
modifiedCluster.InsecureSkipTLSVerify = false
|
||||
modifiedCluster.CertificateAuthorityData = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,6 +155,15 @@ func (o createClusterOptions) validate() error {
|
|||
if o.insecureSkipTLSVerify.Value() && o.certificateAuthority.Value() != "" {
|
||||
return errors.New("You cannot specify a certificate authority and insecure mode at the same time")
|
||||
}
|
||||
if o.embedCAData.Value() {
|
||||
caPath := o.certificateAuthority.Value()
|
||||
if caPath == "" {
|
||||
return fmt.Errorf("You must specify a --%s to embed", clientcmd.FlagCAFile)
|
||||
}
|
||||
if _, err := ioutil.ReadFile(caPath); err != nil {
|
||||
return fmt.Errorf("Could not read %s data from %s: %v", clientcmd.FlagCAFile, caPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue