Skip to content

Commit

Permalink
chore(konnect): do not handle upsert errors (#787)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmalek authored Oct 24, 2024
1 parent 7ab4b18 commit bc480d9
Show file tree
Hide file tree
Showing 21 changed files with 69 additions and 471 deletions.
22 changes: 3 additions & 19 deletions controller/konnect/ops/ops_controlplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ package ops

import (
"context"
"errors"
"fmt"
"sort"

sdkkonnectgo "github.com/Kong/sdk-konnect-go"
sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components"
sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations"
sdkkonnecterrs "github.com/Kong/sdk-konnect-go/models/sdkerrors"
"github.com/samber/lo"
"github.com/sourcegraph/conc/iter"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -99,24 +97,10 @@ func updateControlPlane(
}

resp, err := sdk.UpdateControlPlane(ctx, id, req)
var sdkError *sdkkonnecterrs.NotFoundError
if errors.As(err, &sdkError) {
logEntityNotFoundRecreating(ctx, cp, id)
if err := createControlPlane(ctx, sdk, sdkGroups, cl, cp); err != nil {
return FailedKonnectOpError[konnectv1alpha1.KonnectGatewayControlPlane]{
Op: UpdateOp,
Err: err,
}
}

return nil
}

if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, cp); errWrap != nil {
return FailedKonnectOpError[konnectv1alpha1.KonnectGatewayControlPlane]{
Op: UpdateOp,
Err: errWrap,
}
return handleUpdateError(ctx, err, cp, func(ctx context.Context) error {
return createControlPlane(ctx, sdk, sdkGroups, cl, cp)
})
}

if resp == nil || resp.ControlPlane == nil {
Expand Down
23 changes: 0 additions & 23 deletions controller/konnect/ops/ops_credentialacl.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package ops

import (
"context"
"errors"
"fmt"

sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components"
sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations"
sdkkonnecterrs "github.com/Kong/sdk-konnect-go/models/sdkerrors"
"github.com/samber/lo"

sdkops "github.com/kong/gateway-operator/controller/konnect/ops/sdk"
Expand Down Expand Up @@ -75,27 +73,6 @@ func updateKongCredentialACL(
// Can't adopt it as it will cause conflicts between the controller
// that created that entity and already manages it, hm
if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, cred); errWrap != nil {
// ACL update operation returns an SDKError instead of a NotFoundError.
var sdkError *sdkkonnecterrs.SDKError
if errors.As(errWrap, &sdkError) {
switch sdkError.StatusCode {
case 404:
if err := createKongCredentialACL(ctx, sdk, cred); err != nil {
return FailedKonnectOpError[configurationv1alpha1.KongCredentialACL]{
Op: UpdateOp,
Err: err,
}
}
return nil
default:
return FailedKonnectOpError[configurationv1alpha1.KongCredentialACL]{
Op: UpdateOp,
Err: sdkError,
}

}
}

return errWrap
}

Expand Down
3 changes: 0 additions & 3 deletions controller/konnect/ops/ops_credentialapikey.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ func updateKongCredentialAPIKey(
KeyAuthWithoutParents: kongCredentialAPIKeyToKeyAuthWithoutParents(cred),
})

// TODO: handle already exists
// Can't adopt it as it will cause conflicts between the controller
// that created that entity and already manages it, hm
if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, cred); errWrap != nil {
return errWrap
}
Expand Down
3 changes: 0 additions & 3 deletions controller/konnect/ops/ops_credentialbasicauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ func updateKongCredentialBasicAuth(
BasicAuthWithoutParents: kongCredentialBasicAuthToBasicAuthWithoutParents(cred),
})

// TODO: handle already exists
// Can't adopt it as it will cause conflicts between the controller
// that created that entity and already manages it, hm
if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, cred); errWrap != nil {
return errWrap
}
Expand Down
26 changes: 0 additions & 26 deletions controller/konnect/ops/ops_credentialhmac.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package ops

import (
"context"
"errors"
"fmt"

sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components"
sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations"
sdkkonnecterrs "github.com/Kong/sdk-konnect-go/models/sdkerrors"
"github.com/samber/lo"

sdkops "github.com/kong/gateway-operator/controller/konnect/ops/sdk"
Expand Down Expand Up @@ -71,31 +69,7 @@ func updateKongCredentialHMAC(
HMACAuthWithoutParents: kongCredentialHMACToHMACWithoutParents(cred),
})

