Files
kamaji/internal/resources/resource.go
Dario Tranchitella e0c86d685c feat: support for kubeadm cluster-admins rbac
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
2023-12-15 13:02:49 +01:00

122 lines
4.0 KiB
Go

// Copyright 2022 Clastix Labs
// SPDX-License-Identifier: Apache-2.0
package resources
import (
"context"
corev1 "k8s.io/api/core/v1"
k8stypes "k8s.io/apimachinery/pkg/types"
clientset "k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"
"github.com/clastix/kamaji/internal/kubeadm"
)
const (
OperationResultEnqueueBack controllerutil.OperationResult = "enqueueBack"
)
type Resource interface {
Define(context.Context, *kamajiv1alpha1.TenantControlPlane) error
ShouldCleanup(*kamajiv1alpha1.TenantControlPlane) bool
CleanUp(context.Context, *kamajiv1alpha1.TenantControlPlane) (bool, error)
CreateOrUpdate(context.Context, *kamajiv1alpha1.TenantControlPlane) (controllerutil.OperationResult, error)
GetName() string
ShouldStatusBeUpdated(context.Context, *kamajiv1alpha1.TenantControlPlane) bool
UpdateTenantControlPlaneStatus(context.Context, *kamajiv1alpha1.TenantControlPlane) error
}
type DeletableResource interface {
GetName() string
Define(context.Context, *kamajiv1alpha1.TenantControlPlane) error
Delete(context.Context, *kamajiv1alpha1.TenantControlPlane) error
}
type KubeadmResource interface {
GetClient() client.Client
GetTmpDirectory() string
}
type KubeadmPhaseResource interface {
Resource
KubeadmResource
GetClient() client.Client
GetKubeadmFunction(context.Context, *kamajiv1alpha1.TenantControlPlane) (func(clientset.Interface, *kubeadm.Configuration) ([]byte, error), error)
GetStatus(*kamajiv1alpha1.TenantControlPlane) (kamajiv1alpha1.KubeadmConfigChecksumDependant, error)
SetKubeadmConfigChecksum(string)
GetWatchedObject() client.Object
GetPredicateFunc() func(obj client.Object) bool
}
type HandlerConfig struct {
Resource Resource
TenantControlPlane *kamajiv1alpha1.TenantControlPlane
}
// Handle handles the given resource and returns a boolean to say if the tenantControlPlane has been modified.
func Handle(ctx context.Context, resource Resource, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) (controllerutil.OperationResult, error) {
if err := resource.Define(ctx, tenantControlPlane); err != nil {
return "", err
}
if !resource.ShouldCleanup(tenantControlPlane) {
return createOrUpdate(ctx, resource, tenantControlPlane)
}
cleanUp, err := resource.CleanUp(ctx, tenantControlPlane)
if err != nil {
return controllerutil.OperationResultNone, err
}
if cleanUp {
return controllerutil.OperationResultUpdated, nil
}
return controllerutil.OperationResultNone, err
}
// HandleDeletion handles the deletion of the given resource.
func HandleDeletion(ctx context.Context, resource DeletableResource, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) error {
if err := resource.Define(ctx, tenantControlPlane); err != nil {
return err
}
return resource.Delete(ctx, tenantControlPlane)
}
func createOrUpdate(ctx context.Context, resource Resource, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) (controllerutil.OperationResult, error) {
result, err := resource.CreateOrUpdate(ctx, tenantControlPlane)
if err != nil {
return "", err
}
if result == controllerutil.OperationResultNone && resource.ShouldStatusBeUpdated(ctx, tenantControlPlane) {
return controllerutil.OperationResultUpdatedStatusOnly, nil
}
return result, nil
}
func getStoredKubeadmConfiguration(ctx context.Context, client client.Client, tmpDirectory string, tenantControlPlane *kamajiv1alpha1.TenantControlPlane) (*kubeadm.Configuration, error) {
var configmap corev1.ConfigMap
namespacedName := k8stypes.NamespacedName{Namespace: tenantControlPlane.GetNamespace(), Name: tenantControlPlane.Status.KubeadmConfig.ConfigmapName}
if err := client.Get(ctx, namespacedName, &configmap); err != nil {
return nil, err
}
config, err := kubeadm.GetKubeadmInitConfigurationFromMap(configmap.Data)
if err != nil {
return nil, err
}
if len(tmpDirectory) > 0 {
config.InitConfiguration.ClusterConfiguration.CertificatesDir = tmpDirectory
}
return config, nil
}