refactor: unique service for tcp and konnectivity server

This commit is contained in:
Dario Tranchitella
2022-07-16 13:41:10 +02:00
parent af6024ece1
commit 161f43ed58
4 changed files with 48 additions and 128 deletions

View File

@@ -70,32 +70,3 @@ func (in *TenantControlPlane) DeclaredControlPlaneAddress(ctx context.Context, c
return "", kamajierrors.MissingValidIPError{}
}
func (in *TenantControlPlane) GetKonnectivityServerAddress(ctx context.Context, client client.Client) (string, error) {
var loadBalancerStatus corev1.LoadBalancerStatus
svc := &corev1.Service{}
err := client.Get(ctx, types.NamespacedName{Namespace: in.GetNamespace(), Name: in.Status.Addons.Konnectivity.Service.Name}, svc)
if err != nil {
return "", errors.Wrap(err, "cannot retrieve Service for Konnectivity")
}
switch {
case len(in.Spec.Addons.Konnectivity.ProxyHost) > 0:
// Returning the hard-coded value in the specification in case of non LoadBalanced resources
return in.Spec.Addons.Konnectivity.ProxyHost, nil
case svc.Spec.Type == corev1.ServiceTypeLoadBalancer:
loadBalancerStatus = svc.Status.LoadBalancer
if len(loadBalancerStatus.Ingress) == 0 {
return "", kamajierrors.NonExposedLoadBalancerError{}
}
for _, lb := range loadBalancerStatus.Ingress {
if ip := lb.IP; len(ip) > 0 {
return ip, nil
}
}
}
return "", kamajierrors.MissingValidIPError{}
}

View File

