fix: using the announced ip address as source of truth

This commit is contained in:
Dario Tranchitella
2022-07-18 19:03:56 +00:00
parent 605d54716a
commit b2a23b0691
7 changed files with 50 additions and 15 deletions
+27 -1
View File
@@ -5,6 +5,9 @@ package v1alpha1
import (
"context"
"fmt"
"net"
"strconv"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
@@ -14,7 +17,30 @@ import (
kamajierrors "github.com/clastix/kamaji/internal/errors"
)
func (in *TenantControlPlane) GetControlPlaneAddress(ctx context.Context, client client.Client) (string, error) {
// AssignedControlPlaneAddress returns the announced address and port of a Tenant Control Plane.
// In case of non-well formed values, or missing announcement, an error is returned.
func (in *TenantControlPlane) AssignedControlPlaneAddress() (string, int32, error) {
if len(in.Status.ControlPlaneEndpoint) == 0 {
return "", 0, fmt.Errorf("the Tenant Control Plane is not yet exposed")
}
address, portString, err := net.SplitHostPort(in.Status.ControlPlaneEndpoint)
if err != nil {
return "", 0, errors.Wrap(err, "cannot split host port from Tenant Control Plane endpoint")
}
port, err := strconv.Atoi(portString)
if err != nil {
return "", 0, errors.Wrap(err, "cannot convert Tenant Control Plane port from endpoint")
}
return address, int32(port), nil
}
// DeclaredControlPlaneAddress returns the desired Tenant Control Plane address.
// In case of dynamic allocation, e.g. using a Load Balancer, it queries the API Server looking for the allocated IP.
// When an IP has not been yet assigned, or it is expected, an error is returned.
func (in *TenantControlPlane) DeclaredControlPlaneAddress(ctx context.Context, client client.Client) (string, error) {
var loadBalancerStatus corev1.LoadBalancerStatus
svc := &corev1.Service{}
-1
View File
@@ -115,7 +115,6 @@ func getKubeadmConfigResources(c client.Client, tcpReconcilerConfig TenantContro
return []resources.Resource{
&resources.KubeadmConfigResource{
Name: "kubeadmconfig",
Port: tenantControlPlane.Spec.NetworkProfile.Port,
KubernetesVersion: tenantControlPlane.Spec.Kubernetes.Version,
PodCIDR: tenantControlPlane.Spec.NetworkProfile.PodCIDR,
ServiceCIDR: tenantControlPlane.Spec.NetworkProfile.ServiceCIDR,
+2 -1
View File
@@ -7,9 +7,10 @@ import (
"bytes"
"context"
"fmt"
"io/ioutil"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"io/ioutil"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
@@ -58,7 +58,7 @@ func (r *KubernetesDeploymentResource) Define(_ context.Context, tenantControlPl
func (r *KubernetesDeploymentResource) mutate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) controllerutil.MutateFn {
return func() error {
address, err := tenantControlPlane.GetControlPlaneAddress(ctx, r.Client)
address, _, err := tenantControlPlane.AssignedControlPlaneAddress()
if err != nil {
return errors.Wrap(err, "cannot create TenantControlPlane Deployment")
}
+1 -1
View File
@@ -68,7 +68,7 @@ func (r *KubernetesServiceResource) CreateOrUpdate(ctx context.Context, tenantCo
func (r *KubernetesServiceResource) mutate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) controllerutil.MutateFn {
// We don't need to check error here: in case of dynamic external IP, the Service must be created in advance.
// After that, the specific cloud controller-manager will provide an IP that will be then used.
address, _ := tenantControlPlane.GetControlPlaneAddress(ctx, r.Client)
address, _ := tenantControlPlane.DeclaredControlPlaneAddress(ctx, r.Client)
return func() error {
var servicePort corev1.ServicePort
+13 -9
View File
@@ -32,7 +32,7 @@ type KubeadmConfigResource struct {
}
func (r *KubeadmConfigResource) ShouldStatusBeUpdated(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
address, err := getAddress(ctx, r.Client, *tenantControlPlane)
address, _, err := tenantControlPlane.AssignedControlPlaneAddress()
if err != nil {
return true
}
@@ -66,12 +66,7 @@ func (r *KubeadmConfigResource) getPrefixedName(tenantControlPlane *kamajiv1alph
}
func (r *KubeadmConfigResource) CreateOrUpdate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) (controllerutil.OperationResult, error) {
address, err := getAddress(ctx, r.Client, *tenantControlPlane)
if err != nil {
return controllerutil.OperationResultNone, err
}
return utilities.CreateOrUpdateWithConflict(ctx, r.Client, r.resource, r.mutate(tenantControlPlane, address))
return utilities.CreateOrUpdateWithConflict(ctx, r.Client, r.resource, r.mutate(tenantControlPlane))
}
func (r *KubeadmConfigResource) GetName() string {
@@ -79,7 +74,10 @@ func (r *KubeadmConfigResource) GetName() string {
}
func (r *KubeadmConfigResource) UpdateTenantControlPlaneStatus(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) error {
address, _ := getAddress(ctx, r.Client, *tenantControlPlane)
address, _, err := tenantControlPlane.AssignedControlPlaneAddress()
if err != nil {
return err
}
tenantControlPlane.Status.KubeadmConfig.LastUpdate = metav1.Now()
tenantControlPlane.Status.KubeadmConfig.Checksum = r.resource.GetAnnotations()["checksum"]
@@ -97,11 +95,17 @@ func (r *KubeadmConfigResource) getControlPlaneEndpoint(tenantControlPlane *kama
return fmt.Sprintf("%s:%d", address, tenantControlPlane.Spec.NetworkProfile.Port)
}
func (r *KubeadmConfigResource) mutate(tenantControlPlane *kamajiv1alpha1.TenantControlPlane, address string) controllerutil.MutateFn {
func (r *KubeadmConfigResource) mutate(tenantControlPlane *kamajiv1alpha1.TenantControlPlane) controllerutil.MutateFn {
return func() error {
address, _, err := tenantControlPlane.AssignedControlPlaneAddress()
if err != nil {
return err
}
r.resource.SetLabels(utilities.KamajiLabels())
params := kubeadm.Parameters{
TenantControlPlaneAddress: address,
TenantControlPlaneName: tenantControlPlane.GetName(),
TenantControlPlaneNamespace: tenantControlPlane.GetNamespace(),
TenantControlPlaneEndpoint: r.getControlPlaneEndpoint(tenantControlPlane, address),
+6 -1
View File
@@ -24,13 +24,18 @@ func KubeadmPhaseCreate(ctx context.Context, r KubeadmPhaseResource, tenantContr
return controllerutil.OperationResultNone, err
}
address, _, err := tenantControlPlane.AssignedControlPlaneAddress()
if err != nil {
return controllerutil.OperationResultNone, err
}
config.Kubeconfig = *kubeconfig
config.Parameters = kubeadm.Parameters{
TenantControlPlaneName: tenantControlPlane.GetName(),
TenantDNSServiceIPs: tenantControlPlane.Spec.NetworkProfile.DNSServiceIPs,
TenantControlPlaneVersion: tenantControlPlane.Spec.Kubernetes.Version,
TenantControlPlanePodCIDR: tenantControlPlane.Spec.NetworkProfile.PodCIDR,
TenantControlPlaneAddress: tenantControlPlane.Spec.NetworkProfile.Address,
TenantControlPlaneAddress: address,
TenantControlPlaneCertSANs: tenantControlPlane.Spec.NetworkProfile.CertSANs,
TenantControlPlanePort: tenantControlPlane.Spec.NetworkProfile.Port,
TenantControlPlaneCGroupDriver: tenantControlPlane.Spec.Kubernetes.Kubelet.CGroupFS.String(),