// TODO: handle already exists
// Can't adopt it as it will cause conflicts between the controller
// that created that entity and already manages it, hm
if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, cred); errWrap != nil {
// HMAC update operation returns an SDKError instead of a NotFoundError.
var sdkError *sdkkonnecterrs.SDKError
if errors.As(errWrap, &sdkError) {
switch sdkError.StatusCode {
case 404:
if err := createKongCredentialHMAC(ctx, sdk, cred); err != nil {
return FailedKonnectOpError[configurationv1alpha1.KongCredentialHMAC]{
Op: UpdateOp,
Err: err,
}
}
return nil
default:
return FailedKonnectOpError[configurationv1alpha1.KongCredentialHMAC]{
Op: UpdateOp,
Err: sdkError,
}

}
}

return errWrap
}

Expand Down
26 changes: 0 additions & 26 deletions controller/konnect/ops/ops_credentialjwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package ops

import (
"context"
"errors"
"fmt"

sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components"
sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations"
sdkkonnecterrs "github.com/Kong/sdk-konnect-go/models/sdkerrors"
"github.com/samber/lo"

sdkops "github.com/kong/gateway-operator/controller/konnect/ops/sdk"
Expand Down Expand Up @@ -71,31 +69,7 @@ func updateKongCredentialJWT(
JWTWithoutParents: kongCredentialJWTToJWTWithoutParents(cred),
})

// TODO: handle already exists
// Can't adopt it as it will cause conflicts between the controller
// that created that entity and already manages it, hm
if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, cred); errWrap != nil {
// JWT update operation returns an SDKError instead of a NotFoundError.
var sdkError *sdkkonnecterrs.SDKError
if errors.As(errWrap, &sdkError) {
switch sdkError.StatusCode {
case 404:
if err := createKongCredentialJWT(ctx, sdk, cred); err != nil {
return FailedKonnectOpError[configurationv1alpha1.KongCredentialJWT]{
Op: UpdateOp,
Err: err,
}
}
return nil
default:
return FailedKonnectOpError[configurationv1alpha1.KongCredentialJWT]{
Op: UpdateOp,
Err: sdkError,
}

}
}

return errWrap
}

Expand Down
53 changes: 53 additions & 0 deletions controller/konnect/ops/ops_errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,59 @@ func SDKErrorIsConflict(sdkError *sdkkonnecterrs.SDKError) bool {
return false
}

// handleUpdateError handles errors that occur during an update operation.
// If the entity is not found, then it uses the provided create function to
// recreate the it.
func handleUpdateError[
T constraints.SupportedKonnectEntityType,
TEnt constraints.EntityType[T],
](
ctx context.Context,
err error,
ent TEnt,
createFunc func(ctx context.Context) error,
) error {
var (
sdkError *sdkkonnecterrs.SDKError
id = ent.GetKonnectStatus().GetKonnectID()
)
if errors.As(err, &sdkError) {
switch sdkError.StatusCode {
case http.StatusNotFound:
logEntityNotFoundRecreating(ctx, ent, id)
if err := createFunc(ctx); err != nil {
return FailedKonnectOpError[T]{
Op: UpdateOp,
Err: err,
}
}
return nil
default:
return FailedKonnectOpError[T]{
Op: UpdateOp,
Err: sdkError,
}
}
}

var notFoundError *sdkkonnecterrs.NotFoundError
if errors.As(err, &notFoundError) {
logEntityNotFoundRecreating(ctx, ent, id)
if err := createFunc(ctx); err != nil {
return FailedKonnectOpError[T]{
Op: UpdateOp,
Err: err,
}
}
return nil
}

return FailedKonnectOpError[T]{
Op: UpdateOp,
Err: err,
}
}

// handleDeleteError handles errors that occur during a delete operation.
// It logs a message and returns nil if the entity was not found in Konnect (when
// the delete operation is skipped).
Expand Down
6 changes: 0 additions & 6 deletions controller/konnect/ops/ops_kongcacertificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,10 @@ func updateCACertificate(
},
)

// TODO: handle already exists
// Can't adopt it as it will cause conflicts between the controller
// that created that entity and already manages it, hm
if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, cert); errWrap != nil {
SetKonnectEntityProgrammedConditionFalse(cert, "FailedToUpdate", errWrap.Error())
return errWrap
}

SetKonnectEntityProgrammedCondition(cert)

return nil
}

Expand Down
26 changes: 0 additions & 26 deletions controller/konnect/ops/ops_kongcertificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package ops

import (
"context"
"errors"
"fmt"

sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components"
sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations"
sdkkonnecterrs "github.com/Kong/sdk-konnect-go/models/sdkerrors"
"github.com/samber/lo"

sdkops "github.com/kong/gateway-operator/controller/konnect/ops/sdk"
Expand Down Expand Up @@ -70,31 +68,7 @@ func updateCertificate(
},
)

