mirror of
https://github.com/outbackdingo/kamaji.git
synced 2026-01-27 10:19:29 +00:00
refactor: unique service for tcp and konnectivity server
This commit is contained in:
@@ -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{}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user