@@ -60,7 +60,6 @@ func (r *KubernetesServiceResource) Define(ctx context.Context, tenantControlPla
ObjectMeta: metav1.ObjectMeta{
Name: tenantControlPlane.GetName(),
Namespace: tenantControlPlane.GetNamespace(),
Labels: utilities.CommonLabels(tenantControlPlane.GetName()),
},
}
@@ -79,25 +78,25 @@ func (r *KubernetesServiceResource) mutate(ctx context.Context, tenantControlPla
address, _ := tenantControlPlane.DeclaredControlPlaneAddress(ctx, r.Client)
return func() error {
var servicePort corev1.ServicePort
if len(r.resource.Spec.Ports) > 0 {
servicePort = r.resource.Spec.Ports[0]
}
servicePort.Protocol = corev1.ProtocolTCP
servicePort.Port = tenantControlPlane.Spec.NetworkProfile.Port
servicePort.TargetPort = intstr.FromInt(int(tenantControlPlane.Spec.NetworkProfile.Port))
r.resource.Spec.Ports = []corev1.ServicePort{servicePort}
r.resource.Spec.Selector = map[string]string{
"kamaji.clastix.io/soot": tenantControlPlane.GetName(),
}
labels := utilities.MergeMaps(r.resource.GetLabels(), tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Labels)
labels := utilities.MergeMaps(utilities.CommonLabels(tenantControlPlane.GetName()), tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Labels)
r.resource.SetLabels(labels)
annotations := utilities.MergeMaps(r.resource.GetAnnotations(), tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Annotations)
r.resource.SetAnnotations(annotations)
r.resource.Spec.Selector = map[string]string{
"kamaji.clastix.io/soot": tenantControlPlane.GetName(),
}
if len(r.resource.Spec.Ports) == 0 {
r.resource.Spec.Ports = make([]corev1.ServicePort, 1)
}
r.resource.Spec.Ports[0].Name = "kube-apiserver"
r.resource.Spec.Ports[0].Protocol = corev1.ProtocolTCP
r.resource.Spec.Ports[0].Port = tenantControlPlane.Spec.NetworkProfile.Port
r.resource.Spec.Ports[0].TargetPort = intstr.FromInt(int(tenantControlPlane.Spec.NetworkProfile.Port))
switch tenantControlPlane.Spec.ControlPlane.Service.ServiceType {
case kamajiv1alpha1.ServiceTypeLoadBalancer:
r.resource.Spec.Type = corev1.ServiceTypeLoadBalancer

View File

@@ -100,13 +100,9 @@ func (r *Agent) UpdateTenantControlPlaneStatus(ctx context.Context, tenantContro
func (r *Agent) mutate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) controllerutil.MutateFn {
return func() (err error) {
address := tenantControlPlane.Spec.Addons.Konnectivity.ProxyHost
if len(address) == 0 {
// In case of no explicit konnectivity proxy host, using the Tenant Control Plane one
address, _, err = tenantControlPlane.AssignedControlPlaneAddress()
if err != nil {
return err
}
address, _, err := tenantControlPlane.AssignedControlPlaneAddress()
if err != nil {
return err
}
r.resource.SetLabels(utilities.MergeMaps(

View File

@@ -6,10 +6,8 @@ package konnectivity
import (
"context"
"fmt"
"net"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -19,15 +17,13 @@ import (
"github.com/clastix/kamaji/internal/utilities"
)
// ServiceResource must be the first Resource processed by the TenantControlPlane:
// when a TenantControlPlan is expecting a dynamic IP address, the Service will get it from the controller-manager.
type ServiceResource struct {
resource *corev1.Service
Client client.Client
Name string
}
func (r *ServiceResource) ShouldStatusBeUpdated(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
func (r *ServiceResource) ShouldStatusBeUpdated(_ context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
if tenantControlPlane.Status.Addons.Konnectivity.Service.Name != r.resource.GetName() {
return true
}
@@ -36,7 +32,7 @@ func (r *ServiceResource) ShouldStatusBeUpdated(ctx context.Context, tenantContr
return true
}
if tenantControlPlane.Status.Addons.Konnectivity.Service.Port != r.resource.Spec.Ports[0].Port {
if tenantControlPlane.Status.Addons.Konnectivity.Service.Port != r.resource.Spec.Ports[1].Port {
return true
}
@@ -76,22 +72,31 @@ func (r *ServiceResource) ShouldCleanup(tenantControlPlane *kamajiv1alpha1.Tenan
}
func (r *ServiceResource) CleanUp(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) (bool, error) {
if err := r.Client.Delete(ctx, r.resource); err != nil {
if !k8serrors.IsNotFound(err) {
return false, err
res, err := utilities.CreateOrUpdateWithConflict(ctx, r.Client, r.resource, func() error {
for index, port := range r.resource.Spec.Ports {
if port.Port == tenantControlPlane.Spec.Addons.Konnectivity.ProxyPort {
ports := make([]corev1.ServicePort, 0, len(r.resource.Spec.Ports)-1)
ports = append(ports, r.resource.Spec.Ports[:index]...)
ports = append(ports, r.resource.Spec.Ports[index+1:]...)
r.resource.Spec.Ports = ports
return nil
}
}
return false, nil
}
return nil
})
return true, nil
return res == controllerutil.OperationResultUpdated, err
}
func (r *ServiceResource) UpdateTenantControlPlaneStatus(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) error {
func (r *ServiceResource) UpdateTenantControlPlaneStatus(_ context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) error {
if tenantControlPlane.Spec.Addons.Konnectivity != nil {
tenantControlPlane.Status.Addons.Konnectivity.Service.Name = r.resource.GetName()
tenantControlPlane.Status.Addons.Konnectivity.Service.Namespace = r.resource.GetNamespace()
tenantControlPlane.Status.Addons.Konnectivity.Service.Port = r.resource.Spec.Ports[0].Port
tenantControlPlane.Status.Addons.Konnectivity.Service.Port = r.resource.Spec.Ports[1].Port
tenantControlPlane.Status.Addons.Konnectivity.Service.ServiceStatus = r.resource.Status
tenantControlPlane.Status.Addons.Konnectivity.Enabled = true
@@ -104,10 +109,10 @@ func (r *ServiceResource) UpdateTenantControlPlaneStatus(ctx context.Context, te
return nil
}
func (r *ServiceResource) Define(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) error {
func (r *ServiceResource) Define(_ context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) error {
r.resource = &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: r.getPrefixedName(tenantControlPlane),
Name: tenantControlPlane.GetName(),
Namespace: tenantControlPlane.GetNamespace(),
},
}
@@ -119,66 +124,19 @@ func (r *ServiceResource) CreateOrUpdate(ctx context.Context, tenantControlPlane
return controllerutil.CreateOrUpdate(ctx, r.Client, r.resource, r.mutate(ctx, tenantControlPlane))
}
func (r *ServiceResource) mutate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) func() error {
func (r *ServiceResource) mutate(_ context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) func() error {
return func() (err error) {
address, _ := tenantControlPlane.GetKonnectivityServerAddress(ctx, r.Client)
if address == "" {
// The TenantControlPlane is getting a dynamic IP address: retrieving from the status
address, _, err = net.SplitHostPort(tenantControlPlane.Status.ControlPlaneEndpoint)
if err != nil {
return err
}
switch len(r.resource.Spec.Ports) {
case 0:
return fmt.Errorf("current state of the Service is not ready to be mangled for Konnectivity")
case 1:
r.resource.Spec.Ports = append(r.resource.Spec.Ports, corev1.ServicePort{})
}
var servicePort corev1.ServicePort
if len(r.resource.Spec.Ports) > 0 {
servicePort = r.resource.Spec.Ports[0]
}
servicePort.Protocol = corev1.ProtocolTCP
servicePort.Port = tenantControlPlane.Spec.Addons.Konnectivity.ProxyPort
servicePort.TargetPort = intstr.FromInt(int(tenantControlPlane.Spec.Addons.Konnectivity.ProxyPort))
r.resource.Spec.Ports = []corev1.ServicePort{servicePort}
r.resource.Spec.Selector = map[string]string{
"kamaji.clastix.io/soot": tenantControlPlane.GetName(),
}
labels := utilities.MergeMaps(r.resource.GetLabels(), tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Labels)
r.resource.SetLabels(labels)
annotations := utilities.MergeMaps(r.resource.GetAnnotations(), tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Annotations)
r.resource.SetAnnotations(annotations)
isIP := false
switch {
case utilities.IsValidIP(address):
isIP = true
case !utilities.IsValidHostname(address):
return fmt.Errorf("%s is not a valid address for konnectivity proxy server", address)
}
switch tenantControlPlane.Spec.Addons.Konnectivity.ServiceType {
case kamajiv1alpha1.ServiceTypeLoadBalancer:
r.resource.Spec.Type = corev1.ServiceTypeLoadBalancer
if isIP {
r.resource.Spec.LoadBalancerIP = address
}
case kamajiv1alpha1.ServiceTypeNodePort:
r.resource.Spec.Type = corev1.ServiceTypeNodePort
r.resource.Spec.Ports[0].NodePort = tenantControlPlane.Spec.Addons.Konnectivity.ProxyPort
if isIP && tenantControlPlane.Spec.Addons.Konnectivity.AllowAddressAsExternalIP {
r.resource.Spec.ExternalIPs = []string{address}
}
default:
r.resource.Spec.Type = corev1.ServiceTypeClusterIP
if isIP && tenantControlPlane.Spec.Addons.Konnectivity.AllowAddressAsExternalIP {
r.resource.Spec.ExternalIPs = []string{address}
}
}
r.resource.Spec.Ports[1].Name = "konnectivity-server"
r.resource.Spec.Ports[1].Protocol = corev1.ProtocolTCP
r.resource.Spec.Ports[1].Port = tenantControlPlane.Spec.Addons.Konnectivity.ProxyPort
r.resource.Spec.Ports[1].TargetPort = intstr.FromInt(int(tenantControlPlane.Spec.Addons.Konnectivity.ProxyPort))
return controllerutil.SetControllerReference(tenantControlPlane, r.resource, r.Client.Scheme())
}
@@ -187,7 +145,3 @@ func (r *ServiceResource) mutate(ctx context.Context, tenantControlPlane *kamaji
func (r *ServiceResource) GetName() string {
return r.Name
}
func (r *ServiceResource) getPrefixedName(tenantControlPlane *kamajiv1alpha1.TenantControlPlane) string {
return utilities.AddTenantPrefix(r.Name, tenantControlPlane)
}