feat(konnectivity): reconciliation performed by soot manager

This commit is contained in:
Dario Tranchitella
2022-12-12 11:17:47 +01:00
parent 1a80fc5b28
commit 4c51eafc90
14 changed files with 259 additions and 149 deletions

View File

@@ -120,7 +120,6 @@ type KubeadmPhasesStatus struct {
type ExternalKubernetesObjectStatus struct {
Name string `json:"name,omitempty"`
Namespace string `json:"namespace,omitempty"`
Checksum string `json:"checksum,omitempty"`
// Last time when k8s object was updated
LastUpdate metav1.Time `json:"lastUpdate,omitempty"`
}

View File

@@ -150,6 +150,7 @@ func NewCmd(scheme *runtime.Scheme) *cobra.Command {
MigrateCABundle: webhookCABundle,
MigrateServiceName: managerServiceName,
MigrateServiceNamespace: managerServiceName,
AdminClient: mgr.GetClient(),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to set up soot manager")

View File

@@ -72,13 +72,13 @@ func getDefaultResources(config GroupResourceBuilderConfiguration) []resources.R
resources = append(resources, getKubernetesCertificatesResources(config.client, config.tcpReconcilerConfig, config.tenantControlPlane)...)
resources = append(resources, getKubeconfigResources(config.client, config.tcpReconcilerConfig, config.tenantControlPlane)...)
resources = append(resources, getKubernetesStorageResources(config.client, config.Connection, config.DataStore)...)
resources = append(resources, getInternalKonnectivityResources(config.client)...)
resources = append(resources, getKonnectivityServerRequirementsResources(config.client)...)
resources = append(resources, getKubernetesDeploymentResources(config.client, config.tcpReconcilerConfig, config.DataStore)...)
resources = append(resources, getKonnectivityServerPatchResources(config.client)...)
resources = append(resources, getDataStoreMigratingCleanup(config.client, config.KamajiNamespace)...)
resources = append(resources, getKubernetesIngressResources(config.client)...)
resources = append(resources, getKubeadmPhaseResources(config.client)...)
resources = append(resources, getKubeadmAddonResources(config.client)...)
resources = append(resources, getExternalKonnectivityResources(config.client)...)
return resources
}
@@ -264,17 +264,15 @@ func getKubeadmAddonResources(c client.Client) []resources.Resource {
}
}
func getExternalKonnectivityResources(c client.Client) []resources.Resource {
func GetExternalKonnectivityResources(c client.Client) []resources.Resource {
return []resources.Resource{
&konnectivity.Agent{Client: c},
&konnectivity.ServiceAccountResource{Client: c},
&konnectivity.ClusterRoleBindingResource{Client: c},
&konnectivity.KubernetesDeploymentResource{Client: c},
&konnectivity.ServiceResource{Client: c},
&konnectivity.Agent{Client: c},
}
}
func getInternalKonnectivityResources(c client.Client) []resources.Resource {
func getKonnectivityServerRequirementsResources(c client.Client) []resources.Resource {
return []resources.Resource{
&konnectivity.EgressSelectorConfigurationResource{Client: c},
&konnectivity.CertificateResource{Client: c},
@@ -282,6 +280,13 @@ func getInternalKonnectivityResources(c client.Client) []resources.Resource {
}
}
func getKonnectivityServerPatchResources(c client.Client) []resources.Resource {
return []resources.Resource{
&konnectivity.KubernetesDeploymentResource{Client: c},
&konnectivity.ServiceResource{Client: c},
}
}
func getNamespacedName(namespace string, name string) k8stypes.NamespacedName {
return k8stypes.NamespacedName{Namespace: namespace, Name: name}
}

View File

@@ -0,0 +1,110 @@
// Copyright 2022 Clastix Labs
// SPDX-License-Identifier: Apache-2.0
package controllers
import (
"context"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/types"
controllerruntime "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
"github.com/clastix/kamaji/controllers"
"github.com/clastix/kamaji/controllers/utils"
"github.com/clastix/kamaji/internal/resources"
"github.com/clastix/kamaji/internal/resources/konnectivity"
)
type KonnectivityAgent struct {
AdminClient client.Client
GetTenantControlPlaneFunc utils.TenantControlPlaneRetrievalFn
TriggerChannel chan event.GenericEvent
}
func (k *KonnectivityAgent) Reconcile(ctx context.Context, _ reconcile.Request) (reconcile.Result, error) {
logger := log.FromContext(ctx, "controller", "konnectivity_agent")
tcp, err := k.GetTenantControlPlaneFunc()
if err != nil {
logger.Error(err, "cannot retrieve TenantControlPlane")
return reconcile.Result{}, err
}
for _, resource := range controllers.GetExternalKonnectivityResources(k.AdminClient) {
logger.Info("start processing konnectivity resource", "resource", resource.GetName())
result, handlingErr := resources.Handle(ctx, resource, tcp)
if handlingErr != nil {
logger.Error(handlingErr, "konnectivity resource process failed", "resource", resource.GetName())
return reconcile.Result{}, handlingErr
}
if result == controllerutil.OperationResultNone {
logger.Info("konnectivity resource reconciled", "resource", resource.GetName())
continue
}
if err = utils.UpdateStatus(ctx, k.AdminClient, k.GetTenantControlPlaneFunc, resource); err != nil {
logger.Error(err, "update of the resource failed", "resource", resource.GetName())
return reconcile.Result{}, err
}
}
logger.Info("reconciliation completed")
return reconcile.Result{}, nil
}
func (k *KonnectivityAgent) SetupWithManager(mgr manager.Manager) error {
return controllerruntime.NewControllerManagedBy(mgr).
WithLogger(mgr.GetLogger().WithName("konnectivity_agent")).
For(&appsv1.DaemonSet{}, builder.WithPredicates(predicate.NewPredicateFuncs(func(object client.Object) bool {
return object.GetName() == konnectivity.AgentName && object.GetNamespace() == konnectivity.AgentNamespace
}))).
Watches(&source.Kind{Type: &corev1.ServiceAccount{}}, handler.EnqueueRequestsFromMapFunc(func(object client.Object) []reconcile.Request {
if object.GetName() == konnectivity.AgentName && object.GetNamespace() == konnectivity.AgentNamespace {
return []reconcile.Request{
{
NamespacedName: types.NamespacedName{
Namespace: object.GetNamespace(),
Name: object.GetName(),
},
},
}
}
return nil
})).
Watches(&source.Kind{Type: &v1.ClusterRoleBinding{}}, handler.EnqueueRequestsFromMapFunc(func(object client.Object) []reconcile.Request {
if object.GetName() == konnectivity.CertCommonName {
return []reconcile.Request{
{
NamespacedName: types.NamespacedName{
Name: konnectivity.CertCommonName,
},
},
}
}
return nil
})).
Watches(&source.Channel{Source: k.TriggerChannel}, &handler.EnqueueRequestForObject{}).
Complete(k)
}

View File

@@ -23,14 +23,14 @@ import (
"sigs.k8s.io/controller-runtime/pkg/source"
"github.com/clastix/kamaji/api/v1alpha1"
"github.com/clastix/kamaji/controllers/soot/helpers"
"github.com/clastix/kamaji/controllers/utils"
"github.com/clastix/kamaji/internal/utilities"
)
type Migrate struct {
client client.Client
GetTenantControlPlaneFunc helpers.TenantControlPlaneRetrievalFn
GetTenantControlPlaneFunc utils.TenantControlPlaneRetrievalFn
WebhookNamespace string
WebhookServiceName string
WebhookCABundle []byte

View File

@@ -21,12 +21,12 @@ import (
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"
"github.com/clastix/kamaji/controllers/soot/controllers"
"github.com/clastix/kamaji/controllers/soot/helpers"
"github.com/clastix/kamaji/controllers/utils"
"github.com/clastix/kamaji/internal/utilities"
)
type sootItem struct {
trigger chan event.GenericEvent
triggers []chan event.GenericEvent
cancelFn context.CancelFunc
}
@@ -39,11 +39,12 @@ type Manager struct {
MigrateCABundle []byte
MigrateServiceName string
MigrateServiceNamespace string
AdminClient client.Client
}
// retrieveTenantControlPlane is the function used to let an underlying controller of the soot manager
// to retrieve its parent TenantControlPlane definition, required to understand which actions must be performed.
func (m *Manager) retrieveTenantControlPlane(ctx context.Context, request reconcile.Request) helpers.TenantControlPlaneRetrievalFn {
func (m *Manager) retrieveTenantControlPlane(ctx context.Context, request reconcile.Request) utils.TenantControlPlaneRetrievalFn {
return func() (*kamajiv1alpha1.TenantControlPlane, error) {
tcp := &kamajiv1alpha1.TenantControlPlane{}
@@ -83,14 +84,6 @@ func (m *Manager) Reconcile(ctx context.Context, request reconcile.Request) (res
return reconcile.Result{}, err
}
// Deferring the trigger execution to propagate change from the TCP to the underlying manager controller:
// if a value is assigned, propagating it, otherwise ignoring it.
var ch chan event.GenericEvent
defer func() {
if ch != nil {
ch <- event.GenericEvent{Object: tcp}
}
}()
tcpStatus := *tcp.Status.Kubernetes.Version.Status
// Triggering the reconciliation of the underlying controllers of
@@ -106,7 +99,9 @@ func (m *Manager) Reconcile(ctx context.Context, request reconcile.Request) (res
return reconcile.Result{}, nil
}
ch = v.trigger
for _, trigger := range v.triggers {
trigger <- event.GenericEvent{Object: tcp}
}
return reconcile.Result{}, nil
}
@@ -146,17 +141,26 @@ func (m *Manager) Reconcile(ctx context.Context, request reconcile.Request) (res
return reconcile.Result{}, err
}
ch = make(chan event.GenericEvent)
//
// Register all the controllers of the soot here:
//
if err = (&controllers.Migrate{
migrate := &controllers.Migrate{
WebhookNamespace: m.MigrateServiceName,
WebhookServiceName: m.MigrateServiceNamespace,
WebhookCABundle: m.MigrateCABundle,
GetTenantControlPlaneFunc: m.retrieveTenantControlPlane(tcpCtx, request),
TriggerChannel: ch,
}).SetupWithManager(mgr); err != nil {
TriggerChannel: make(chan event.GenericEvent),
}
if err = migrate.SetupWithManager(mgr); err != nil {
return reconcile.Result{}, err
}
konnectivityAgent := &controllers.KonnectivityAgent{
AdminClient: m.AdminClient,
GetTenantControlPlaneFunc: m.retrieveTenantControlPlane(tcpCtx, request),
TriggerChannel: make(chan event.GenericEvent),
}
if err = konnectivityAgent.SetupWithManager(mgr); err != nil {
return reconcile.Result{}, err
}
// Starting the manager
@@ -167,11 +171,14 @@ func (m *Manager) Reconcile(ctx context.Context, request reconcile.Request) (res
}()
m.sootMap[request.NamespacedName.String()] = sootItem{
trigger: ch,
triggers: []chan event.GenericEvent{
migrate.TriggerChannel,
konnectivityAgent.TriggerChannel,
},
cancelFn: tcpCancelFn,
}
return reconcile.Result{}, nil
return reconcile.Result{Requeue: true}, nil
}
func (m *Manager) SetupWithManager(mgr manager.Manager) error {

View File

@@ -12,10 +12,9 @@ import (
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
errors2 "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/util/retry"
"k8s.io/client-go/util/workqueue"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
@@ -30,6 +29,7 @@ import (
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"
"github.com/clastix/kamaji/controllers/finalizers"
"github.com/clastix/kamaji/controllers/utils"
"github.com/clastix/kamaji/internal/datastore"
kamajierrors "github.com/clastix/kamaji/internal/errors"
"github.com/clastix/kamaji/internal/resources"
@@ -68,16 +68,18 @@ type TenantControlPlaneReconcilerConfig struct {
func (r *TenantControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := log.FromContext(ctx)
tenantControlPlane := &kamajiv1alpha1.TenantControlPlane{}
isTenantControlPlane, err := r.getTenantControlPlane(ctx, req.NamespacedName, tenantControlPlane)
tenantControlPlane, err := r.getTenantControlPlane(ctx, req.NamespacedName)()
if err != nil {
if errors2.IsNotFound(err) {
log.Info("resource may have been deleted, skipping")
return ctrl.Result{}, nil
}
log.Error(err, "cannot retrieve the required instance")
return ctrl.Result{}, err
}
if !isTenantControlPlane {
return ctrl.Result{}, nil
}
markedToBeDeleted := tenantControlPlane.GetDeletionTimestamp() != nil
@@ -156,7 +158,7 @@ func (r *TenantControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.R
continue
}
if err := r.updateStatus(ctx, req.NamespacedName, resource); err != nil {
if err = utils.UpdateStatus(ctx, r.Client, r.getTenantControlPlane(ctx, req.NamespacedName), resource); err != nil {
log.Error(err, "update of the resource failed", "resource", resource.GetName())
return ctrl.Result{}, err
@@ -220,43 +222,15 @@ func (r *TenantControlPlaneReconciler) SetupWithManager(mgr ctrl.Manager) error
Complete(r)
}
func (r *TenantControlPlaneReconciler) getTenantControlPlane(ctx context.Context, namespacedName k8stypes.NamespacedName, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) (bool, error) {
if err := r.APIReader.Get(ctx, namespacedName, tenantControlPlane); err != nil {
if !k8serrors.IsNotFound(err) {
return false, err
func (r *TenantControlPlaneReconciler) getTenantControlPlane(ctx context.Context, namespacedName k8stypes.NamespacedName) utils.TenantControlPlaneRetrievalFn {
return func() (*kamajiv1alpha1.TenantControlPlane, error) {
tcp := &kamajiv1alpha1.TenantControlPlane{}
if err := r.APIReader.Get(ctx, namespacedName, tcp); err != nil {
return nil, err
}
return false, nil
return tcp, nil
}
return true, nil
}
func (r *TenantControlPlaneReconciler) updateStatus(ctx context.Context, namespacedName k8stypes.NamespacedName, resource resources.Resource) error {
tenantControlPlane := &kamajiv1alpha1.TenantControlPlane{}
updateErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
isTenantControlPlane, err := r.getTenantControlPlane(ctx, namespacedName, tenantControlPlane)
if err != nil {
return err
}
if !isTenantControlPlane {
return fmt.Errorf("error updating tenantControlPlane %s: not found", namespacedName.Name)
}
if err = resource.UpdateTenantControlPlaneStatus(ctx, tenantControlPlane); err != nil {
return fmt.Errorf("error applying TenantcontrolPlane status: %w", err)
}
if err = r.Client.Status().Update(ctx, tenantControlPlane); err != nil {
return fmt.Errorf("error updating tenantControlPlane status: %w", err)
}
return nil
})
return updateErr
}
func (r *TenantControlPlaneReconciler) RemoveFinalizer(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) error {

View File

@@ -1,7 +1,7 @@
// Copyright 2022 Clastix Labs
// SPDX-License-Identifier: Apache-2.0
package helpers
package utils
import (
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"

View File

@@ -0,0 +1,35 @@
// Copyright 2022 Clastix Labs
// SPDX-License-Identifier: Apache-2.0
package utils
import (
"context"
"fmt"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/clastix/kamaji/internal/resources"
)
func UpdateStatus(ctx context.Context, client client.Client, tcpRetrieval TenantControlPlaneRetrievalFn, resource resources.Resource) error {
updateErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
tenantControlPlane, err := tcpRetrieval()
if err != nil {
return err
}
if err = resource.UpdateTenantControlPlaneStatus(ctx, tenantControlPlane); err != nil {
return fmt.Errorf("error applying TenantcontrolPlane status: %w", err)
}
if err = client.Status().Update(ctx, tenantControlPlane); err != nil {
return fmt.Errorf("error updating tenantControlPlane status: %w", err)
}
return nil
})
return updateErr
}

View File

@@ -18,35 +18,34 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"
"github.com/clastix/kamaji/internal/constants"
"github.com/clastix/kamaji/internal/utilities"
)
const (
agentNamespace = "kube-system"
)
type Agent struct {
resource *appsv1.DaemonSet
Client client.Client
tenantClient client.Client
}
func (r *Agent) ShouldStatusBeUpdated(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
return tenantControlPlane.Status.Addons.Konnectivity.Agent.Checksum != r.resource.GetAnnotations()[constants.Checksum]
func (r *Agent) ShouldStatusBeUpdated(_ context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
return tenantControlPlane.Spec.Addons.Konnectivity == nil && len(tenantControlPlane.Status.Addons.Konnectivity.Agent.Namespace) == 0
}
func (r *Agent) ShouldCleanup(tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
return tenantControlPlane.Spec.Addons.Konnectivity == nil
return tenantControlPlane.Spec.Addons.Konnectivity == nil && len(tenantControlPlane.Status.Addons.Konnectivity.Agent.Name) > 0
}
func (r *Agent) CleanUp(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) (bool, error) {
func (r *Agent) CleanUp(ctx context.Context, _ *kamajiv1alpha1.TenantControlPlane) (bool, error) {
logger := log.FromContext(ctx, "resource", r.GetName())
if err := r.tenantClient.Delete(ctx, r.resource); err != nil {
if !k8serrors.IsNotFound(err) {
if k8serrors.IsNotFound(err) {
return false, err
}
return false, nil
logger.Error(err, "cannot delete the requested resource")
return false, err
}
return true, nil
@@ -58,7 +57,7 @@ func (r *Agent) Define(ctx context.Context, tenantControlPlane *kamajiv1alpha1.T
r.resource = &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: AgentName,
Namespace: agentNamespace,
Namespace: AgentNamespace,
},
}
@@ -72,19 +71,22 @@ func (r *Agent) Define(ctx context.Context, tenantControlPlane *kamajiv1alpha1.T
}
func (r *Agent) CreateOrUpdate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) (controllerutil.OperationResult, error) {
return controllerutil.CreateOrUpdate(ctx, r.tenantClient, r.resource, r.mutate(ctx, tenantControlPlane))
if tenantControlPlane.Spec.Addons.Konnectivity != nil {
return controllerutil.CreateOrUpdate(ctx, r.tenantClient, r.resource, r.mutate(ctx, tenantControlPlane))
}
return controllerutil.OperationResultNone, nil
}
func (r *Agent) GetName() string {
return "konnectivity-agent"
}
func (r *Agent) UpdateTenantControlPlaneStatus(ctx context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) error {
func (r *Agent) UpdateTenantControlPlaneStatus(_ context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) error {
if tenantControlPlane.Spec.Addons.Konnectivity != nil {
tenantControlPlane.Status.Addons.Konnectivity.Agent = kamajiv1alpha1.ExternalKubernetesObjectStatus{
Name: r.resource.GetName(),
Namespace: r.resource.GetNamespace(),
Checksum: r.resource.GetAnnotations()[constants.Checksum],
LastUpdate: metav1.Now(),
}
@@ -154,7 +156,7 @@ func (r *Agent) mutate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.T
},
},
},
DefaultMode: pointer.Int32Ptr(420),
DefaultMode: pointer.Int32(420),
},
},
},
@@ -164,7 +166,7 @@ func (r *Agent) mutate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.T
r.resource.Spec.Template.Spec.Containers = make([]corev1.Container, 1)
}
r.resource.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:%s", tenantControlPlane.Spec.Addons.Konnectivity.KonnectivityAgentSpec.AgentImage, tenantControlPlane.Spec.Addons.Konnectivity.KonnectivityServerSpec.Version)
r.resource.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:%s", tenantControlPlane.Spec.Addons.Konnectivity.KonnectivityAgentSpec.Image, tenantControlPlane.Spec.Addons.Konnectivity.KonnectivityAgentSpec.Version)
r.resource.Spec.Template.Spec.Containers[0].Name = AgentName
r.resource.Spec.Template.Spec.Containers[0].Command = []string{"/proxy-agent"}
@@ -200,18 +202,6 @@ func (r *Agent) mutate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.T
SuccessThreshold: 1,
FailureThreshold: 3,
}
// Creating a copy to remove the metadata that would be changed at every reconciliation
c := r.resource.DeepCopy()
c.SetAnnotations(nil)
c.SetResourceVersion("")
yaml, _ := utilities.EncodeToYaml(c)
annotations := r.resource.GetAnnotations()
if annotations == nil {
annotations = map[string]string{}
}
annotations[constants.Checksum] = utilities.MD5Checksum(yaml)
r.resource.SetAnnotations(annotations)
return nil
}

View File

@@ -14,36 +14,35 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"
"github.com/clastix/kamaji/internal/constants"
"github.com/clastix/kamaji/internal/utilities"
)
type ClusterRoleBindingResource struct {
Client client.Client
resource *rbacv1.ClusterRoleBinding
Client client.Client
tenantClient client.Client
}
func (r *ClusterRoleBindingResource) ShouldStatusBeUpdated(_ context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
return tenantControlPlane.Status.Addons.Konnectivity.ClusterRoleBinding.Name != r.resource.GetName() ||
tenantControlPlane.Status.Addons.Konnectivity.ClusterRoleBinding.Checksum != r.resource.ObjectMeta.GetAnnotations()[constants.Checksum]
return tenantControlPlane.Status.Addons.Konnectivity.ClusterRoleBinding.Name != r.resource.GetName()
}
func (r *ClusterRoleBindingResource) ShouldCleanup(tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
return tenantControlPlane.Spec.Addons.Konnectivity == nil
return tenantControlPlane.Spec.Addons.Konnectivity == nil && len(tenantControlPlane.Status.Addons.Konnectivity.ClusterRoleBinding.Name) > 0
}
func (r *ClusterRoleBindingResource) CleanUp(ctx context.Context, _ *kamajiv1alpha1.TenantControlPlane) (bool, error) {
logger := log.FromContext(ctx, "resource", r.GetName())
if err := r.tenantClient.Delete(ctx, r.resource); err != nil {
if !k8serrors.IsNotFound(err) {
logger.Error(err, "cannot delete the requeste resource")
return false, err
if k8serrors.IsNotFound(err) {
return false, nil
}
return false, nil
logger.Error(err, "cannot delete the requested resource")
return false, err
}
return true, nil
@@ -67,8 +66,12 @@ func (r *ClusterRoleBindingResource) Define(ctx context.Context, tenantControlPl
return nil
}
func (r *ClusterRoleBindingResource) CreateOrUpdate(ctx context.Context, _ *kamajiv1alpha1.TenantControlPlane) (controllerutil.OperationResult, error) {
return controllerutil.CreateOrUpdate(ctx, r.tenantClient, r.resource, r.mutate())
func (r *ClusterRoleBindingResource) CreateOrUpdate(ctx context.Context, tcp *kamajiv1alpha1.TenantControlPlane) (controllerutil.OperationResult, error) {
if tcp.Spec.Addons.Konnectivity != nil {
return controllerutil.CreateOrUpdate(ctx, r.tenantClient, r.resource, r.mutate())
}
return controllerutil.OperationResultNone, nil
}
func (r *ClusterRoleBindingResource) GetName() string {
@@ -79,8 +82,7 @@ func (r *ClusterRoleBindingResource) UpdateTenantControlPlaneStatus(_ context.Co
if tenantControlPlane.Spec.Addons.Konnectivity != nil {
tenantControlPlane.Status.Addons.Konnectivity.Enabled = true
tenantControlPlane.Status.Addons.Konnectivity.ClusterRoleBinding = kamajiv1alpha1.ExternalKubernetesObjectStatus{
Name: r.resource.GetName(),
Checksum: r.resource.GetAnnotations()[constants.Checksum],
Name: r.resource.GetName(),
}
return nil
@@ -115,14 +117,6 @@ func (r *ClusterRoleBindingResource) mutate() controllerutil.MutateFn {
},
}
annotations := r.resource.GetAnnotations()
if annotations == nil {
annotations = map[string]string{}
}
yaml, _ := utilities.EncodeToYaml(r.resource)
annotations[constants.Checksum] = utilities.MD5Checksum(yaml)
return nil
}
}

View File

@@ -3,9 +3,14 @@
package konnectivity
import (
"k8s.io/kubernetes/pkg/apis/core"
)
const (
AgentName = "konnectivity-agent"
CertCommonName = "system:konnectivity-server"
AgentNamespace = core.NamespaceSystem
agentTokenName = "konnectivity-agent-token"
apiServerAPIVersion = "apiserver.k8s.io/v1beta1"

View File

@@ -129,7 +129,7 @@ func (r *KubernetesDeploymentResource) syncContainer(tenantControlPlane *kamajiv
}
r.resource.Spec.Template.Spec.Containers[index].Name = konnectivityServerName
r.resource.Spec.Template.Spec.Containers[index].Image = fmt.Sprintf("%s:%s", tenantControlPlane.Spec.Addons.Konnectivity.KonnectivityServerSpec.Image, tenantControlPlane.Spec.Addons.Konnectivity.KonnectivityAgentSpec.Version)
r.resource.Spec.Template.Spec.Containers[index].Image = fmt.Sprintf("%s:%s", tenantControlPlane.Spec.Addons.Konnectivity.KonnectivityServerSpec.Image, tenantControlPlane.Spec.Addons.Konnectivity.KonnectivityServerSpec.Version)
r.resource.Spec.Template.Spec.Containers[index].Command = []string{"/proxy-server"}
args := utilities.ArgsFromSliceToMap(tenantControlPlane.Spec.Addons.Konnectivity.KonnectivityServerSpec.ExtraArgs)

View File

@@ -14,35 +14,35 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"
"github.com/clastix/kamaji/internal/constants"
"github.com/clastix/kamaji/internal/utilities"
)
type ServiceAccountResource struct {
Client client.Client
resource *corev1.ServiceAccount
Client client.Client
tenantClient client.Client
}
func (r *ServiceAccountResource) ShouldStatusBeUpdated(_ context.Context, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
return tenantControlPlane.Status.Addons.Konnectivity.ServiceAccount.Checksum != r.resource.GetAnnotations()[constants.Checksum]
return len(tenantControlPlane.Status.Addons.Konnectivity.ServiceAccount.Name) == 0 && len(tenantControlPlane.Status.Addons.Konnectivity.ServiceAccount.Namespace) == 0
}
func (r *ServiceAccountResource) ShouldCleanup(tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool {
return tenantControlPlane.Spec.Addons.Konnectivity == nil
return tenantControlPlane.Spec.Addons.Konnectivity == nil && len(tenantControlPlane.Status.Addons.Konnectivity.ServiceAccount.Name) > 0
}
func (r *ServiceAccountResource) CleanUp(ctx context.Context, _ *kamajiv1alpha1.TenantControlPlane) (bool, error) {
logger := log.FromContext(ctx, "resource", r.GetName())
if err := r.tenantClient.Delete(ctx, r.resource); err != nil {
if !k8serrors.IsNotFound(err) {
logger.Error(err, "cannot delete the requested resource")
return false, err
if k8serrors.IsNotFound(err) {
return false, nil
}
return false, nil
logger.Error(err, "cannot delete the requested resource")
return false, err
}
return true, nil
@@ -54,7 +54,7 @@ func (r *ServiceAccountResource) Define(ctx context.Context, tenantControlPlane
r.resource = &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: AgentName,
Namespace: agentNamespace,
Namespace: AgentNamespace,
},
}
@@ -67,8 +67,12 @@ func (r *ServiceAccountResource) Define(ctx context.Context, tenantControlPlane
return nil
}
func (r *ServiceAccountResource) CreateOrUpdate(ctx context.Context, _ *kamajiv1alpha1.TenantControlPlane) (controllerutil.OperationResult, error) {
return controllerutil.CreateOrUpdate(ctx, r.tenantClient, r.resource, r.mutate())
func (r *ServiceAccountResource) CreateOrUpdate(ctx context.Context, tcp *kamajiv1alpha1.TenantControlPlane) (controllerutil.OperationResult, error) {
if tcp.Spec.Addons.Konnectivity != nil {
return controllerutil.CreateOrUpdate(ctx, r.tenantClient, r.resource, r.mutate())
}
return controllerutil.OperationResultNone, nil
}
func (r *ServiceAccountResource) GetName() string {
@@ -80,7 +84,6 @@ func (r *ServiceAccountResource) UpdateTenantControlPlaneStatus(_ context.Contex
tenantControlPlane.Status.Addons.Konnectivity.ServiceAccount = kamajiv1alpha1.ExternalKubernetesObjectStatus{
Name: r.resource.GetName(),
Namespace: r.resource.GetNamespace(),
Checksum: r.resource.GetAnnotations()[constants.Checksum],
}
return nil
@@ -101,19 +104,6 @@ func (r *ServiceAccountResource) mutate() controllerutil.MutateFn {
},
))
c := r.resource.DeepCopy()
c.SetAnnotations(nil)
c.SetResourceVersion("")
yaml, _ := utilities.EncodeToYaml(c)
annotations := r.resource.GetAnnotations()
if annotations == nil {
annotations = map[string]string{}
}
annotations[constants.Checksum] = utilities.MD5Checksum(yaml)
r.resource.SetAnnotations(annotations)
return nil
}
}