Skip to content

Commit

Permalink
feat: add ResolvedRefs condition to DataPlane
Browse files Browse the repository at this point in the history
Signed-off-by: Mattia Lavacca <[email protected]>
  • Loading branch information
mlavacca committed Oct 9, 2024
1 parent 3688abb commit e6ba101
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 12 deletions.
10 changes: 9 additions & 1 deletion controller/dataplane/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,17 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
}

log.Trace(logger, "applying extensions", dataplane)
if err = applyExtensions(ctx, r.Client, dataplane); err != nil {
patched, requeue, err := applyExtensions(ctx, r.Client, logger, dataplane)
if err != nil {
if !requeue {
log.Debug(logger, "failed to apply extensions", dataplane, "error:", err)
return ctrl.Result{}, nil
}
return ctrl.Result{}, err
}
if patched {
return ctrl.Result{}, nil
}

log.Trace(logger, "exposing DataPlane deployment admin API via headless service", dataplane)
res, dataplaneAdminService, err := ensureAdminServiceForDataPlane(ctx, r.Client, dataplane,
Expand Down
31 changes: 29 additions & 2 deletions controller/dataplane/controller_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,33 @@ func isDeploymentReady(deploymentStatus appsv1.DeploymentStatus) (metav1.Conditi
// DataPlane - Private Functions - extensions
// -----------------------------------------------------------------------------

func applyExtensions(ctx context.Context, cl client.Client, dataplane *operatorv1beta1.DataPlane) error {
return applyDataPlaneKonnectExtension(ctx, cl, dataplane)
func applyExtensions(ctx context.Context, cl client.Client, logger logr.Logger, dataplane *operatorv1beta1.DataPlane) (patched bool, requeue bool, err error) {
condition := k8sutils.NewConditionWithGeneration(consts.ResolvedRefsType, metav1.ConditionTrue, consts.ResolvedRefsReason, "", dataplane.GetGeneration())
err = applyDataPlaneKonnectExtension(ctx, cl, dataplane)
if err != nil {
switch err {
case ErrCrossNamespaceReference:
condition.Status = metav1.ConditionFalse
condition.Reason = string(consts.RefNotPermittedReason)
condition.Message = consts.RefNotPermittedMessage
case ErrKonnectExtensionNotFound:
condition.Status = metav1.ConditionFalse
condition.Reason = string(consts.InvalidExtensionRefReason)
condition.Message = consts.InvalidExtensionRefMessage
case ErrClusterCertificateNotFound:
condition.Status = metav1.ConditionFalse
condition.Reason = string(consts.InvalidSecretRefReason)
condition.Message = consts.InvalidSecretRefMessage
default:
requeue = false
return
}
}
newDataPlane := dataplane.DeepCopy()
k8sutils.SetCondition(condition, newDataPlane)
patched, patchErr := patchDataPlaneStatus(ctx, cl, logger, newDataPlane)
if patchErr != nil {
return false, true, fmt.Errorf("failed patching status for DataPlane %s/%s: %w", dataplane.Namespace, dataplane.Name, patchErr)
}
return
}
27 changes: 25 additions & 2 deletions controller/dataplane/konnect_extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/samber/lo"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"

operatorv1alpha1 "github.com/kong/gateway-operator/api/v1alpha1"
Expand All @@ -17,6 +18,12 @@ import (
k8sresources "github.com/kong/gateway-operator/pkg/utils/kubernetes/resources"
)

var (
ErrCrossNamespaceReference = errors.New("cross-namespace reference is not currently supported for Konnect extensions")
ErrKonnectExtensionNotFound = errors.New("konnect extension not found")
ErrClusterCertificateNotFound = errors.New("cluster certificate not found")
)

// applyDataPlaneKonnectExtension gets the DataPlane as argument, and in case it references a KonnectExtension, it
// fetches the referenced extension and applies the necessary changes to the DataPlane spec.
func applyDataPlaneKonnectExtension(ctx context.Context, cl client.Client, dataplane *v1beta1.DataPlane) error {
Expand All @@ -26,15 +33,31 @@ func applyDataPlaneKonnectExtension(ctx context.Context, cl client.Client, datap
}
namespace := dataplane.Namespace
if extensionRef.Namespace != nil && *extensionRef.Namespace != namespace {
return errors.New("cross-namespace reference is not currently supported for Konnect extensions")
return ErrCrossNamespaceReference
}

konnectExt := operatorv1alpha1.DataPlaneKonnectExtension{}
if err := cl.Get(ctx, client.ObjectKey{
Namespace: namespace,
Name: extensionRef.Name,
}, &konnectExt); err != nil {
return err
if k8serrors.IsNotFound(err) {
return ErrKonnectExtensionNotFound
} else {
return err
}
}

secret := corev1.Secret{}
if err := cl.Get(ctx, client.ObjectKey{
Namespace: namespace,
Name: konnectExt.Spec.AuthConfiguration.ClusterCertificateSecretRef.Name,
}, &secret); err != nil {
if k8serrors.IsNotFound(err) {
return ErrClusterCertificateNotFound
} else {
return err
}
}

if dataplane.Spec.Deployment.PodTemplateSpec == nil {
Expand Down
36 changes: 29 additions & 7 deletions pkg/consts/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,56 @@ type ConditionType string
// CoditionReason literal to enumerate a specific condition reason
type ConditionReason string

// -----------------------------------------------------------------------------
// DataPlane - Ready Condition Constants
// -----------------------------------------------------------------------------

const (
// ReadyType indicates if the resource has all the dependent conditions Ready
ReadyType ConditionType = "Ready"

// DependenciesNotReadyReason is a generic reason describing that the other Conditions are not true
DependenciesNotReadyReason ConditionReason = "DependenciesNotReady"

// ResourceReadyReason indicates the resource is ready
ResourceReadyReason ConditionReason = ConditionReason("Ready")

// WaitingToBecomeReadyReason generic message for dependent resources waiting to be ready
WaitingToBecomeReadyReason ConditionReason = "WaitingToBecomeReady"

// ResourceCreatedOrUpdatedReason generic message for missing or outdated resources
ResourceCreatedOrUpdatedReason ConditionReason = "ResourceCreatedOrUpdated"

// UnableToProvisionReason generic message for unexpected errors
UnableToProvisionReason ConditionReason = "UnableToProvision"

// DependenciesNotReadyMessage indicates the other conditions are not yet ready
DependenciesNotReadyMessage = "There are other conditions that are not yet ready"

// WaitingToBecomeReadyMessage indicates the target resource is not ready
WaitingToBecomeReadyMessage = "Waiting for the resource to become ready"

// ResourceCreatedMessage indicates a missing resource was provisioned
ResourceCreatedMessage = "Resource has been created"

// ResourceUpdatedMessage indicates a resource was updated
ResourceUpdatedMessage = "Resource has been updated"
)

// -----------------------------------------------------------------------------
// DataPlane - ResolvedRefs Condition Constants
// -----------------------------------------------------------------------------

const (
// ResolvedRefsType indicates if the resource has all the dependent references resolved
ResolvedRefsType ConditionType = "ResolvedRefs"

// ResolvedRefsReason is a generic reason describing that the references are resolved. It must be used when the ResolvedRefs condition is set to True.
ResolvedRefsReason ConditionReason = "ResolvedRefs"
// RefNotPermittedReason is a generic reason describing that the reference is not permitted. It must be used when the ResolvedRefs condition is set to False.
RefNotPermittedReason ConditionReason = "RefNotPermitted"
// InvalidExtensionRefReason is a generic reason describing that the extension reference is invalid. It must be used when the ResolvedRefs condition is set to False.
InvalidExtensionRefReason ConditionReason = "InvalidExtension"
// InvalidSecretRefReason is a generic reason describing that the secret reference is invalid. It must be used when the ResolvedRefs condition is set to False.
InvalidSecretRefReason ConditionReason = "InvalidSecret"

// RefNotPermittedMessage indicates the reference is not permitted. It must be used when the ResolvedRefs condition is set to False.
RefNotPermittedMessage = "The extension cross-namespace reference is not permitted"
// InvalidExtensionRefMessage indicates the extension reference is invalid. It must be used when the ResolvedRefs condition is set to False.
InvalidExtensionRefMessage = "The referenced extension is invalid"
// InvalidSecretRefMessage indicates the secret reference is invalid. It must be used when the ResolvedRefs condition is set to False.
InvalidSecretRefMessage = "The secret referenced by the konnectExtension is invalid"
)

0 comments on commit e6ba101

Please sign in to comment.