Skip to content

Commit 8756981

Browse files
committed
Fix kube_config generation function at rancher2_cluster, rancher2_cluster_v2 and rancher2_cluster_sync for Rancher 2.6.0 and above
1 parent 6d3f7e1 commit 8756981

6 files changed

Lines changed: 183 additions & 8 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
k8s.io/api v0.22.3
1717
k8s.io/apimachinery v0.22.3
1818
k8s.io/apiserver v0.22.3
19+
k8s.io/client-go v12.0.0+incompatible
1920
)
2021

2122
replace (

rancher2/resource_rancher2_cluster.go

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
norman "github.com/rancher/norman/types"
1313
managementClient "github.com/rancher/rancher/pkg/client/generated/management/v3"
1414
projectClient "github.com/rancher/rancher/pkg/client/generated/project/v3"
15+
"k8s.io/client-go/kubernetes"
16+
"k8s.io/client-go/tools/clientcmd"
1517
)
1618

1719
func resourceRancher2Cluster() *schema.Resource {
@@ -238,7 +240,7 @@ func resourceRancher2ClusterRead(d *schema.ResourceData, meta interface{}) error
238240
return err
239241
}
240242

241-
kubeConfig, err := getClusterKubeconfig(meta.(*Config), cluster.ID)
243+
kubeConfig, err := getClusterKubeconfig(meta.(*Config), cluster.ID, d.Get("kube_config").(string))
242244
if err != nil && !IsForbidden(err) {
243245
return err
244246
}
@@ -584,10 +586,81 @@ func createClusterRegistrationToken(client *managementClient.Client, clusterID s
584586
return newRegToken, nil
585587
}
586588

