Skip to content

Commit 5ef9254

Browse files
xrstfembik
authored andcommitted
include a shard-base context in kubeconfigs
On-behalf-of: @SAP [email protected] Signed-off-by: Marvin Beckers <[email protected]>
1 parent 1f72490 commit 5ef9254

File tree

2 files changed

+96
-54
lines changed

2 files changed

+96
-54
lines changed

internal/controller/kubeconfig_controller.go

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"context"
2121
"errors"
2222
"fmt"
23-
"net/url"
2423
"time"
2524

2625
certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
@@ -73,42 +72,39 @@ func (r *KubeconfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
7372
return ctrl.Result{}, err
7473
}
7574

75+
rootShard := &operatorv1alpha1.RootShard{}
76+
shard := &operatorv1alpha1.Shard{}
77+
7678
var (
77-
clientCertIssuer, serverCA, serverURL, serverName string
79+
clientCertIssuer string
80+
serverCA string
7881
)
7982

8083
switch {
8184
case kc.Spec.Target.RootShardRef != nil:
82-
var rootShard operatorv1alpha1.RootShard
83-
if err := r.Get(ctx, types.NamespacedName{Name: kc.Spec.Target.RootShardRef.Name, Namespace: req.Namespace}, &rootShard); err != nil {
85+
if err := r.Get(ctx, types.NamespacedName{Name: kc.Spec.Target.RootShardRef.Name, Namespace: req.Namespace}, rootShard); err != nil {
8486
return ctrl.Result{}, fmt.Errorf("failed to get RootShard: %w", err)
8587
}
8688

87-
clientCertIssuer = resources.GetRootShardCAName(&rootShard, operatorv1alpha1.ClientCA)
88-
serverCA = resources.GetRootShardCAName(&rootShard, operatorv1alpha1.ServerCA)
89-
serverURL = resources.GetRootShardBaseURL(&rootShard)
90-
serverName = rootShard.Name
89+
clientCertIssuer = resources.GetRootShardCAName(rootShard, operatorv1alpha1.ClientCA)
90+
serverCA = resources.GetRootShardCAName(rootShard, operatorv1alpha1.ServerCA)
9191

9292
case kc.Spec.Target.ShardRef != nil:
93-
var shard operatorv1alpha1.Shard
94-
if err := r.Get(ctx, types.NamespacedName{Name: kc.Spec.Target.ShardRef.Name, Namespace: req.Namespace}, &shard); err != nil {
93+
if err := r.Get(ctx, types.NamespacedName{Name: kc.Spec.Target.ShardRef.Name, Namespace: req.Namespace}, shard); err != nil {
9594
return ctrl.Result{}, fmt.Errorf("failed to get Shard: %w", err)
9695
}
9796

9897
ref := shard.Spec.RootShard.Reference
9998
if ref == nil || ref.Name == "" {
10099
return ctrl.Result{}, errors.New("the Shard does not reference a (valid) RootShard")
101100
}
102-
var rootShard operatorv1alpha1.RootShard
103-
if err := r.Get(ctx, types.NamespacedName{Name: ref.Name, Namespace: req.Namespace}, &rootShard); err != nil {
101+
if err := r.Get(ctx, types.NamespacedName{Name: ref.Name, Namespace: req.Namespace}, rootShard); err != nil {
104102
return ctrl.Result{}, fmt.Errorf("failed to get RootShard: %w", err)
105103
}
106104

107105
// The client CA is shared among all shards and owned by the root shard.
108-
clientCertIssuer = resources.GetRootShardCAName(&rootShard, operatorv1alpha1.ClientCA)
109-
serverCA = resources.GetRootShardCAName(&rootShard, operatorv1alpha1.ServerCA)
110-
serverURL = resources.GetShardBaseURL(&shard)
111-
serverName = shard.Name
106+
clientCertIssuer = resources.GetRootShardCAName(rootShard, operatorv1alpha1.ClientCA)
107+
serverCA = resources.GetRootShardCAName(rootShard, operatorv1alpha1.ServerCA)
112108

113109
case kc.Spec.Target.FrontProxyRef != nil:
114110
var frontProxy operatorv1alpha1.FrontProxy
@@ -120,15 +116,12 @@ func (r *KubeconfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
120116
if ref == nil || ref.Name == "" {
121117
return ctrl.Result{}, errors.New("the FrontProxy does not reference a (valid) RootShard")
122118
}
123-
var rootShard operatorv1alpha1.RootShard
124-
if err := r.Get(ctx, types.NamespacedName{Name: frontProxy.Spec.RootShard.Reference.Name, Namespace: req.Namespace}, &rootShard); err != nil {
119+
if err := r.Get(ctx, types.NamespacedName{Name: frontProxy.Spec.RootShard.Reference.Name, Namespace: req.Namespace}, rootShard); err != nil {
125120
return ctrl.Result{}, fmt.Errorf("failed to get RootShard: %w", err)
126121
}
127122

128-
clientCertIssuer = resources.GetRootShardCAName(&rootShard, operatorv1alpha1.FrontProxyClientCA)
129-
serverCA = resources.GetRootShardCAName(&rootShard, operatorv1alpha1.ServerCA)
130-
serverURL = fmt.Sprintf("https://%s:6443", rootShard.Spec.External.Hostname)
131-
serverName = rootShard.Spec.External.Hostname
123+
clientCertIssuer = resources.GetRootShardCAName(rootShard, operatorv1alpha1.FrontProxyClientCA)
124+
serverCA = resources.GetRootShardCAName(rootShard, operatorv1alpha1.ServerCA)
132125

133126
default:
134127
return ctrl.Result{}, fmt.Errorf("no valid target for kubeconfig found")
@@ -156,14 +149,12 @@ func (r *KubeconfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
156149
return ctrl.Result{RequeueAfter: time.Second * 5}, nil
157150
}
158151

159-
rootWSURL, err := url.JoinPath(serverURL, "clusters", "root")
152+
reconciler, err := kubeconfig.KubeconfigSecretReconciler(&kc, rootShard, shard, serverCASecret, clientCertSecret)
160153
if err != nil {
161154
return ctrl.Result{}, err
162155
}
163156

164-
if err := k8creconciling.ReconcileSecrets(ctx, []k8creconciling.NamedSecretReconcilerFactory{
165-
kubeconfig.KubeconfigSecretReconciler(&kc, serverCASecret, clientCertSecret, serverName, rootWSURL),
166-
}, req.Namespace, r.Client); err != nil {
157+
if err := k8creconciling.ReconcileSecrets(ctx, []k8creconciling.NamedSecretReconcilerFactory{reconciler}, req.Namespace, r.Client); err != nil {
167158
return ctrl.Result{}, err
168159
}
169160

internal/resources/kubeconfig/secret.go

Lines changed: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,49 +18,100 @@ package kubeconfig
1818

1919
import (
2020
"fmt"
21+
"net/url"
2122

2223
"k8c.io/reconciler/pkg/reconciling"
2324

2425
corev1 "k8s.io/api/core/v1"
2526
"k8s.io/client-go/tools/clientcmd"
2627
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
2728

29+
"github.com/kcp-dev/kcp-operator/internal/resources"
2830
operatorv1alpha1 "github.com/kcp-dev/kcp-operator/sdk/apis/operator/v1alpha1"
2931
)
3032

31-
func KubeconfigSecretReconciler(kubeconfig *operatorv1alpha1.Kubeconfig, caSecret, certSecret *corev1.Secret, serverName, serverURL string) reconciling.NamedSecretReconcilerFactory {
32-
return func() (string, reconciling.SecretReconciler) {
33-
return kubeconfig.Spec.SecretRef.Name, func(secret *corev1.Secret) (*corev1.Secret, error) {
34-
var config *clientcmdapi.Config
33+
func KubeconfigSecretReconciler(
34+
kubeconfig *operatorv1alpha1.Kubeconfig,
35+
rootShard *operatorv1alpha1.RootShard,
36+
shard *operatorv1alpha1.Shard,
37+
caSecret, certSecret *corev1.Secret,
38+
) (reconciling.NamedSecretReconcilerFactory, error) {
39+
config := &clientcmdapi.Config{
40+
Clusters: map[string]*clientcmdapi.Cluster{},
41+
Contexts: map[string]*clientcmdapi.Context{},
42+
AuthInfos: map[string]*clientcmdapi.AuthInfo{
43+
kubeconfig.Spec.Username: {
44+
ClientCertificateData: certSecret.Data["tls.crt"],
45+
ClientKeyData: certSecret.Data["tls.key"],
46+
},
47+
},
48+
}
3549

36-
if secret.Data == nil {
37-
secret.Data = make(map[string][]byte)
38-
}
50+
addCluster := func(name, url string) {
51+
config.Clusters[name] = &clientcmdapi.Cluster{
52+
Server: url,
53+
CertificateAuthorityData: caSecret.Data["tls.crt"],
54+
}
55+
config.Contexts[name] = &clientcmdapi.Context{
56+
Cluster: name,
57+
AuthInfo: kubeconfig.Spec.Username,
58+
}
59+
}
3960

40-
config = &clientcmdapi.Config{}
61+
switch {
62+
case kubeconfig.Spec.Target.RootShardRef != nil:
63+
if rootShard == nil {
64+
panic("RootShard must be provided when kubeconfig targets one.")
65+
}
4166

42-
config.Clusters = map[string]*clientcmdapi.Cluster{
43-
serverName: {
44-
Server: serverURL,
45-
CertificateAuthorityData: caSecret.Data["tls.crt"],
46-
},
47-
}
67+
serverURL := resources.GetRootShardBaseURL(rootShard)
68+
defaultURL, err := url.JoinPath(serverURL, "clusters", "root")
69+
if err != nil {
70+
return nil, err
71+
}
4872

49-
contextName := fmt.Sprintf("%s:%s", serverName, kubeconfig.Spec.Username)
73+
addCluster("default", defaultURL)
74+
addCluster("base", serverURL)
75+
config.CurrentContext = "default"
5076

51-
config.Contexts = map[string]*clientcmdapi.Context{
52-
contextName: {
53-
Cluster: serverName,
54-
AuthInfo: kubeconfig.Spec.Username,
55-
},
56-
}
57-
config.AuthInfos = map[string]*clientcmdapi.AuthInfo{
58-
kubeconfig.Spec.Username: {
59-
ClientCertificateData: certSecret.Data["tls.crt"],
60-
ClientKeyData: certSecret.Data["tls.key"],
61-
},
77+
case kubeconfig.Spec.Target.ShardRef != nil:
78+
if shard == nil {
79+
panic("Shard must be provided when kubeconfig targets one.")
80+
}
81+
82+
serverURL := resources.GetShardBaseURL(shard)
83+
defaultURL, err := url.JoinPath(serverURL, "clusters", "root")
84+
if err != nil {
85+
return nil, err
86+
}
87+
88+
addCluster("default", defaultURL)
89+
addCluster("base", serverURL)
90+
config.CurrentContext = "default"
91+
92+
case kubeconfig.Spec.Target.FrontProxyRef != nil:
93+
if rootShard == nil {
94+
panic("RootShard must be provided when kubeconfig targets a FrontProxy.")
95+
}
96+
97+
serverURL := fmt.Sprintf("https://%s:6443", rootShard.Spec.External.Hostname)
98+
defaultURL, err := url.JoinPath(serverURL, "clusters", "root")
99+
if err != nil {
100+
return nil, err
101+
}
102+
103+
addCluster("default", defaultURL)
104+
config.CurrentContext = "default"
105+
106+
default:
107+
panic("Called reconciler for an invalid kubeconfig, this should not have happened.")
108+
}
109+
110+
return func() (string, reconciling.SecretReconciler) {
111+
return kubeconfig.Spec.SecretRef.Name, func(secret *corev1.Secret) (*corev1.Secret, error) {
112+
if secret.Data == nil {
113+
secret.Data = make(map[string][]byte)
62114
}
63-
config.CurrentContext = contextName
64115

65116
data, err := clientcmd.Write(*config)
66117
if err != nil {
@@ -71,5 +122,5 @@ func KubeconfigSecretReconciler(kubeconfig *operatorv1alpha1.Kubeconfig, caSecre
71122

72123
return secret, nil
73124
}
74-
}
125+
}, nil
75126
}

0 commit comments

Comments
 (0)