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

feat(trait): let Camel runtime manages Kamelets #4812

Merged
merged 6 commits into from
Oct 16, 2023
Merged
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
8 changes: 8 additions & 0 deletions config/crd/bases/camel.apache.org_builds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,10 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a
Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers
the org.apache.camel.k.RoutesLoader uses to pre/post
Expand Down Expand Up @@ -1424,6 +1428,10 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a
Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers
the org.apache.camel.k.RoutesLoader uses to pre/post
Expand Down
3 changes: 3 additions & 0 deletions config/crd/bases/camel.apache.org_integrationkits.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers the org.apache.camel.k.RoutesLoader
uses to pre/post process sources
Expand Down
8 changes: 8 additions & 0 deletions config/crd/bases/camel.apache.org_integrationplatforms.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,10 @@ spec:
description: Comma separated list of Kamelet names to load
into the current integration
type: string
mountPoint:
description: The directory where the application mounts and
reads Kamelet spec (default `/etc/camel/kamelets`)
type: string
type: object
keda:
description: 'Deprecated: for backward compatibility.'
Expand Down Expand Up @@ -3004,6 +3008,10 @@ spec:
description: Comma separated list of Kamelet names to load
into the current integration
type: string
mountPoint:
description: The directory where the application mounts and
reads Kamelet spec (default `/etc/camel/kamelets`)
type: string
type: object
keda:
description: 'Deprecated: for backward compatibility.'
Expand Down
10 changes: 10 additions & 0 deletions config/crd/bases/camel.apache.org_integrations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers the org.apache.camel.k.RoutesLoader
uses to pre/post process sources
Expand Down Expand Up @@ -7107,6 +7110,10 @@ spec:
description: Comma separated list of Kamelet names to load
into the current integration
type: string
mountPoint:
description: The directory where the application mounts and
reads Kamelet spec (default `/etc/camel/kamelets`)
type: string
type: object
keda:
description: 'Deprecated: for backward compatibility.'
Expand Down Expand Up @@ -7916,6 +7923,9 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers the org.apache.camel.k.RoutesLoader
uses to pre/post process sources
Expand Down
7 changes: 7 additions & 0 deletions config/crd/bases/camel.apache.org_kameletbindings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers the org.apache.camel.k.RoutesLoader
uses to pre/post process sources
Expand Down Expand Up @@ -7393,6 +7396,10 @@ spec:
description: Comma separated list of Kamelet names to
load into the current integration
type: string
mountPoint:
description: The directory where the application mounts
and reads Kamelet spec (default `/etc/camel/kamelets`)
type: string
type: object
keda:
description: 'Deprecated: for backward compatibility.'
Expand Down
6 changes: 6 additions & 0 deletions config/crd/bases/camel.apache.org_kamelets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,9 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers the org.apache.camel.k.RoutesLoader
uses to pre/post process sources
Expand Down Expand Up @@ -1163,6 +1166,9 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers the org.apache.camel.k.RoutesLoader
uses to pre/post process sources
Expand Down
7 changes: 7 additions & 0 deletions config/crd/bases/camel.apache.org_pipes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers the org.apache.camel.k.RoutesLoader
uses to pre/post process sources
Expand Down Expand Up @@ -7391,6 +7394,10 @@ spec:
description: Comma separated list of Kamelet names to
load into the current integration
type: string
mountPoint:
description: The directory where the application mounts
and reads Kamelet spec (default `/etc/camel/kamelets`)
type: string
type: object
keda:
description: 'Deprecated: for backward compatibility.'
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/modules/ROOT/nav-end.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
*** xref:architecture/cr/camel-catalog.adoc[CamelCatalog]
** xref:architecture/runtime.adoc[Runtime]
** xref:architecture/traits.adoc[Traits]
** xref:architecture/kamelets.adoc[Kamelets]
** xref:architecture/incremental-image.adoc[Incremental Image]
* API
** xref:apis/camel-k.adoc[Camel K API]
Expand Down
21 changes: 21 additions & 0 deletions docs/modules/ROOT/pages/architecture/kamelets.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
= Kamelets architecture in Camel K

