Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(deployer): deprecate client side apply enforcement #5826

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/modules/ROOT/partials/apis/camel-k-crds.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6877,6 +6877,7 @@ bool
|


Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.

Expand Down
3 changes: 2 additions & 1 deletion docs/modules/traits/pages/deployer.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ The following configuration options are available:

| deployer.use-ssa
| bool
| Use server-side apply to update the owned resources (default `true`).
| Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.

|===
Expand Down
7 changes: 7 additions & 0 deletions helm/camel-k/crds/camel-k-crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4079,6 +4079,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down Expand Up @@ -6220,6 +6221,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down Expand Up @@ -8263,6 +8265,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down Expand Up @@ -10283,6 +10286,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down Expand Up @@ -18343,6 +18347,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down Expand Up @@ -26766,6 +26771,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down Expand Up @@ -37689,6 +37695,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/camel/v1/trait/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type DeployerTrait struct {
// Allows to explicitly select the desired deployment kind between `deployment`, `cron-job` or `knative-service` when creating the resources for running the integration.
// +kubebuilder:validation:Enum=deployment;cron-job;knative-service
Kind string `property:"kind" json:"kind,omitempty"`
// Deprecated: won't be able to enforce client side update in the future.
// Use server-side apply to update the owned resources (default `true`).
// Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
UseSSA *bool `property:"use-ssa" json:"useSSA,omitempty"`
Expand Down
93 changes: 5 additions & 88 deletions pkg/install/kamelets.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,30 @@ package install

import (
"context"
"encoding/json"
"errors"
"fmt"
"io/fs"
"net/http"
"os"
"path/filepath"
"strings"
"sync"
"sync/atomic"

"golang.org/x/sync/errgroup"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"

ctrl "sigs.k8s.io/controller-runtime/pkg/client"
logf "sigs.k8s.io/controller-runtime/pkg/log"

v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"

"github.com/apache/camel-k/v2/pkg/client"
"github.com/apache/camel-k/v2/pkg/util"
"github.com/apache/camel-k/v2/pkg/util/defaults"
"github.com/apache/camel-k/v2/pkg/util/kubernetes"
"github.com/apache/camel-k/v2/pkg/util/patch"
"github.com/apache/camel-k/v2/pkg/util/log"
)

const (
kameletDirEnv = "KAMELET_CATALOG_DIR"
defaultKameletDir = "/kamelets/"
)

var (
log = logf.Log

hasServerSideApply atomic.Value
tryServerSideApply sync.Once
)

// KameletCatalog installs the bundled Kamelets into the specified namespace.
func KameletCatalog(ctx context.Context, c client.Client, namespace string) error {
kameletDir := os.Getenv(kameletDirEnv)
Expand All @@ -76,6 +60,7 @@ func KameletCatalog(ctx context.Context, c client.Client, namespace string) erro
}

g, gCtx := errgroup.WithContext(ctx)
applier := c.ServerOrClientSideApplier()

err = filepath.WalkDir(kameletDir, func(p string, f fs.DirEntry, err error) error {
if err != nil {
Expand All @@ -93,38 +78,10 @@ func KameletCatalog(ctx context.Context, c client.Client, namespace string) erro
if err != nil {
return err
}
once := false
tryServerSideApply.Do(func() {
once = true
if err = serverSideApply(gCtx, c, kamelet); err != nil {
if isIncompatibleServerError(err) {
log.Info("Fallback to client-side apply for installing bundled Kamelets")
hasServerSideApply.Store(false)
err = nil
} else {
// Unexpected error occurred
err = fmt.Errorf("unexpected error occurred whilst validating kamelet: %w", err)
log.Error(err, "Error occurred whilst loading kamelets")
}
} else {
hasServerSideApply.Store(true)
}
})
if err != nil {
return err
}
v := hasServerSideApply.Load()
var bundleKamError error
if vb, ok := v.(bool); ok && vb {
if !once {
bundleKamError = serverSideApply(gCtx, c, kamelet)
}
} else {
bundleKamError = clientSideApply(gCtx, c, kamelet)
}
err = applier.Apply(gCtx, kamelet)
// We only log the error. If we returned the error, the creation of the ITP would have stopped
if bundleKamError != nil {
log.Error(bundleKamError, "Error occurred whilst applying bundled kamelet")
if err != nil {
log.Error(err, "Error occurred whilst applying bundled kamelet")
}
return nil
})
Expand All @@ -137,43 +94,6 @@ func KameletCatalog(ctx context.Context, c client.Client, namespace string) erro
return g.Wait()
}

func serverSideApply(ctx context.Context, c client.Client, resource runtime.Object) error {
target, err := patch.ApplyPatch(resource)
if err != nil {
return err
}
return c.Patch(ctx, target, ctrl.Apply, ctrl.ForceOwnership, ctrl.FieldOwner("camel-k-operator"))
}

func clientSideApply(ctx context.Context, c client.Client, resource ctrl.Object) error {
if err := c.Create(ctx, resource); err == nil {
return nil
} else if !k8serrors.IsAlreadyExists(err) {
return fmt.Errorf("error during create resource: %s/%s: %w", resource.GetNamespace(), resource.GetName(), err)
}
// Directly use the serialized resource as JSON merge patch since it's prescriptive
p, err := json.Marshal(resource)
if err != nil {
return err
}
return c.Patch(ctx, resource, ctrl.RawPatch(types.MergePatchType, p))
}

func isIncompatibleServerError(err error) bool {
// First simpler check for older servers (i.e. OpenShift 3.11)
if strings.Contains(err.Error(), "415: Unsupported Media Type") {
return true
}
// 415: Unsupported media type means we're talking to a server which doesn't
// support server-side apply.
var serr *k8serrors.StatusError
if errors.As(err, &serr) {
return serr.Status().Code == http.StatusUnsupportedMediaType
}
// Non-StatusError means the error isn't because the server is incompatible.
return false
}

func loadKamelet(path string, namespace string) (ctrl.Object, error) {
content, err := util.ReadFile(path)
if err != nil {
Expand Down Expand Up @@ -212,8 +132,5 @@ func loadKamelet(path string, namespace string) (ctrl.Object, error) {

// KameletViewerRole installs the role that allows any user ro access kamelets in the global namespace.
func KameletViewerRole(ctx context.Context, c client.Client, namespace string) error {
if err := Resource(ctx, c, namespace, true, IdentityResourceCustomizer, "/resources/viewer/user-global-kamelet-viewer-role.yaml"); err != nil {
return err
}
return Resource(ctx, c, namespace, true, IdentityResourceCustomizer, "/resources/viewer/user-global-kamelet-viewer-role-binding.yaml")
}
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down Expand Up @@ -3065,6 +3066,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down Expand Up @@ -2812,6 +2813,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6812,6 +6812,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6879,6 +6879,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down
1 change: 1 addition & 0 deletions pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6877,6 +6877,7 @@ spec:
type: string
useSSA:
description: |-
Deprecated: won't be able to enforce client side update in the future.
Use server-side apply to update the owned resources (default `true`).
Note that it automatically falls back to client-side patching, if SSA is not available, e.g., on old Kubernetes clusters.
type: boolean
Expand Down
Loading
Loading