// TODO: handle already exists
// Can't adopt it as it will cause conflicts between the controller
// that created that entity and already manages it, hm
if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, cert); errWrap != nil {
// Certificate update operation returns an SDKError instead of a NotFoundError.
var sdkError *sdkkonnecterrs.SDKError
if errors.As(errWrap, &sdkError) {
switch sdkError.StatusCode {
case 404:
if err := createCertificate(ctx, sdk, cert); err != nil {
return FailedKonnectOpError[configurationv1alpha1.KongCertificate]{
Op: UpdateOp,
Err: err,
}
}
// Create succeeded, createCertificate sets the status so no need to do this here.

return nil
default:
return FailedKonnectOpError[configurationv1alpha1.KongCertificate]{
Op: UpdateOp,
Err: sdkError,
}
}
}
return errWrap
}

Expand Down
14 changes: 10 additions & 4 deletions controller/konnect/ops/ops_kongconsumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,21 @@ func handleConsumerGroupAssignments(
populateConsumerGroupRefsValidCondition(invalidConsumerGroups, consumer)

if err != nil {
SetKonnectEntityProgrammedConditionFalse(consumer, konnectv1alpha1.KonnectEntityProgrammedReasonFailedToResolveConsumerGroupRefs, err.Error())
return err
return KonnectEntityCreatedButRelationsFailedError{
KonnectID: consumer.GetKonnectID(),
Reason: konnectv1alpha1.KonnectEntityProgrammedReasonFailedToResolveConsumerGroupRefs,
Err: err,
}
}

// Reconcile the ConsumerGroups assigned to the KongConsumer in Konnect (list the actual ConsumerGroups, calculate the
// difference, and add/remove the Consumer from the ConsumerGroups accordingly).
if err := reconcileConsumerGroupsWithKonnect(ctx, desiredConsumerGroupsIDs, cgSDK, cpID, consumer); err != nil {
SetKonnectEntityProgrammedConditionFalse(consumer, konnectv1alpha1.KonnectEntityProgrammedReasonFailedToReconcileConsumerGroupsWithKonnect, err.Error())
return err
return KonnectEntityCreatedButRelationsFailedError{
KonnectID: consumer.GetKonnectID(),
Reason: konnectv1alpha1.KonnectEntityProgrammedReasonFailedToReconcileConsumerGroupsWithKonnect,
Err: err,
}
}
return nil
}
Expand Down
4 changes: 1 addition & 3 deletions controller/konnect/ops/ops_kongdataplaneclientcertificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@ func createKongDataPlaneClientCertificate(
// Can't adopt it as it will cause conflicts between the controller
// that created that entity and already manages it, hm
if errWrap := wrapErrIfKonnectOpFailed(err, CreateOp, cert); errWrap != nil {
SetKonnectEntityProgrammedConditionFalse(cert, "FailedToCreate", errWrap.Error())
return errWrap
}

cert.Status.Konnect.SetKonnectID(*resp.DataPlaneClientCertificate.Item.ID)
SetKonnectEntityProgrammedCondition(cert)
cert.SetKonnectID(*resp.DataPlaneClientCertificate.Item.ID)

return nil
}
Expand Down
21 changes: 0 additions & 21 deletions controller/konnect/ops/ops_kongkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package ops

import (
"context"
"errors"
"fmt"

sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components"
sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations"
sdkkonnecterrs "github.com/Kong/sdk-konnect-go/models/sdkerrors"
"github.com/samber/lo"

sdkops "github.com/kong/gateway-operator/controller/konnect/ops/sdk"
Expand Down Expand Up @@ -69,26 +67,7 @@ func updateKey(
},
)

// TODO: handle already exists
// Can't adopt it as it will cause conflicts between the controller
// that created that entity and already manages it, hm
if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, key); errWrap != nil {
var sdkError *sdkkonnecterrs.SDKError
if errors.As(errWrap, &sdkError) {
if sdkError.StatusCode == 404 {
if err := createKey(ctx, sdk, key); err != nil {
return FailedKonnectOpError[configurationv1alpha1.KongKey]{
Op: UpdateOp,
Err: err,
}
}
return nil // createKey sets the status so we can return here.
}
return FailedKonnectOpError[configurationv1alpha1.KongKey]{
Op: UpdateOp,
Err: sdkError,
}
}
return errWrap
}

Expand Down
Loading

0 comments on commit bc480d9

Please sign in to comment.