xref:kamelets/kamelets.adoc[Kamelets] are a technology which were originally developed as a Camel K side resource but moved into Camel framework as Kamelet component. From an design point of view, a Kamelet is a specification that is provided into the cluster and which can be used at any point by an Integration or a Pipe, in order to reuse the connector style approach.

In Camel framework, a Kamelet is nothing than a component which can be used as any other component with the `kamelet` uri scheme. This is translated to one or more Route Templates. What's important for Camel runtime is to have the Kamelet spec available somewhere when running the application making reference to it.

[[deployment-model]]
== Deployment model

In Camel K, it is worth to explain how the Kamelets are deployed in order to make Camel runtime application to correctly use the Kamelet referenced in the Integration. First of all, the operator uses a xref:traits:kamelets.adoc[Camel K trait] which is in charge to discover the Kamelets used in your route. This is due to get all the specification and dependencies required.

image::architecture/kamelets_deployment.png[Kamelets deployment model]

The operator creates a ConfigMap in order to bundle all the Kamelets which are eventually required by the application runtime. The Kamelets spec has to be available and in ready phase status. Once the application is created and ready to start, the operator mounts such a ConfigMap in a known location (default `/etc/camel/kamelets`) so that the Camel application will be able to read the definition from such location and run them according the logic expected in the same Camel framework.

NOTE: as the Configmap resource is limited to 1 MiB, the operator may split into more than a single Configmap bundle.

[[kamelet-parsing]]
=== Parsing capabilities defined in a Kamelet

