Merge pull request #10126 from medyagh/extension_context
add annotation to kubeconfig to identify contexts/clusters created by minikubepull/9985/head^2
commit
8b76fa2c46
|
@ -35,8 +35,9 @@ var updateContextCmd = &cobra.Command{
|
|||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cname := ClusterFlagValue()
|
||||
co := mustload.Running(cname)
|
||||
// cluster extension metada for kubeconfig
|
||||
|
||||
updated, err := kubeconfig.UpdateEndpoint(cname, co.CP.Hostname, co.CP.Port, kubeconfig.PathFromEnv())
|
||||
updated, err := kubeconfig.UpdateEndpoint(cname, co.CP.Hostname, co.CP.Port, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
|
||||
if err != nil {
|
||||
exit.Error(reason.HostKubeconfigUpdate, "update config", err)
|
||||
}
|
||||
|
|
|
@ -99,6 +99,8 @@ func SetupCerts(cmd command.Runner, k8s config.KubernetesConfig, n config.Node)
|
|||
ClientCertificate: path.Join(vmpath.GuestKubernetesCertsDir, "apiserver.crt"),
|
||||
ClientKey: path.Join(vmpath.GuestKubernetesCertsDir, "apiserver.key"),
|
||||
CertificateAuthority: path.Join(vmpath.GuestKubernetesCertsDir, "ca.crt"),
|
||||
ExtensionContext: kubeconfig.NewExtension(),
|
||||
ExtensionCluster: kubeconfig.NewExtension(),
|
||||
KeepContext: false,
|
||||
}
|
||||
|
||||
|
|
|
@ -576,14 +576,14 @@ func (k *Bootstrapper) restartControlPlane(cfg config.ClusterConfig) error {
|
|||
klog.Infof("restartCluster took %s", time.Since(start))
|
||||
}()
|
||||
|
||||
version, err := util.ParseKubernetesVersion(cfg.KubernetesConfig.KubernetesVersion)
|
||||
k8sVersion, err := util.ParseKubernetesVersion(cfg.KubernetesConfig.KubernetesVersion)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "parsing Kubernetes version")
|
||||
}
|
||||
|
||||
phase := "alpha"
|
||||
controlPlane := "controlplane"
|
||||
if version.GTE(semver.MustParse("1.13.0")) {
|
||||
if k8sVersion.GTE(semver.MustParse("1.13.0")) {
|
||||
phase = "init"
|
||||
controlPlane = "control-plane"
|
||||
}
|
||||
|
@ -603,7 +603,7 @@ func (k *Bootstrapper) restartControlPlane(cfg config.ClusterConfig) error {
|
|||
}
|
||||
|
||||
// Save the costly tax of reinstalling Kubernetes if the only issue is a missing kube context
|
||||
_, err = kubeconfig.UpdateEndpoint(cfg.Name, hostname, port, kubeconfig.PathFromEnv())
|
||||
_, err = kubeconfig.UpdateEndpoint(cfg.Name, hostname, port, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
|
||||
if err != nil {
|
||||
klog.Warningf("unable to update kubeconfig (cluster will likely require a reset): %v", err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/minikube/pkg/version"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// implementing the runtime.Object internally so we can write extensions to kubeconfig
|
||||
type Extension struct {
|
||||
runtime.TypeMeta `json:",inline"`
|
||||
Version string `json:"version"`
|
||||
Provider string `json:"provider"`
|
||||
LastUpdate string `json:"last-update"`
|
||||
}
|
||||
|
||||
// NewExtension returns a minikube formated kubeconfig's extension block to idenity clusters and contexts
|
||||
func NewExtension() *Extension {
|
||||
return &Extension{
|
||||
Provider: "minikube.sigs.k8s.io",
|
||||
Version: version.GetVersion(),
|
||||
// time format matching other RFC in notify.go
|
||||
LastUpdate: time.Now().Format(time.RFC1123)}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Extension.
|
||||
func (in *Extension) DeepCopy() *Extension {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Extension)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Extension) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Extension) DeepCopyInto(out *Extension) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
}
|
|
@ -105,7 +105,7 @@ func Endpoint(contextName string, configPath ...string) (string, int, error) {
|
|||
}
|
||||
|
||||
// UpdateEndpoint overwrites the IP stored in kubeconfig with the provided IP.
|
||||
func UpdateEndpoint(contextName string, hostname string, port int, confpath string) (bool, error) {
|
||||
func UpdateEndpoint(contextName string, hostname string, port int, confpath string, ext *Extension) (bool, error) {
|
||||
if hostname == "" {
|
||||
return false, fmt.Errorf("empty ip")
|
||||
}
|
||||
|
@ -136,6 +136,9 @@ func UpdateEndpoint(contextName string, hostname string, port int, confpath stri
|
|||
CertificateAuthority: path.Join(gp, "ca.crt"),
|
||||
KeepContext: false,
|
||||
}
|
||||
if ext != nil {
|
||||
kcs.ExtensionCluster = ext
|
||||
}
|
||||
err = PopulateFromSettings(kcs, cfg)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "populating kubeconfig")
|
||||
|
|
|
@ -410,7 +410,7 @@ func TestUpdateIP(t *testing.T) {
|
|||
t.Parallel()
|
||||
configFilename := tempFile(t, test.existing)
|
||||
defer os.Remove(configFilename)
|
||||
statusActual, err := UpdateEndpoint("minikube", test.hostname, test.port, configFilename)
|
||||
statusActual, err := UpdateEndpoint("minikube", test.hostname, test.port, configFilename, nil)
|
||||
if err != nil && !test.err {
|
||||
t.Errorf("Got unexpected error: %v", err)
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ func TestUpdateIP(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
if !configEquals(actual, expected) {
|
||||
t.Fatal("configs did not match")
|
||||
t.Fatalf("configs did not match: Actual:\n%+v\n Expected:\n%+v", actual, expected)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/juju/mutex"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/minikube/pkg/util/lock"
|
||||
|
@ -54,6 +55,12 @@ type Settings struct {
|
|||
// Should the certificate files be embedded instead of referenced by path
|
||||
EmbedCerts bool
|
||||
|
||||
// Extension meta data for the cluster
|
||||
ExtensionCluster *Extension
|
||||
|
||||
// Extension meta data for the cluster
|
||||
ExtensionContext *Extension
|
||||
|
||||
// kubeConfigFile is the path where the kube config is stored
|
||||
// Only access this with atomic ops
|
||||
kubeConfigFile atomic.Value
|
||||
|
@ -83,6 +90,10 @@ func PopulateFromSettings(cfg *Settings, apiCfg *api.Config) error {
|
|||
} else {
|
||||
cluster.CertificateAuthority = cfg.CertificateAuthority
|
||||
}
|
||||
|
||||
if cfg.ExtensionCluster != nil {
|
||||
cluster.Extensions = map[string]runtime.Object{"cluster_info": cfg.ExtensionCluster.DeepCopy()}
|
||||
}
|
||||
apiCfg.Clusters[clusterName] = cluster
|
||||
|
||||
// user
|
||||
|
@ -109,6 +120,10 @@ func PopulateFromSettings(cfg *Settings, apiCfg *api.Config) error {
|
|||
context.Cluster = cfg.ClusterName
|
||||
context.Namespace = cfg.Namespace
|
||||
context.AuthInfo = userName
|
||||
if cfg.ExtensionContext != nil {
|
||||
context.Extensions = map[string]runtime.Object{"context_info": cfg.ExtensionContext.DeepCopy()}
|
||||
}
|
||||
|
||||
apiCfg.Contexts[contextName] = context
|
||||
|
||||
// Only set current context to minikube if the user has not used the keepContext flag
|
||||
|
@ -138,6 +153,9 @@ func Update(kcs *Settings) error {
|
|||
return err
|
||||
}
|
||||
|
||||
ext := NewExtension()
|
||||
kcs.ExtensionCluster = ext
|
||||
kcs.ExtensionContext = ext
|
||||
err = PopulateFromSettings(kcs, kcfg)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue