Skip to content

Commit 8b76fa2

Browse files
authored
Merge pull request #10126 from medyagh/extension_context
add annotation to kubeconfig to identify contexts/clusters created by minikube
2 parents 3b2d962 + 89a8cdc commit 8b76fa2

File tree

7 files changed

+97
-7
lines changed

7 files changed

+97
-7
lines changed

cmd/minikube/cmd/update-context.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ var updateContextCmd = &cobra.Command{
3535
Run: func(cmd *cobra.Command, args []string) {
3636
cname := ClusterFlagValue()
3737
co := mustload.Running(cname)
38+
// cluster extension metada for kubeconfig
3839

39-
updated, err := kubeconfig.UpdateEndpoint(cname, co.CP.Hostname, co.CP.Port, kubeconfig.PathFromEnv())
40+
updated, err := kubeconfig.UpdateEndpoint(cname, co.CP.Hostname, co.CP.Port, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
4041
if err != nil {
4142
exit.Error(reason.HostKubeconfigUpdate, "update config", err)
4243
}

pkg/minikube/bootstrapper/certs.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ func SetupCerts(cmd command.Runner, k8s config.KubernetesConfig, n config.Node)
9999
ClientCertificate: path.Join(vmpath.GuestKubernetesCertsDir, "apiserver.crt"),
100100
ClientKey: path.Join(vmpath.GuestKubernetesCertsDir, "apiserver.key"),
101101
CertificateAuthority: path.Join(vmpath.GuestKubernetesCertsDir, "ca.crt"),
102+
ExtensionContext: kubeconfig.NewExtension(),
103+
ExtensionCluster: kubeconfig.NewExtension(),
102104
KeepContext: false,
103105
}
104106

pkg/minikube/bootstrapper/kubeadm/kubeadm.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,14 +576,14 @@ func (k *Bootstrapper) restartControlPlane(cfg config.ClusterConfig) error {
576576
klog.Infof("restartCluster took %s", time.Since(start))
577577
}()
578578

579-
version, err := util.ParseKubernetesVersion(cfg.KubernetesConfig.KubernetesVersion)
579+
k8sVersion, err := util.ParseKubernetesVersion(cfg.KubernetesConfig.KubernetesVersion)
580580
if err != nil {
581581
return errors.Wrap(err, "parsing Kubernetes version")
582582
}
583583

584584
phase := "alpha"
585585
controlPlane := "controlplane"
586-
if version.GTE(semver.MustParse("1.13.0")) {
586+
if k8sVersion.GTE(semver.MustParse("1.13.0")) {
587587
phase = "init"
588588
controlPlane = "control-plane"
589589
}
@@ -603,7 +603,7 @@ func (k *Bootstrapper) restartControlPlane(cfg config.ClusterConfig) error {
603603
}
604604

605605
// Save the costly tax of reinstalling Kubernetes if the only issue is a missing kube context
606-
_, err = kubeconfig.UpdateEndpoint(cfg.Name, hostname, port, kubeconfig.PathFromEnv())
606+
_, err = kubeconfig.UpdateEndpoint(cfg.Name, hostname, port, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
607607
if err != nil {
608608
klog.Warningf("unable to update kubeconfig (cluster will likely require a reset): %v", err)
609609
}

pkg/minikube/kubeconfig/extension.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package kubeconfig
18+
19+
import (
20+
"time"
21+
22+
"k8s.io/apimachinery/pkg/runtime"
23+
"k8s.io/minikube/pkg/version"
24+
)
25+
26+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
27+
// implementing the runtime.Object internally so we can write extensions to kubeconfig
28+
type Extension struct {
29+
runtime.TypeMeta `json:",inline"`
30+
Version string `json:"version"`
31+
Provider string `json:"provider"`
32+
LastUpdate string `json:"last-update"`
33+
}
34+
35+
// NewExtension returns a minikube formated kubeconfig's extension block to idenity clusters and contexts
36+
func NewExtension() *Extension {
37+
return &Extension{
38+
Provider: "minikube.sigs.k8s.io",
39+
Version: version.GetVersion(),
40+
// time format matching other RFC in notify.go
41+
LastUpdate: time.Now().Format(time.RFC1123)}
42+
}
43+
44+
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Extension.
45+
func (in *Extension) DeepCopy() *Extension {
46+
if in == nil {
47+
return nil
48+
}
49+
out := new(Extension)
50+
in.DeepCopyInto(out)
51+
return out
52+
}
53+
54+
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
55+
func (in *Extension) DeepCopyObject() runtime.Object {
56+
if c := in.DeepCopy(); c != nil {
57+
return c
58+
}
59+
return nil
60+
}
61+
62+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
63+
func (in *Extension) DeepCopyInto(out *Extension) {
64+
*out = *in
65+
out.TypeMeta = in.TypeMeta
66+
}

pkg/minikube/kubeconfig/kubeconfig.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func Endpoint(contextName string, configPath ...string) (string, int, error) {
105105
}
106106

107107
// UpdateEndpoint overwrites the IP stored in kubeconfig with the provided IP.
108-
func UpdateEndpoint(contextName string, hostname string, port int, confpath string) (bool, error) {
108+
func UpdateEndpoint(contextName string, hostname string, port int, confpath string, ext *Extension) (bool, error) {
109109
if hostname == "" {
110110
return false, fmt.Errorf("empty ip")
111111
}
@@ -136,6 +136,9 @@ func UpdateEndpoint(contextName string, hostname string, port int, confpath stri
136136
CertificateAuthority: path.Join(gp, "ca.crt"),
137137
KeepContext: false,
138138
}
139+
if ext != nil {
140+
kcs.ExtensionCluster = ext
141+
}
139142
err = PopulateFromSettings(kcs, cfg)
140143
if err != nil {
141144
return false, errors.Wrap(err, "populating kubeconfig")

pkg/minikube/kubeconfig/kubeconfig_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ func TestUpdateIP(t *testing.T) {
410410
t.Parallel()
411411
configFilename := tempFile(t, test.existing)
412412
defer os.Remove(configFilename)
413-
statusActual, err := UpdateEndpoint("minikube", test.hostname, test.port, configFilename)
413+
statusActual, err := UpdateEndpoint("minikube", test.hostname, test.port, configFilename, nil)
414414
if err != nil && !test.err {
415415
t.Errorf("Got unexpected error: %v", err)
416416
}
@@ -430,7 +430,7 @@ func TestUpdateIP(t *testing.T) {
430430
t.Fatal(err)
431431
}
432432
if !configEquals(actual, expected) {
433-
t.Fatal("configs did not match")
433+
t.Fatalf("configs did not match: Actual:\n%+v\n Expected:\n%+v", actual, expected)
434434
}
435435
})
436436

pkg/minikube/kubeconfig/settings.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323

2424
"github.com/juju/mutex"
2525
"github.com/pkg/errors"
26+
"k8s.io/apimachinery/pkg/runtime"
2627
"k8s.io/client-go/tools/clientcmd/api"
2728
"k8s.io/klog/v2"
2829
"k8s.io/minikube/pkg/util/lock"
@@ -54,6 +55,12 @@ type Settings struct {
5455
// Should the certificate files be embedded instead of referenced by path
5556
EmbedCerts bool
5657

58+
// Extension meta data for the cluster
59+
ExtensionCluster *Extension
60+
61+
// Extension meta data for the cluster
62+
ExtensionContext *Extension
63+
5764
// kubeConfigFile is the path where the kube config is stored
5865
// Only access this with atomic ops
5966
kubeConfigFile atomic.Value
@@ -83,6 +90,10 @@ func PopulateFromSettings(cfg *Settings, apiCfg *api.Config) error {
8390
} else {
8491
cluster.CertificateAuthority = cfg.CertificateAuthority
8592
}
93+
94+
if cfg.ExtensionCluster != nil {
95+
cluster.Extensions = map[string]runtime.Object{"cluster_info": cfg.ExtensionCluster.DeepCopy()}
96+
}
8697
apiCfg.Clusters[clusterName] = cluster
8798

8899
// user
@@ -109,6 +120,10 @@ func PopulateFromSettings(cfg *Settings, apiCfg *api.Config) error {
109120
context.Cluster = cfg.ClusterName
110121
context.Namespace = cfg.Namespace
111122
context.AuthInfo = userName
123+
if cfg.ExtensionContext != nil {
124+
context.Extensions = map[string]runtime.Object{"context_info": cfg.ExtensionContext.DeepCopy()}
125+
}
126+
112127
apiCfg.Contexts[contextName] = context
113128

114129
// Only set current context to minikube if the user has not used the keepContext flag
@@ -138,6 +153,9 @@ func Update(kcs *Settings) error {
138153
return err
139154
}
140155

156+
ext := NewExtension()
157+
kcs.ExtensionCluster = ext
158+
kcs.ExtensionContext = ext
141159
err = PopulateFromSettings(kcs, kcfg)
142160
if err != nil {
143161
return err

0 commit comments

Comments
 (0)