mirror of
https://github.com/rancher/k3k.git
synced 2026-08-19 04:16:16 +00:00
Merge branch 'main' into fix-ingress
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
|
||||
@@ -98,7 +99,8 @@ func (c *ClusterReconciler) Reconcile(ctx context.Context, req reconcile.Request
|
||||
}
|
||||
|
||||
// update Status HostVersion
|
||||
cluster.Status.HostVersion = fmt.Sprintf("v%s.%s.0-k3s1", hostVersion.Major, hostVersion.Minor)
|
||||
k8sVersion := strings.Split(hostVersion.GitVersion, "+")[0]
|
||||
cluster.Status.HostVersion = k8sVersion + "-k3s1"
|
||||
if err := c.Client.Status().Update(ctx, &cluster); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ var _ = Describe("Cluster Controller", func() {
|
||||
|
||||
serverVersion, err := k8s.DiscoveryClient.ServerVersion()
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
expectedHostVersion := fmt.Sprintf("v%s.%s.0-k3s1", serverVersion.Major, serverVersion.Minor)
|
||||
expectedHostVersion := fmt.Sprintf("%s-k3s1", serverVersion.GitVersion)
|
||||
|
||||
Eventually(func() string {
|
||||
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(cluster), cluster)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -12,7 +13,9 @@ import (
|
||||
"github.com/rancher/k3k/pkg/controller"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
type ControlRuntimeBootstrap struct {
|
||||
@@ -171,3 +174,24 @@ func DecodedBootstrap(token, ip string) (*ControlRuntimeBootstrap, error) {
|
||||
|
||||
return bootstrap, nil
|
||||
}
|
||||
|
||||
func GetFromSecret(ctx context.Context, client client.Client, cluster *v1alpha1.Cluster) (*ControlRuntimeBootstrap, error) {
|
||||
key := types.NamespacedName{
|
||||
Name: controller.SafeConcatNameWithPrefix(cluster.Name, "bootstrap"),
|
||||
Namespace: cluster.Namespace,
|
||||
}
|
||||
|
||||
var bootstrapSecret v1.Secret
|
||||
if err := client.Get(ctx, key, &bootstrapSecret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bootstrapData := bootstrapSecret.Data["bootstrap"]
|
||||
if bootstrapData == nil {
|
||||
return nil, errors.New("empty bootstrap")
|
||||
}
|
||||
|
||||
var bootstrap ControlRuntimeBootstrap
|
||||
err := json.Unmarshal(bootstrapData, &bootstrap)
|
||||
return &bootstrap, err
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ package kubeconfig
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -17,7 +15,7 @@ import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
@@ -29,72 +27,45 @@ type KubeConfig struct {
|
||||
ExpiryDate time.Duration
|
||||
}
|
||||
|
||||
func (k *KubeConfig) Extract(ctx context.Context, client client.Client, cluster *v1alpha1.Cluster, hostServerIP string) ([]byte, error) {
|
||||
nn := types.NamespacedName{
|
||||
Name: controller.SafeConcatNameWithPrefix(cluster.Name, "bootstrap"),
|
||||
Namespace: cluster.Namespace,
|
||||
func New() *KubeConfig {
|
||||
return &KubeConfig{
|
||||
CN: controller.AdminCommonName,
|
||||
ORG: []string{user.SystemPrivilegedGroup},
|
||||
ExpiryDate: 0,
|
||||
}
|
||||
|
||||
var bootstrapSecret v1.Secret
|
||||
if err := client.Get(ctx, nn, &bootstrapSecret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bootstrapData := bootstrapSecret.Data["bootstrap"]
|
||||
if bootstrapData == nil {
|
||||
return nil, errors.New("empty bootstrap")
|
||||
}
|
||||
|
||||
var bootstrap bootstrap.ControlRuntimeBootstrap
|
||||
if err := json.Unmarshal(bootstrapData, &bootstrap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
adminCert, adminKey, err := certs.CreateClientCertKey(
|
||||
k.CN, k.ORG,
|
||||
&k.AltNames, []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, k.ExpiryDate,
|
||||
bootstrap.ClientCA.Content,
|
||||
bootstrap.ClientCAKey.Content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// get the server service to extract the right IP
|
||||
nn = types.NamespacedName{
|
||||
Name: server.ServiceName(cluster.Name),
|
||||
Namespace: cluster.Namespace,
|
||||
}
|
||||
|
||||
var k3kService v1.Service
|
||||
if err := client.Get(ctx, nn, &k3kService); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://%s:%d", k3kService.Spec.ClusterIP, server.ServerPort)
|
||||
if k3kService.Spec.Type == v1.ServiceTypeNodePort {
|
||||
nodePort := k3kService.Spec.Ports[0].NodePort
|
||||
url = fmt.Sprintf("https://%s:%d", hostServerIP, nodePort)
|
||||
}
|
||||
if cluster.Spec.Expose.Ingress.Enabled {
|
||||
var k3kIngress networkingv1.Ingress
|
||||
nn = types.NamespacedName{
|
||||
Name: server.IngressName(cluster.Name),
|
||||
Namespace: cluster.Namespace,
|
||||
}
|
||||
|
||||
if err := client.Get(ctx, nn, &k3kIngress); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
url = fmt.Sprintf("https://%s", k3kIngress.Spec.Rules[0].Host)
|
||||
}
|
||||
kubeconfigData, err := kubeconfig(url, []byte(bootstrap.ServerCA.Content), adminCert, adminKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return kubeconfigData, nil
|
||||
}
|
||||
|
||||
func kubeconfig(url string, serverCA, clientCert, clientKey []byte) ([]byte, error) {
|
||||
func (k *KubeConfig) Extract(ctx context.Context, client client.Client, cluster *v1alpha1.Cluster, hostServerIP string) (*clientcmdapi.Config, error) {
|
||||
bootstrapData, err := bootstrap.GetFromSecret(ctx, client, cluster)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
serverCACert := []byte(bootstrapData.ServerCA.Content)
|
||||
|
||||
adminCert, adminKey, err := certs.CreateClientCertKey(
|
||||
k.CN,
|
||||
k.ORG,
|
||||
&k.AltNames,
|
||||
[]x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
k.ExpiryDate,
|
||||
bootstrapData.ClientCA.Content,
|
||||
bootstrapData.ClientCAKey.Content,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
url, err := getURLFromService(ctx, client, cluster, hostServerIP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config := NewConfig(url, serverCACert, adminCert, adminKey)
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func NewConfig(url string, serverCA, clientCert, clientKey []byte) *clientcmdapi.Config {
|
||||
config := clientcmdapi.NewConfig()
|
||||
|
||||
cluster := clientcmdapi.NewCluster()
|
||||
@@ -114,10 +85,39 @@ func kubeconfig(url string, serverCA, clientCert, clientKey []byte) ([]byte, err
|
||||
config.Contexts["default"] = context
|
||||
config.CurrentContext = "default"
|
||||
|
||||
kubeconfig, err := clientcmd.Write(*config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return config
|
||||
}
|
||||
|
||||
func getURLFromService(ctx context.Context, client client.Client, cluster *v1alpha1.Cluster, hostServerIP string) (string, error) {
|
||||
// get the server service to extract the right IP
|
||||
key := types.NamespacedName{
|
||||
Name: server.ServiceName(cluster.Name),
|
||||
Namespace: cluster.Namespace,
|
||||
}
|
||||
|
||||
return kubeconfig, nil
|
||||
var k3kService v1.Service
|
||||
if err := client.Get(ctx, key, &k3kService); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://%s:%d", k3kService.Spec.ClusterIP, server.ServerPort)
|
||||
|
||||
if k3kService.Spec.Type == v1.ServiceTypeNodePort {
|
||||
nodePort := k3kService.Spec.Ports[0].NodePort
|
||||
url = fmt.Sprintf("https://%s:%d", hostServerIP, nodePort)
|
||||
}
|
||||
if cluster.Spec.Expose.Ingress.Enabled {
|
||||
var k3kIngress networkingv1.Ingress
|
||||
ingressKey = types.NamespacedName{
|
||||
Name: server.IngressName(cluster.Name),
|
||||
Namespace: cluster.Namespace,
|
||||
}
|
||||
|
||||
if err := client.Get(ctx, ingressKey, &k3kIngress); err != nil {
|
||||
return "", err
|
||||
}
|
||||
url = fmt.Sprintf("https://%s", k3kIngress.Spec.Rules[0].Host)
|
||||
}
|
||||
|
||||
return url, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user