587-
func getClusterKubeconfig(c *Config, id string) (*managementClient.GenerateKubeConfigOutput, error) {
589+
func isKubeConfigValid(c *Config, config string) (string, bool, error) {
590+
token, tokenValid, err := isKubeConfigTokenValid(c, config)
591+
if err != nil {
592+
return "", false, err
593+
}
594+
if !tokenValid {
595+
return "", false, nil
596+
}
597+
kubeconfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(config))
598+
if err != nil {
599+
return "", false, fmt.Errorf("Checking Kubeconfig: %v", err)
600+
}
601+
_, err = kubernetes.NewForConfig(kubeconfig)
602+
if err != nil {
603+
return token, false, nil
604+
}
605+
606+
return token, true, nil
607+
}
608+
609+
func isKubeConfigTokenValid(c *Config, config string) (string, bool, error) {
610+
token, err := getTokenFromKubeConfig(config)
611+
if err != nil {
612+
return "", false, fmt.Errorf("Getting Kubeconfig token: %v", err)
613+
}
614+
isValid, err := isTokenValid(c, splitTokenID(token))
615+
if err != nil {
616+
return "", false, fmt.Errorf("Checking Kubeconfig token: %v", err)
617+
}
618+
return token, isValid, nil
619+
}
620+
621+
func replaceKubeConfigToken(c *Config, config, token string) (string, error) {
622+
if len(token) == 0 {
623+
return config, nil
624+
}
625+
kubeconfig, err := getObjFromKubeConfig(config)
626+
if err != nil {
627+
return "", fmt.Errorf("Getting K8s config object: %v", err)
628+
}
629+
if kubeconfig == nil || kubeconfig.AuthInfos == nil || len(kubeconfig.AuthInfos) == 0 {
630+
return config, nil
631+
}
632+
633+
client, err := c.ManagementClient()
634+
if err != nil {
635+
return "", fmt.Errorf("Replacing cluster Kubeconfig token: %v", err)
636+
}
637+
removeToken, err := client.Token.ByID(splitTokenID(kubeconfig.AuthInfos[0].AuthInfo.Token))
638+
if err != nil {
639+
if !IsNotFound(err) && !IsForbidden(err) {
640+
return "", err
641+
}
642+
}
643+
644+
err = client.Token.Delete(removeToken)
645+
if err != nil {
646+
return "", fmt.Errorf("Error removing Token: %s", err)
647+
}
648+
kubeconfig.AuthInfos[0].AuthInfo.Token = token
649+
return getKubeConfigFromObj(kubeconfig)
650+
}
651+
652+
func getClusterKubeconfig(c *Config, id, origconfig string) (*managementClient.GenerateKubeConfigOutput, error) {
588653
action := "generateKubeconfig"
589654
cluster := &Cluster{}
590655

656+
token, kubeValid, err := isKubeConfigValid(c, origconfig)
657+
if err != nil {
658+
return nil, fmt.Errorf("Getting cluster Kubeconfig: %v", err)
659+
}
660+
if kubeValid {
661+
return &managementClient.GenerateKubeConfigOutput{Config: origconfig}, nil
662+
}
663+
591664
client, err := c.ManagementClient()
592665
if err != nil {
593666
return nil, fmt.Errorf("Getting cluster Kubeconfig: %v", err)
@@ -621,6 +694,13 @@ func getClusterKubeconfig(c *Config, id string) (*managementClient.GenerateKubeC
621694
}
622695
err = client.APIBaseClient.Action(managementClient.ClusterType, action, clusterResource, nil, kubeConfig)
623696
if err == nil {
697+
if isRancher26 && len(token) > 0 {
698+
newConfig, err := replaceKubeConfigToken(c, kubeConfig.Config, token)
699+
if err != nil {
700+
return nil, err
701+
}
702+
kubeConfig.Config = newConfig
703+
}
624704
return kubeConfig, nil
625705
}
626706
if !IsNotFound(err) && !IsForbidden(err) && !IsServiceUnavailableError(err) {

rancher2/resource_rancher2_cluster_sync.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,7 @@ func resourceRancher2ClusterSyncRead(d *schema.ResourceData, meta interface{}) e
8888
d.Set("default_project_id", defaultProjectID)
8989
d.Set("system_project_id", systemProjectID)
9090

91-
client, err := meta.(*Config).ManagementClient()
92-
if err != nil {
93-
return err
94-
}
95-
kubeConfig, err := client.Cluster.ActionGenerateKubeconfig(clus)
91+
kubeConfig, err := getClusterKubeconfig(meta.(*Config), clusterID, d.Get("kube_config").(string))
9692
if err != nil {
9793
return err
9894
}

rancher2/resource_rancher2_cluster_v2.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ func setClusterV2LegacyData(d *schema.ResourceData, c *Config) error {
342342
return fmt.Errorf("Setting cluster V2 legacy data: %v", err)
343343
}
344344

345-
kubeConfig, err := getClusterKubeconfig(c, cluster.ID)
345+
kubeConfig, err := getClusterKubeconfig(c, cluster.ID, d.Get("kube_config").(string))
346346
if err != nil {
347347
return fmt.Errorf("Setting cluster V2 legacy data: %v", err)
348348
}

rancher2/resource_rancher2_token.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,24 @@ func resourceRancher2TokenDelete(d *schema.ResourceData, meta interface{}) error
117117
d.SetId("")
118118
return nil
119119
}
120+
121+
func isTokenValid(c *Config, id string) (bool, error) {
122+
if len(id) == 0 {
123+
return false, nil
124+
}
125+
126+
client, err := c.ManagementClient()
127+
if err != nil {
128+
return false, err
129+
}
130+
131+
token, err := client.Token.ByID(id)
132+
if err != nil {
133+
if !IsNotFound(err) && !IsForbidden(err) {
134+
return false, err
135+
}
136+
return false, nil
137+
}
138+
// Token is valid if it's enabled and not expired
139+
return (token.Enabled != nil && *token.Enabled && !token.Expired), nil
140+
}

rancher2/util.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/rancher/norman/types"
2525
"golang.org/x/crypto/bcrypt"
2626
"gopkg.in/yaml.v2"
27+
kubeconfig "k8s.io/client-go/tools/clientcmd/api/v1"
2728
)
2829

2930
const (
@@ -67,6 +68,82 @@ func IsBase64(s string) bool {
6768
return err == nil
6869
}
6970

71+
func getKubeConfigFromObj(kubeconfig *kubeconfig.Config) (string, error) {
72+
if kubeconfig == nil {
73+
return "", nil
74+
}
75+
config, err := interfaceToMap(kubeconfig)
76+
if err != nil {
77+
return "", err
78+
}
79+
80+
return mapInterfaceToYAML(config)
81+
}
82+
83+
func getObjFromKubeConfig(config string) (*kubeconfig.Config, error) {
84+
kubeconfig := &kubeconfig.Config{}
85+
if len(config) == 0 {
86+
return kubeconfig, nil
87+
}
88+
kubeconfigMap, err := ghodssyamlToMapInterface(config)
89+
if err != nil {
90+
return nil, fmt.Errorf("Yaml unmarshall kube_config %v", err)
91+
}
92+
kubeconfigJSON, err := mapInterfaceToJSON(kubeconfigMap)
93+
if err != nil {
94+
return nil, fmt.Errorf("Json marshall kube_config: %v", err)
95+
}
96+
err = jsonToInterface(kubeconfigJSON, kubeconfig)
97+
if err != nil {
98+
return nil, fmt.Errorf("Json unmarshall kube_config: %v", err)
99+
}
100+
101+
return kubeconfig, nil
102+
}
103+
104+
func getTokenFromKubeConfig(config string) (string, error) {
105+
if len(config) == 0 {
106+
return "", nil
107+
}
108+
kubeconfig, err := getObjFromKubeConfig(config)
109+
if err != nil {
110+
return "", err
111+
}
112+
if kubeconfig == nil || kubeconfig.AuthInfos == nil || len(kubeconfig.AuthInfos) == 0 {
113+
return "", nil
114+
}
115+
116+
return kubeconfig.AuthInfos[0].AuthInfo.Token, nil
117+
}
118+
119+
func getTokenIDFromKubeConfig(config string) (string, error) {
120+
token, err := getTokenFromKubeConfig(config)
121+
if err != nil {
122+
return "", err
123+
}
124+
return splitTokenID(token), nil
125+
126+
}
127+
128+
func updateKubeConfigToken(config, token string) (string, error) {
129+
if len(token) == 0 {
130+
return config, nil
131+
}
132+
if len(config) == 0 {
133+
return "", nil
134+
}
135+
kubeconfig := &kubeconfig.Config{}
136+
err := jsonToInterface(config, kubeconfig)
137+
if err != nil {
138+
return "", err
139+
}
140+
if kubeconfig == nil || kubeconfig.AuthInfos == nil || len(kubeconfig.AuthInfos) == 0 {
141+
return "", nil
142+
}
143+
144+
return kubeconfig.AuthInfos[0].AuthInfo.Token, nil
145+
}
146+
70147
func TrimSpace(val interface{}) string {
71148
return strings.TrimSpace(val.(string))
72149
}

0 commit comments

Comments
 (0)