The operator is in charge to perform one important hidden operation. The Kamelet specification may contains Camel components and capabilities which the user should be in charge to define explicitly. However, the operator extract the Kamelet source and parses its content as a generated Integration source. In this way you will be able to get all the Kubernetes resources which are required to run your Integration (ie, a Kamelet using rest or exposing http services).
11 changes: 10 additions & 1 deletion docs/modules/ROOT/pages/kamelets/kamelets-distribution.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,13 @@ kamel kamelet add-repo <git-platform>:<owner>/<repo>[/path_to_kamelets_folder][@
```
Mind that `<git-platform>` is the repository of your choice, for instance `github` and `[@version]` is the tag to use (by default it will use `main` branch).

With this approach you can dynamically include any repository where your Kamelets are hosted. They will be lazily initialized as soon as they are required by any of the Integration or Pipes which will make use of them.
With this approach you can dynamically include any repository where your Kamelets are hosted. They will be lazily initialized as soon as they are required by any of the Integration or Pipes which will make use of them.

[[kamelets-as-dependency]]
== Kamelets as a dependency

The Camel K has an opinionated way to use Kamelets which is the one exposed above. Here the Kamelet spec resource is expected to be available in the cluster.

However, you may find situations where you want to bundle a Kamelet in a dependency (ie, some external catalog containing all Kamelets spec). As Kamelets are a Camel thing, then, you can use such dependency and let the runtime use the Kamelets available in the classpath.

If you're using such an approach, then, you will need to make sure to skip the Kamelet trait (which is in charge to discover them and get required dependencies), and provide all the dependencies which may be required by your Kamelet. Additionally, you may need to specify a Camel property to tell the runtime where to expect to find the Kamelets, `camel.component.kamelet.location` (default `classpath:/kamelets`).
29 changes: 0 additions & 29 deletions docs/modules/ROOT/pages/kamelets/kamelets-user.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -205,35 +205,6 @@ from('timer:tick')
You can run this integration without specifying other parameters, the Kamelet endpoint will be implicitly configured by the Camel K operator that will
automatically mount the secret into the integration Pod.

[[kamelets-default-catalog]]
== Kamelets Catalog

When you install a Camel K Operator, you will have automatically a wide set of canned Kamelets available to be used. The catalog and the related documentation is available at link:/camel-kamelets/next/index.html[Apache Kamelets Catalog]. There is a CLI command very useful to have a quick list of the available Kamelets:
[source,shell]
----
$ kamel kamelet get
----

These Kamelets are installed by default when you install Camel K operator. You will be able to use them without worrying to install each of them, just look at the documentation and be ready to experiment how easy they are.

[[kamelets-custom-catalog]]
=== Use a custom Catalog

You can overwrite the default catalog by adding certain configuration to the `IntegrationPlatform`. In order to add a new repository, you must edit the `IntegrationPlatfom` and edit the `.spec.kamelet.repositories[].uri` field, which expects an array of repository URIs where you can host your catalog of Kamelets, ie:
[source,yaml]
----
spec:
...
kamelet:
repositories:
- uri: github:my-org/my-repo
...
----

By default the value is null, which means they fallback to the Apache Kamelets Catalog.

NOTE: this option is experimental and may be subjected to changes in future versions.

[[kamelets-usage-binding]]
== Binding Kamelets

Expand Down
14 changes: 14 additions & 0 deletions docs/modules/ROOT/partials/apis/camel-k-crds.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5064,6 +5064,13 @@ Type defines the kind of source described by this object

List of property names defined in the source (e.g. if type is "template")

|`from-kamelet` +
bool
|


True if the spec is generated from a Kamelet


|===

Expand Down Expand Up @@ -6932,6 +6939,13 @@ string

Comma separated list of Kamelet names to load into the current integration

|`mountPoint` +
string
|


The directory where the application mounts and reads Kamelet spec (default `/etc/camel/kamelets`)


|===

Expand Down
4 changes: 4 additions & 0 deletions docs/modules/traits/pages/kamelets.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ The following configuration options are available:
| string
| Comma separated list of Kamelet names to load into the current integration

| kamelets.mount-point
| string
| The directory where the application mounts and reads Kamelet spec (default `/etc/camel/kamelets`)

|===

// End of autogenerated code - DO NOT EDIT! (configuration)
21 changes: 21 additions & 0 deletions e2e/common/traits/files/webhook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ---------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ---------------------------------------------------------------------------

- from:
uri: "kamelet:capabilities-webhook-source"
steps:
- log: "${body}"
67 changes: 67 additions & 0 deletions e2e/common/traits/kamelet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//go:build integration
// +build integration

// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"

/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package traits

import (
"testing"

. "github.com/onsi/gomega"

corev1 "k8s.io/api/core/v1"

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

func TestKameletTrait(t *testing.T) {
RegisterTestingT(t)

t.Run("discover kamelet capabilities", func(t *testing.T) {
template := map[string]interface{}{
"from": map[string]interface{}{
"uri": "platform-http:///webhook",
"steps": []map[string]interface{}{
{
"to": "kamelet:sink",
},
},
},
}
Expect(CreateKamelet(ns, "capabilities-webhook-source", template, nil, nil)()).To(Succeed())

name := "webhook"
Expect(KamelRunWithID(operatorID, ns, "files/webhook.yaml", "--name", name).Execute()).To(Succeed())
Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Started capabilities-webhook-source-1 (platform-http:///webhook)"))
// Verify Integration capabilities
Eventually(IntegrationStatusCapabilities(ns, name), TestTimeoutShort).Should(ContainElements("platform-http"))
// Verify expected resources from Kamelet (Service in this case)
service := Service(ns, name)
Eventually(service, TestTimeoutShort).ShouldNot(BeNil())
})

// Clean-up
Expect(DeleteKamelet(ns, "capabilities-webhook-source")).To(Succeed())
Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
}
10 changes: 10 additions & 0 deletions e2e/support/test_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,16 @@ func IntegrationSpecProfile(ns string, name string) func() v1.TraitProfile {
}
}

func IntegrationStatusCapabilities(ns string, name string) func() []string {
return func() []string {
it := Integration(ns, name)()
if it == nil || &it.Status == nil {
return nil
}
return it.Status.Capabilities
}
}

func IntegrationSpecSA(ns string, name string) func() string {
return func() string {
it := Integration(ns, name)()
Expand Down
8 changes: 8 additions & 0 deletions helm/camel-k/crds/crd-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,10 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a
Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers
the org.apache.camel.k.RoutesLoader uses to pre/post
Expand Down Expand Up @@ -1424,6 +1428,10 @@ spec:
contentType:
description: the content type (tipically text or binary)
type: string
from-kamelet:
description: True if the spec is generated from a
Kamelet
type: boolean
interceptors:
description: Interceptors are optional identifiers
the org.apache.camel.k.RoutesLoader uses to pre/post
Expand Down
Loading
Loading