diff --git a/Makefile b/Makefile index 7a00b79c..adfc623d 100644 --- a/Makefile +++ b/Makefile @@ -20,8 +20,8 @@ OPERATOR_VERSION := $(subst -SNAPSHOT,,$(VERSION)) LAST_RELEASED_IMAGE_NAME := yaks-operator LAST_RELEASED_VERSION := 0.19.0 -CONTROLLER_GEN_VERSION := v0.6.1 -CODEGEN_VERSION := v0.25.6 +CONTROLLER_GEN_VERSION := v0.15.0 +CODEGEN_VERSION := v0.30.2 OPERATOR_SDK_VERSION := v1.28.0 KUSTOMIZE_VERSION := v4.5.4 DEFAULT_IMAGE := docker.io/citrusframework/yaks diff --git a/config/crd/bases/yaks.citrusframework.org_instances.yaml b/config/crd/bases/yaks.citrusframework.org_instances.yaml index f08a7bd5..674aa37d 100644 --- a/config/crd/bases/yaks.citrusframework.org_instances.yaml +++ b/config/crd/bases/yaks.citrusframework.org_instances.yaml @@ -20,8 +20,7 @@ metadata: labels: app: yaks annotations: - controller-gen.kubebuilder.io/version: v0.6.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: instances.yaks.citrusframework.org spec: group: yaks.citrusframework.org @@ -54,14 +53,19 @@ spec: description: Instance is the Schema for the yaks instance. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object diff --git a/config/crd/bases/yaks.citrusframework.org_tests.yaml b/config/crd/bases/yaks.citrusframework.org_tests.yaml index f96a1822..6c7d2915 100644 --- a/config/crd/bases/yaks.citrusframework.org_tests.yaml +++ b/config/crd/bases/yaks.citrusframework.org_tests.yaml @@ -20,8 +20,7 @@ metadata: labels: app: yaks annotations: - controller-gen.kubebuilder.io/version: v0.6.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: tests.yaks.citrusframework.org spec: group: yaks.citrusframework.org @@ -66,14 +65,19 @@ spec: description: Test is the Schema for the tests API. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -120,8 +124,10 @@ spec: verbose: type: boolean type: object - secret: - type: string + secrets: + items: + type: string + type: array selenium: description: SeleniumSpec --. properties: diff --git a/deploy/olm-catalog/yaks/0.19.2/yaks.citrusframework.org_instances.yaml b/deploy/olm-catalog/yaks/0.19.2/yaks.citrusframework.org_instances.yaml new file mode 100644 index 00000000..3b2ae087 --- /dev/null +++ b/deploy/olm-catalog/yaks/0.19.2/yaks.citrusframework.org_instances.yaml @@ -0,0 +1,100 @@ +# --------------------------------------------------------------------------- +# Copyright the original author or authors. +# +# Licensed 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. +# --------------------------------------------------------------------------- + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.1 + creationTimestamp: null + labels: + app: yaks + name: instances.yaks.citrusframework.org +spec: + group: yaks.citrusframework.org + names: + categories: + - yaks + - testing + kind: Instance + listKind: InstanceList + plural: instances + singular: instance + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: True if YAKS instance is global + jsonPath: .spec.operator.global + name: Global + type: boolean + - description: The YAKS operator pod name + jsonPath: .spec.operator.pod + name: Pod + type: string + - description: The YAKS version + jsonPath: .status.version + name: Version + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Instance is the Schema for the yaks instance. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: InstanceSpec provides the state of a yaks instance + properties: + operator: + description: OperatorSpec--. + properties: + global: + type: boolean + namespace: + type: string + pod: + type: string + required: + - global + type: object + type: object + status: + description: InstanceStatus defines the observed state of a yaks instance + properties: + version: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/deploy/olm-catalog/yaks/0.19.2/yaks.citrusframework.org_tests.yaml b/deploy/olm-catalog/yaks/0.19.2/yaks.citrusframework.org_tests.yaml new file mode 100644 index 00000000..fe330ea2 --- /dev/null +++ b/deploy/olm-catalog/yaks/0.19.2/yaks.citrusframework.org_tests.yaml @@ -0,0 +1,214 @@ +# --------------------------------------------------------------------------- +# Copyright the original author or authors. +# +# Licensed 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. +# --------------------------------------------------------------------------- + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.1 + creationTimestamp: null + labels: + app: yaks + name: tests.yaks.citrusframework.org +spec: + group: yaks.citrusframework.org + names: + categories: + - yaks + - testing + kind: Test + listKind: TestList + plural: tests + singular: test + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The test phase + jsonPath: .status.phase + name: Phase + type: string + - description: The total amount of tests + jsonPath: .status.results.summary.total + name: Total + type: string + - description: Passed tests + jsonPath: .status.results.summary.passed + name: Passed + type: string + - description: Failed tests + jsonPath: .status.results.summary.failed + name: Failed + type: string + - description: Skipped tests + jsonPath: .status.results.summary.skipped + name: Skipped + type: string + - description: Test error details + jsonPath: .status.errors + name: Errors + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Test is the Schema for the tests API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TestSpec defines the desired state of Test + properties: + config: + description: SettingsSpec --. + properties: + content: + type: string + name: + type: string + type: object + env: + items: + type: string + type: array + kubedock: + description: KubeDockSpec --. + properties: + image: + type: string + runAsUser: + type: integer + type: object + resources: + items: + description: ResourceSpec --. + properties: + content: + type: string + name: + type: string + type: object + type: array + runtime: + description: RuntimeSpec --. + properties: + logger: + items: + type: string + type: array + verbose: + type: boolean + type: object + secret: + type: string + selenium: + description: SeleniumSpec --. + properties: + env: + items: + type: string + type: array + image: + type: string + noVNC: + type: boolean + runAsUser: + type: integer + type: object + source: + description: SourceSpec --. + properties: + content: + type: string + language: + type: string + name: + type: string + type: object + type: object + status: + description: TestStatus defines the observed state of Test + properties: + digest: + type: string + errors: + type: string + phase: + description: TestPhase --. + type: string + results: + properties: + errors: + items: + type: string + type: array + suiteName: + type: string + summary: + properties: + errors: + type: integer + failed: + type: integer + passed: + type: integer + pending: + type: integer + skipped: + type: integer + total: + type: integer + undefined: + type: integer + type: object + tests: + items: + properties: + classname: + type: string + errorMessage: + type: string + errorType: + type: string + name: + type: string + type: object + type: array + type: object + testID: + type: string + version: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/deploy/olm-catalog/yaks/0.19.2/yaks.v0.19.2.clusterserviceversion.yaml b/deploy/olm-catalog/yaks/0.19.2/yaks.v0.19.2.clusterserviceversion.yaml new file mode 100644 index 00000000..787afd24 --- /dev/null +++ b/deploy/olm-catalog/yaks/0.19.2/yaks.v0.19.2.clusterserviceversion.yaml @@ -0,0 +1,437 @@ +# --------------------------------------------------------------------------- +# Copyright the original author or authors. +# +# Licensed 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. +# --------------------------------------------------------------------------- + +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "yaks.citrusframework.org/v1alpha1", + "kind": "Instance", + "metadata": { + "labels": { + "app": "yaks" + }, + "name": "example-instance" + }, + "spec": { + "operator": { + "global": true + } + } + }, + { + "apiVersion": "yaks.citrusframework.org/v1alpha1", + "kind": "Test", + "metadata": { + "labels": { + "app": "yaks" + }, + "name": "example-test" + }, + "spec": { + "source": { + "content": "Feature: hello world\n\n Scenario: print slogan\n Given YAKS does Cloud-Native BDD testing\n Then YAKS rocks!", + "language": "feature", + "name": "example.feature" + } + } + } + ] + capabilities: Full Lifecycle + categories: Integration & Delivery + certified: "false" + containerImage: docker.io/citrusframework/yaks:0.19.2 + createdAt: "2024-05-17T10:45:05Z" + description: YAKS is a platform to enable Cloud Native BDD testing on Kubernetes. + operators.operatorframework.io/builder: operator-sdk-v1.28.0 + operators.operatorframework.io/internal-objects: '["instances.yaks.citrusframework.org"]' + operators.operatorframework.io/project_layout: go.kubebuilder.io/v2 + repository: https://github.com/citrusframework/yaks + support: Citrus Framework + name: yaks-operator.v0.19.2 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: Instance is the Schema for the yaks instance + displayName: Instance + kind: Instance + name: instances.yaks.citrusframework.org + version: v1alpha1 + - description: Test is the Schema for the tests API + displayName: Test + kind: Test + name: tests.yaks.citrusframework.org + version: v1alpha1 + description: | + YAKS + ==== + + YAKS is a platform to enable Cloud Native BDD testing on Kubernetes. + + ## Running a YAKS test + + With the YAKS operator installed, you can run tests by creating a `Test` custom resource on the cluster. + + Tests are defined using [Gherkin](https://cucumber.io/docs/gherkin/) syntax. YAKS provides a set of predefined steps which + help to connect with different messaging transports (Http REST, JMS, Kafka, Knative eventing) and verify responses with + assertions on message header and body content. + + The example below defines a simple test resource. + + ``` + apiVersion: yaks.citrusframework.org/v1alpha1 + kind: Test + metadata: + name: example + spec: + source: + name: example.feature + content: |- + Feature: hello world + + Scenario: print slogan + Given YAKS does Cloud-Native BDD testing + Then YAKS rocks! + ``` + + Refer to the [YAKS repository](https://github.com/citrusframework/yaks) for more complex examples. + displayName: YAKS Operator + icon: + - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iNDkuMDcwNDkybW0iCiAgIGhlaWdodD0iNDcuNTEyNDYzbW0iCiAgIHZpZXdCb3g9IjAgMCA0OS4wNzA0OTIgNDcuNTEyNDYzIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmc4IgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjIgNWMzZTgwZCwgMjAxNy0wOC0wNiIKICAgc29kaXBvZGk6ZG9jbmFtZT0ibG9nby5zdmciCiAgIGlua3NjYXBlOmV4cG9ydC14ZHBpPSIzNjguNjMiCiAgIGlua3NjYXBlOmV4cG9ydC15ZHBpPSIzNjguNjMiPgogIDxkZWZzCiAgICAgaWQ9ImRlZnMyIiAvPgogIDxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBpZD0iYmFzZSIKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgYm9yZGVyb3BhY2l0eT0iMS4wIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp6b29tPSI0LjQxMDQyMTYiCiAgICAgaW5rc2NhcGU6Y3g9IjkyLjczMTY0MSIKICAgICBpbmtzY2FwZTpjeT0iODkuNzg3MzI4IgogICAgIGlua3NjYXBlOmRvY3VtZW50LXVuaXRzPSJtbSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJnODc0IgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE2ODAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTAwNSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iMjU2MCIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iMTk0IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNSI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGUgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICBpbmtzY2FwZTpsYWJlbD0iTGF5ZXIgMSIKICAgICBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIgogICAgIGlkPSJsYXllcjEiCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM3LjIzMDI1NCwtOTcuNjQwODEzKSI+CiAgICA8ZwogICAgICAgaWQ9Imc4NzQiCiAgICAgICB0cmFuc2Zvcm09Im1hdHJpeCgwLjUzNDQ2OTMsMCwwLDAuNTM0NDY5MywzOS4zMzE2MzcsOTguMjczNjY4KSI+CiAgICAgIDxwYXRoCiAgICAgICAgIHN0eWxlPSJmaWxsOiMwMDkxMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiM4Y2Q0OTA7c3Ryb2tlLXdpZHRoOjQuMzY2OTQ4NjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgICBpZD0icGF0aDEwMzQ5IgogICAgICAgICBkPSJtIDc4LjA0NzIwOCwxOS44MDAxMzEgYyAtMC41LC0xLjYgLTEuNywtMi45IC0zLjIsLTMuNyBsIC0zMC41LC0xNC42MDAwMDA1IGMgLTAuOCwtMC40IC0xLjcsLTAuNSAtMi41LC0wLjUgLTAuOCwwIC0xLjcsMCAtMi41LDAuMiBMIDguODQ3MjA3NiwxNS45MDAxMzEgYyAtMS41MDAwMDAyLDAuNyAtMi42MDAwMDAyLDIgLTMuMDAwMDAwMiwzLjcgbCAtNy41LDMyLjkgYyAtMC4zLDEuNyAwLjEsMy40IDEuMSw0LjggbCAyMS4xMDAwMDA2LDI2LjEgYyAxLjIsMS4yIDIuOSwyIDQuNiwyLjEgaCAzMy42IGMgMS44LDAuMiAzLjUsLTAuNiA0LjYsLTIuMSBsIDIxLjEsLTI2LjEgYyAxLC0xLjQgMS40LC0zLjEgMS4yLC00LjggeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgICAgPHBhdGgKICAgICAgICAgc3R5bGU9ImZpbGw6IzkyZmE5MTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6IzMwYjAzOTtzdHJva2Utd2lkdGg6MC41NjEzMDQ0NTtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgICBkPSJtIDMyLjc5Nzk2LDExLjk5MzQ4NCBjIDEuMjgwMzM1LDYuNTAzMTc2IDguOTA1NTQ2LDI0LjAyMDE5NiA4LjgzNjEzNCwyOC4yMjQ3MjkgNC4yMDY4NTUsLTkuNjMzNTY2IDUuNjYyOTUzLC0xOS43MzExMDcgNS40MTI5NzksLTI4LjMzOTMzOCBDIDQxLjcwMDE3Nyw3Ljc5OTg2OTcgMzYuMDUzODU1LDguNzg1MDU2NyAzMi43OTc5NiwxMS45OTM0ODQgWiIKICAgICAgICAgaWQ9InBhdGg4OTUiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2NjYyIgLz4KICAgICAgPHBhdGgKICAgICAgICAgc3R5bGU9ImZpbGw6IzkyZmE5MTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6IzMwYjAzOTtzdHJva2Utd2lkdGg6MC41NjEzMDQ0NTtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgICBkPSJtIDguODgyMjE0LDQxLjk0OTQ0IGMgNC45NTY5NTIsMS42NDI0NCAxNy43Njg4LDAuNTg0NjMyIDI3LjA5MzAyNCwyLjIzMDA4MyBDIDMxLjEyMzExNSwzNy4wODE1ODMgMjMuMjg2MzUyLDMxLjY3MzE2MSAxMi4yMTk3ODYsMjYuMjEzNzM1IDcuMDQyMjIyLDI4Ljg4NDE1NiA2Ljk0ODg3MjcsMzYuODgzMjk4IDguODgyMjE0LDQxLjk0OTQ0IFoiCiAgICAgICAgIGlkPSJwYXRoODk1LTMiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2NjYyIKICAgICAgICAgaW5rc2NhcGU6dHJhbnNmb3JtLWNlbnRlci14PSIwLjg5NjEzOTQyIgogICAgICAgICBpbmtzY2FwZTp0cmFuc2Zvcm0tY2VudGVyLXk9Ii0wLjY4NjM0NzUzIiAvPgogICAgICA8cGF0aAogICAgICAgICBzdHlsZT0iZmlsbDojOTJmYTkxO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTojMzBiMDM5O3N0cm9rZS13aWR0aDowLjU2MTMwNDQ1O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICAgIGQ9Ik0gMTQuNjQ1MjQyLDYzLjgwNDAzMiBDIDM1LjE3NTAyOCw1MS4zMjY0ODQgMzYuNTc2Njk4LDQ3LjI0MTA3NyAzNi41NzY2OTgsNDcuMjQxMDc3IDI4LjY2MzAzMiw0OS4xMzQzMjQgOC44ODIyMTQsNDEuOTQ5NDQgNS43NDU1NjE2LDQ5Ljk2NDYyMyA2LjEyMjY2NzMsNTMuOTU5NDU2IDguMzY1NTk0Myw2Mi4yNDI4MzEgMTQuNjQ1MjQyLDYzLjgwNDAzMiBaIgogICAgICAgICBpZD0icGF0aDg5NS0zLTYiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2NjYyIKICAgICAgICAgaW5rc2NhcGU6dHJhbnNmb3JtLWNlbnRlci14PSIwLjk0MTE4MTU2IgogICAgICAgICBpbmtzY2FwZTp0cmFuc2Zvcm0tY2VudGVyLXk9IjIuMDU1MDM4OCIgLz4KICAgICAgPHBhdGgKICAgICAgICAgc3R5bGU9ImZpbGw6IzkyZmE5MTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6IzMwYjAzOTtzdHJva2Utd2lkdGg6MC41NjEzMDQ0NTtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgICBkPSJtIDMxLjk0NDU2Myw3OC4xMjIxOSBjIDYuMzI3NiwtMjMuMTc1OTExIDYuODgwNDMsLTI4LjQ5MzI0NiA2Ljg4MDQzLC0yOC40OTMyNDYgLTQuMzQyNDMyLDguNTcyMjQ4IC0xOS4zOTEzMDksMTEuNjgxMzQgLTIwLjIwOTIwMywyMC41NjkxMzggMy4wMjA1NzUsNC4xNDE1OTIgOC4wOTcyNDcsOS4zNTA1NDQgMTMuMzI4NzczLDcuOTI0MTA4IHoiCiAgICAgICAgIGlkPSJwYXRoODk1LTMtNi03IgogICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICBzb2RpcG9kaTpub2RldHlwZXM9ImNjY2MiCiAgICAgICAgIGlua3NjYXBlOnRyYW5zZm9ybS1jZW50ZXIteD0iMS4yMjM5MDE0IgogICAgICAgICBpbmtzY2FwZTp0cmFuc2Zvcm0tY2VudGVyLXk9IjEuMzc0MDI2OCIgLz4KICAgICAgPHBhdGgKICAgICAgICAgc3R5bGU9ImZpbGw6IzkyZmE5MTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6IzMwYjAzOTtzdHJva2Utd2lkdGg6MC41NjEzMDQ0NTtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgICBkPSJNIDU2LjcyMzQ3NCw3Ni45MDg2ODEgQyA1Ny41NzI2OTEsNzAuNzc2MDUxIDQ3Ljk2NTg2OCw1Ny40NjY4MzkgNDIuMDk5MDQ3LDUwLjM0NDg5IDQwLjU3NTIwNCw2MC45NDA5NTUgMzcuMDYwNzk0LDcxLjcyMzgzNiA0My44MTYzMDMsNzguNzEwOTMyIDQ3Ljc5NDE2NCw3OC4xODQxNTcgNTUuMDkzNDM1LDgwLjUzMDc0IDU2LjcyMzQ3NCw3Ni45MDg2ODEgWiIKICAgICAgICAgaWQ9InBhdGg4OTUtMy02LTctNSIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgc29kaXBvZGk6bm9kZXR5cGVzPSJjY2NjIgogICAgICAgICBpbmtzY2FwZTp0cmFuc2Zvcm0tY2VudGVyLXg9Ii0yLjA0MjI4NTEiCiAgICAgICAgIGlua3NjYXBlOnRyYW5zZm9ybS1jZW50ZXIteT0iMC45NzIxMDMxNyIgLz4KICAgICAgPHBhdGgKICAgICAgICAgc3R5bGU9ImZpbGw6IzkyZmE5MTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6IzMwYjAzOTtzdHJva2Utd2lkdGg6MC41NjEzMDQ0NTtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgICBkPSJNIDczLjM3MTE1Miw1OC41MTI1OTkgQyA3MS4yNzMzODYsNTQuNDUyOTgzIDQ0LjgxNzA3NSw0OC4yNTI5OTQgNDQuODE3MDc1LDQ4LjI1Mjk5NCBjIDQuMTk3Mzc3LDUuMzU2OTg3IDEzLjQ0NzQzLDIwLjgyOTgwNyAxOS45ODAyNjQsMjMuNTE2MDE4IDIuOTU0MTk0LC0yLjcxNTQ0IDkuNDMwNjgxLC03LjkwMjAzNiA4LjU3MzgxMywtMTMuMjU2NDEzIHoiCiAgICAgICAgIGlkPSJwYXRoODk1LTMtNi03LTUtMyIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgc29kaXBvZGk6bm9kZXR5cGVzPSJjY2NjIgogICAgICAgICBpbmtzY2FwZTp0cmFuc2Zvcm0tY2VudGVyLXg9Ii0xLjQ4Nzc2ODIiCiAgICAgICAgIGlua3NjYXBlOnRyYW5zZm9ybS1jZW50ZXIteT0iMS4yNDgwMzM3IiAvPgogICAgICA8cGF0aAogICAgICAgICBzdHlsZT0iZmlsbDojOTJmYTkxO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTojMzBiMDM5O3N0cm9rZS13aWR0aDowLjU2MTMwNDQ1O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICAgIGQ9Im0gNzIuMTEzNzc0LDM2LjcyOTA0IGMgLTExLjk0NDU5OSwxLjg3NjU2MSAtMjUuODIwOTc3LDguODM3MDgxIC0yNS44MjA5NzcsOC44MzcwODEgNy41NTk3NzYsMS4wMTk3MDcgMjEuNzc4ODI2LDkuMDEyMTA1IDI5LjgzNTAxMiw2LjczODE0NCAwLjQ3MjA5OCwtMy45ODQ3MiAwLjExOTMwNSwtMTIuMDY1Mzc3IC00LjAxNDAzNSwtMTUuNTc1MjI1IHoiCiAgICAgICAgIGlkPSJwYXRoODk1LTMtNi03LTUtMy01IgogICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICBzb2RpcG9kaTpub2RldHlwZXM9ImNjY2MiCiAgICAgICAgIGlua3NjYXBlOnRyYW5zZm9ybS1jZW50ZXIteD0iLTAuOTA2MzE3MzciCiAgICAgICAgIGlua3NjYXBlOnRyYW5zZm9ybS1jZW50ZXIteT0iLTEuNjg4NTU4NyIgLz4KICAgICAgPHBhdGgKICAgICAgICAgc3R5bGU9ImZpbGw6IzkyZmE5MTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6IzMwYjAzOTtzdHJva2Utd2lkdGg6MC41NjEzMDQ0NTtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgICBkPSJtIDE2Ljg0Njg5NywyMy4wMjM4MjEgYyAzLjQ5Njc0Miw1LjUyMDc2NyAxNS4wMzY1NDcsMTAuNTU3ODE0IDIyLjI2MjUzMiwxOC4zMzk2NDQgLTAuODIyMDQ3LC04LjU4MDMxOSAtNy4xNTcyMDcsLTIwLjk0NDI4NiAtMTIuNzE4ODcyLC0yNy41MTkzOTMgLTMuODEyNzM1LDEuMjUwNTgxIC04LjYwMTkwNyw0LjIwMjQ3MiAtOS41NDM2Niw5LjE3OTc0OSB6IgogICAgICAgICBpZD0icGF0aDg5NS02IgogICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICBzb2RpcG9kaTpub2RldHlwZXM9ImNjY2MiIC8+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4K + mediatype: image/svg+xml + install: + spec: + clusterPermissions: + - rules: + - apiGroups: + - console.openshift.io + resources: + - consoleclidownloads + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + serviceAccountName: yaks-operator + deployments: + - label: + app: yaks + yaks.citrusframework.org/component: operator + name: yaks-operator + spec: + replicas: 1 + selector: + matchLabels: + app: yaks + name: yaks-operator + strategy: + type: Recreate + template: + metadata: + labels: + app: yaks + name: yaks-operator + yaks.citrusframework.org/component: operator + spec: + containers: + - command: + - yaks + - operator + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: OPERATOR_NAME + value: yaks + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: docker.io/citrusframework/yaks:0.19.1 + imagePullPolicy: IfNotPresent + name: yaks-operator + resources: {} + serviceAccountName: yaks-operator + permissions: + - rules: + - apiGroups: + - yaks.citrusframework.org + resources: + - '*' + verbs: + - '*' + - apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - batch + resources: + - jobs/status + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - pods + - pods/exec + - services + - endpoints + - persistentvolumeclaims + - configmaps + - secrets + - serviceaccounts + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - pods/log + - pods/status + verbs: + - get + - list + - watch + - apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + - rolebindings + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - clusterrolebindings + verbs: + - get + - list + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - get + - list + - watch + - apiGroups: + - apps + resources: + - deployments + - replicasets + - statefulsets + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - camel.apache.org + resources: + - integrations + - kamelets + - kameletbindings + - pipes + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - eventing.knative.dev + resources: + - brokers + - triggers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - messaging.knative.dev + resources: + - channels + - inmemorychannels + - subscriptions + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - sources.knative.dev + resources: + - '*' + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + - apiGroups: + - kafka.strimzi.io + resources: + - kafkatopics + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + serviceAccountName: yaks-operator + strategy: deployment + installModes: + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - yaks + - testing + - microservices + - knative + - kafka + - serverless + - camel + - camel-k + labels: + name: yaks-operator + links: + - name: Project page + url: https://citrusframework.org/ + - name: YAKS source code repository + url: https://github.com/citrusframework/yaks + maintainers: + - email: cdeppisch@redhat.com + name: Christoph Deppisch + - email: nferraro@redhat.com + name: Nicola Ferraro + maturity: alpha + minKubeVersion: 1.22.0 + provider: + name: Citrus Framework + replaces: yaks-operator.v0.19.1 + selector: + matchLabels: + name: yaks-operator + version: 0.19.2 diff --git a/deploy/olm-catalog/yaks/0.20.0-snapshot/yaks.citrusframework.org_instances.yaml b/deploy/olm-catalog/yaks/0.20.0-snapshot/yaks.citrusframework.org_instances.yaml index 0add3b47..674aa37d 100644 --- a/deploy/olm-catalog/yaks/0.20.0-snapshot/yaks.citrusframework.org_instances.yaml +++ b/deploy/olm-catalog/yaks/0.20.0-snapshot/yaks.citrusframework.org_instances.yaml @@ -17,11 +17,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.6.1 - creationTimestamp: null labels: app: yaks + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 name: instances.yaks.citrusframework.org spec: group: yaks.citrusframework.org @@ -54,14 +53,19 @@ spec: description: Instance is the Schema for the yaks instance. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -92,9 +96,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/deploy/olm-catalog/yaks/0.20.0-snapshot/yaks.citrusframework.org_tests.yaml b/deploy/olm-catalog/yaks/0.20.0-snapshot/yaks.citrusframework.org_tests.yaml index 7d4c5f85..6c7d2915 100644 --- a/deploy/olm-catalog/yaks/0.20.0-snapshot/yaks.citrusframework.org_tests.yaml +++ b/deploy/olm-catalog/yaks/0.20.0-snapshot/yaks.citrusframework.org_tests.yaml @@ -17,11 +17,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.6.1 - creationTimestamp: null labels: app: yaks + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 name: tests.yaks.citrusframework.org spec: group: yaks.citrusframework.org @@ -66,14 +65,19 @@ spec: description: Test is the Schema for the tests API. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -120,8 +124,10 @@ spec: verbose: type: boolean type: object - secret: - type: string + secrets: + items: + type: string + type: array selenium: description: SeleniumSpec --. properties: @@ -206,9 +212,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/examples/kamelets/hello-source.kamelet.yaml b/examples/kamelets/hello-source.kamelet.yaml index 32a77da3..e3afcf5a 100644 --- a/examples/kamelets/hello-source.kamelet.yaml +++ b/examples/kamelets/hello-source.kamelet.yaml @@ -14,7 +14,7 @@ # limitations under the License. # --------------------------------------------------------------------------- -apiVersion: camel.apache.org/v1alpha1 +apiVersion: camel.apache.org/v1 kind: Kamelet metadata: name: hello-source @@ -41,5 +41,5 @@ spec: period: "{{period}}" steps: - set-body: - constant: "Hello world!" + constant: "Hello World!" - to: "kamelet:sink" diff --git a/examples/kamelets/hello-to-log-binding.yaml b/examples/kamelets/hello-to-log-binding.yaml index 9cd9ce75..d8b30fa6 100644 --- a/examples/kamelets/hello-to-log-binding.yaml +++ b/examples/kamelets/hello-to-log-binding.yaml @@ -22,7 +22,7 @@ spec: source: ref: kind: Kamelet - apiVersion: camel.apache.org/v1alpha1 + apiVersion: camel.apache.org/v1 name: hello-source sink: uri: log:info diff --git a/examples/kamelets/kamelet-binding.feature b/examples/kamelets/kamelet-pipe.feature similarity index 50% rename from examples/kamelets/kamelet-binding.feature rename to examples/kamelets/kamelet-pipe.feature index b2c162f4..627c0302 100644 --- a/examples/kamelets/kamelet-binding.feature +++ b/examples/kamelets/kamelet-pipe.feature @@ -1,11 +1,4 @@ -Feature: Kamelet resource - - Background: - Given Disable auto removal of Kamelet resources - Given Disable auto removal of Kubernetes resources - Given Camel K resource polling configuration - | maxAttempts | 20 | - | delayBetweenAttempts | 1000 | +Feature: Kamelet pipe Scenario: Bind Kamelet to service # Create Kamelet from file @@ -14,24 +7,24 @@ Feature: Kamelet resource # Create the binding Given create Kubernetes service greeting-service with target port 8080 - And KameletBinding source properties + And Pipe source properties | message | Hello World | And bind Kamelet hello-source to uri http://greeting-service.${YAKS_NAMESPACE}/greeting - When create KameletBinding hello-source-uri - Then KameletBinding hello-source-uri should be available + When create Pipe hello-source-uri + Then Pipe hello-source-uri should be available # Verify binding Given HTTP server "greeting-service" And HTTP server timeout is 600000 ms - Then expect HTTP request body: Hello World + Then expect HTTP request body: Hello World! And receive POST /greeting Scenario: Create binding from YAML - Given load KameletBinding hello-to-log-binding.yaml - Then KameletBinding hello-to-log-binding should be available - And Camel K integration hello-to-log-binding should print Hello world! + Given load Pipe hello-to-log-binding.yaml + Then Pipe hello-to-log-binding should be available + And Camel K integration hello-to-log-binding should print Hello World! Scenario: Remove Camel K resources Given delete Kamelet hello-source - Given delete KameletBinding hello-source-uri - Given delete KameletBinding hello-to-log-binding + Given delete Pipe hello-source-uri + Given delete Pipe hello-to-log-binding diff --git a/examples/kamelets/kamelet-resource.feature b/examples/kamelets/kamelet-resource.feature index dcc957c5..1bd4a384 100644 --- a/examples/kamelets/kamelet-resource.feature +++ b/examples/kamelets/kamelet-resource.feature @@ -1,12 +1,5 @@ Feature: Kamelet resource - Background: - Given Disable auto removal of Camel K resources - Given Disable auto removal of Kamelet resources - Given Camel K resource polling configuration - | maxAttempts | 200 | - | delayBetweenAttempts | 1000 | - Scenario: Use Kamelet Given load Camel K integration timer-to-log.groovy Then Camel K integration timer-to-log should be running diff --git a/examples/kamelets/kamelet.feature b/examples/kamelets/kamelet.feature index 0740a042..0930a19b 100644 --- a/examples/kamelets/kamelet.feature +++ b/examples/kamelets/kamelet.feature @@ -1,12 +1,5 @@ Feature: Kamelet - Background: - Given Disable auto removal of Camel K resources - Given Disable auto removal of Kamelet resources - Given Camel K resource polling configuration - | maxAttempts | 200 | - | delayBetweenAttempts | 1000 | - Scenario: Create Kamelet Given Kamelet property definition | name | message | diff --git a/examples/kamelets/yaks-config.yaml b/examples/kamelets/yaks-config.yaml index 942b46af..1c23bad6 100644 --- a/examples/kamelets/yaks-config.yaml +++ b/examples/kamelets/yaks-config.yaml @@ -17,8 +17,14 @@ config: runtime: env: - - name: YAKS_KAMELET_API_VERSION - value: v1alpha1 + - name: YAKS_CAMELK_MAX_ATTEMPTS + value: 100 + - name: YAKS_CAMELK_DELAY_BETWEEN_ATTEMPTS + value: 1000 + - name: YAKS_CAMELK_AUTO_REMOVE_RESOURCES + value: false + - name: YAKS_KAMELETS_AUTO_REMOVE_RESOURCES + value: false settings: loggers: - name: INTEGRATION_STATUS diff --git a/go.mod b/go.mod index 5f6e2855..b52a31ac 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/citrusframework/yaks -go 1.21 +go 1.22 require ( github.com/Masterminds/semver v1.5.0 @@ -11,30 +11,30 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/mapstructure v1.5.0 // go get github.com/openshift/api@release-4.14 - github.com/openshift/api v0.0.0-20240304080513-3e8192a10b13 + github.com/openshift/api v0.0.0-20240228005710-4511c790cc60 github.com/operator-framework/api v0.20.0 github.com/pkg/errors v0.9.1 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.67.1 - github.com/rs/xid v1.4.0 + github.com/rs/xid v1.5.0 github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.18.2 + github.com/spf13/viper v1.19.0 github.com/stoewer/go-strcase v1.3.0 github.com/stretchr/testify v1.9.0 - go.uber.org/multierr v1.10.0 - go.uber.org/zap v1.26.0 + go.uber.org/multierr v1.11.0 + go.uber.org/zap v1.27.0 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.27.7 - k8s.io/apiextensions-apiserver v0.27.7 - k8s.io/apimachinery v0.27.7 - k8s.io/client-go v0.27.7 + k8s.io/api v0.28.8 + k8s.io/apiextensions-apiserver v0.28.8 + k8s.io/apimachinery v0.28.8 + k8s.io/client-go v0.28.8 k8s.io/klog/v2 v2.120.1 - k8s.io/kubectl v0.27.7 - knative.dev/eventing v0.39.3 - sigs.k8s.io/controller-runtime v0.15.2 + k8s.io/kubectl v0.28.8 + knative.dev/eventing v0.40.3 + sigs.k8s.io/controller-runtime v0.16.5 ) require ( @@ -49,21 +49,21 @@ require ( github.com/cloudevents/sdk-go/sql/v2 v2.13.0 // indirect github.com/cloudevents/sdk-go/v2 v2.15.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.10.2 // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.7.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.8.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/zapr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.1 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/gnostic v0.6.9 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect @@ -76,18 +76,17 @@ require ( github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/minio/minio-go v6.0.14+incompatible // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.17.0 // indirect - github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.1 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/rickb777/date v1.13.0 // indirect github.com/rickb777/plural v1.2.1 // indirect @@ -102,31 +101,31 @@ require ( go.opencensus.io v0.24.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sync v0.5.0 // indirect + golang.org/x/net v0.23.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect + golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/api v0.153.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/grpc v1.59.0 // indirect + google.golang.org/api v0.171.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect + google.golang.org/grpc v1.62.1 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/component-base v0.27.7 // indirect - k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect + k8s.io/component-base v0.28.8 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect - knative.dev/pkg v0.0.0-20231023151236-29775d7c9e5c // indirect + knative.dev/pkg v0.0.0-20240116073220-b488e7be5902 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) replace github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 // Required by Helm diff --git a/go.sum b/go.sum index 97a2cff2..e43eea77 100644 --- a/go.sum +++ b/go.sum @@ -39,7 +39,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -60,11 +59,9 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -78,30 +75,26 @@ github.com/cloudevents/sdk-go/sql/v2 v2.13.0/go.mod h1:XZRQBCgRreddIpQrdjBJQUrRg github.com/cloudevents/sdk-go/v2 v2.15.2 h1:54+I5xQEnI73RBhWHxbI1XJcqOFOVJN85vb41+8mHUc= github.com/cloudevents/sdk-go/v2 v2.15.2/go.mod h1:lL7kSWAE/V8VI4Wh0jbL2v/jvqsm6tjmaQBSvxcv4uE= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/container-tools/snap v0.0.10 h1:osH6xx67USIME5tz0HQ/EBZc7jgbPQwBG5aFwpDKYy4= github.com/container-tools/snap v0.0.10/go.mod h1:oc/WJPTvUx+p4opnHu0S3hA0b//4zelB35lWt7xGNQ0= +github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo= +github.com/coreos/go-oidc/v3 v3.9.0/go.mod h1:rTKz2PYwftcrtoCzV5g5kvfJoWcm0Mk8AF8y1iAQro4= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= -github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= -github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= +github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= +github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -115,6 +108,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -133,8 +128,8 @@ github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= -github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -144,8 +139,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -174,12 +169,12 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= -github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -191,6 +186,7 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -215,9 +211,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-retryablehttp v0.6.7 h1:8/CAEZt/+F7kR7GevNHulKkUjLht3CPmn7egmhieNKo= +github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= @@ -250,7 +249,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -264,8 +262,6 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o= github.com/minio/minio-go v6.0.14+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -289,22 +285,18 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= -github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= -github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= -github.com/openshift/api v0.0.0-20240103200955-7ca3a4634e46 h1:mnrBzHjjqYKw2uinOVXL9Eplj3+QaQwJ3SaWAs8l6cc= -github.com/openshift/api v0.0.0-20240103200955-7ca3a4634e46/go.mod h1:aQ6LDasvHMvHZXqLHnX2GRmnfTWCF/iIwz8EMTTIE9A= -github.com/openshift/api v0.0.0-20240304080513-3e8192a10b13 h1:KNaEkpcVi4XGb86cA6FMJ8Wia7KWAembCUv8blIksTY= -github.com/openshift/api v0.0.0-20240304080513-3e8192a10b13/go.mod h1:yimSGmjsI+XF1mr+AKBs2//fSXIOhhetHGbMlBEfXbs= -github.com/openshift/api v3.9.1-0.20190927182313-d4a64ec2cbd8+incompatible h1:YwFnUQ5RQ17CmkxHyjpQnWAQOGkLKXY0shOUEyqaCGk= -github.com/openshift/api v3.9.1-0.20190927182313-d4a64ec2cbd8+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/openshift/api v0.0.0-20240228005710-4511c790cc60 h1:BfN2JThYjmpXhULHahY1heyfct+fsj4fhkUo3tVIGH4= +github.com/openshift/api v0.0.0-20240228005710-4511c790cc60/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU= github.com/operator-framework/api v0.20.0 h1:A2YCRhr+6s0k3pRJacnwjh1Ue8BqjIGuQ2jvPg9XCB4= github.com/operator-framework/api v0.20.0/go.mod h1:rXPOhrQ6mMeXqCmpDgt1ALoar9ZlHL+Iy5qut9R99a4= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -321,30 +313,30 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= +github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/rickb777/date v1.13.0 h1:+8AmwLuY1d/rldzdqvqTEg7107bZ8clW37x4nsdG3Hs= @@ -355,10 +347,10 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= @@ -377,7 +369,6 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -386,20 +377,19 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -413,14 +403,12 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -429,26 +417,26 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -484,8 +472,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -519,13 +508,14 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -533,8 +523,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -547,8 +537,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -596,6 +587,7 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -607,9 +599,9 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -661,8 +653,9 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -686,16 +679,16 @@ google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= -google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -727,13 +720,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c h1:lfpJ/2rWPa/kJgxyyXM8PrNnfCzcmxJ265mADgwmvLI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -746,12 +738,9 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -764,7 +753,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= @@ -792,7 +780,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -803,36 +790,36 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.27.7 h1:7yG4D3t/q4utJe2ptlRw9aPuxcSmroTsYxsofkQNl/A= -k8s.io/api v0.27.7/go.mod h1:ZNExI/Lhrs9YrLgVWx6jjHZdoWCTXfBXuFjt1X6olro= -k8s.io/apiextensions-apiserver v0.27.7 h1:YqIOwZAUokzxJIjunmUd4zS1v3JhK34EPXn+pP0/bsU= -k8s.io/apiextensions-apiserver v0.27.7/go.mod h1:x0p+b5a955lfPz9gaDeBy43obM12s+N9dNHK6+dUL+g= -k8s.io/apimachinery v0.27.7 h1:Gxgtb7Y/Rsu8ymgmUEaiErkxa6RY4oTd8kNUI6SUR58= -k8s.io/apimachinery v0.27.7/go.mod h1:jBGQgTjkw99ef6q5hv1YurDd3BqKDk9YRxmX0Ozo0i8= -k8s.io/client-go v0.27.7 h1:+Xgh9OOKv6A3qdD4Dnl/0VOI5EvAv+0s/OseDxVVTwQ= -k8s.io/client-go v0.27.7/go.mod h1:dZ2kqcalYp5YZ2EV12XIMc77G6PxHWOJp/kclZr4+5Q= -k8s.io/component-base v0.27.7 h1:kngM58HR9W9Nqpv7e4rpdRyWnKl/ABpUhLAZ+HoliMs= -k8s.io/component-base v0.27.7/go.mod h1:YGjlCVL1oeKvG3HSciyPHFh+LCjIEqsxz4BDR3cfHRs= +k8s.io/api v0.28.8 h1:G0/G7yX1puRAcon/+XPLsKXZ9A5L7Ds6oKbDIe027xw= +k8s.io/api v0.28.8/go.mod h1:rU8f1t9CNUAXlk/1j/wMJ7XnaxkR1g1AlZGQAOOL+sw= +k8s.io/apiextensions-apiserver v0.28.8 h1:JucS9tcaMMlfFrJ09cgh1Maeb8X2wlnxcfNpplyGHXs= +k8s.io/apiextensions-apiserver v0.28.8/go.mod h1:IKpLiKmvEYq/ti8sNtB1sM3A3vVV7fILIsvdmZswhoQ= +k8s.io/apimachinery v0.28.8 h1:hi/nrxHwk4QLV+W/SHve1bypTE59HCDorLY1stBIxKQ= +k8s.io/apimachinery v0.28.8/go.mod h1:cBnwIM3fXoRo28SqbV/Ihxf/iviw85KyXOrzxvZQ83U= +k8s.io/client-go v0.28.8 h1:TE59Tjd87WKvS2FPBTfIKLFX0nQJ4SSHsnDo5IHjgOw= +k8s.io/client-go v0.28.8/go.mod h1:uDVQ/rPzWpWIy40c6lZ4mUwaEvRWGnpoqSO4FM65P3o= +k8s.io/component-base v0.28.8 h1:N/c5L6Ty5rcrFyhsMYsqRFUOVGrqGQsLfjB0yj6npqM= +k8s.io/component-base v0.28.8/go.mod h1:9PjQ4nM1Hth6WGe/O+wgLF32eSwf4oPOoN5elmFznJM= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/kubectl v0.27.7 h1:HTEDa4s/oWjB3t5ysdW1yKlcNl9bzigcqWBq0LIIe3k= -k8s.io/kubectl v0.27.7/go.mod h1:Xb1Ubc8uN1i2RvSN1HCgSHTtzgX0woihMk/gW7XbjJU= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/kubectl v0.28.8 h1:bukHhQp4f7QYBFjS3iZTHKecrRpfZsR5lCCKFpbiUQw= +k8s.io/kubectl v0.28.8/go.mod h1:X3u3VYbeWR1JirXkvtvq6b0kJ002M2ZQSk42M0ayKT8= k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -knative.dev/eventing v0.39.3 h1:I3/56fQ3t0t1cAG/6j4f0D+FNo+9avn1Ij2N9jXKSXM= -knative.dev/eventing v0.39.3/go.mod h1:MlEiEcHALqZnu0OFMuWdJfjBzM7HlSJfk8pQbTcIy4o= -knative.dev/pkg v0.0.0-20231023151236-29775d7c9e5c h1:xyPoEToTWeBdn6tinhLxXfnhJhTNQt5WzHiTNiFphRw= -knative.dev/pkg v0.0.0-20231023151236-29775d7c9e5c/go.mod h1:HHRXEd7ZlFpthgE+rwAZ6MUVnuJOAeolnaFSthXloUQ= +knative.dev/eventing v0.40.3 h1:Fjc5QqHRSuW6sLQ848bZvVAuurQAUbgnLMnwcn44Cc0= +knative.dev/eventing v0.40.3/go.mod h1:+yUUIyvX9fn9bCSH3012kc8rG7YBbjvvxwy1Kr53dRc= +knative.dev/pkg v0.0.0-20240116073220-b488e7be5902 h1:H6+JJN23fhwYWCHY1339sY6uhIyoUwDy1a8dN233fdk= +knative.dev/pkg v0.0.0-20240116073220-b488e7be5902/go.mod h1:NYk8mMYoLkO7CQWnNkti4YGGnvLxN6MIDbUvtgeo0C0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/controller-runtime v0.15.2 h1:9V7b7SDQSJ08IIsJ6CY1CE85Okhp87dyTMNDG0FS7f4= -sigs.k8s.io/controller-runtime v0.15.2/go.mod h1:7ngYvp1MLT+9GeZ+6lH3LOlcHkp/+tzA/fmHa4iq9kk= +sigs.k8s.io/controller-runtime v0.16.5 h1:yr1cEJbX08xsTW6XEIzT13KHHmIyX8Umvme2cULvFZw= +sigs.k8s.io/controller-runtime v0.16.5/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/helm/yaks/crds/crd-instance.yaml b/helm/yaks/crds/crd-instance.yaml index f08a7bd5..674aa37d 100644 --- a/helm/yaks/crds/crd-instance.yaml +++ b/helm/yaks/crds/crd-instance.yaml @@ -20,8 +20,7 @@ metadata: labels: app: yaks annotations: - controller-gen.kubebuilder.io/version: v0.6.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: instances.yaks.citrusframework.org spec: group: yaks.citrusframework.org @@ -54,14 +53,19 @@ spec: description: Instance is the Schema for the yaks instance. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object diff --git a/helm/yaks/crds/crd-test.yaml b/helm/yaks/crds/crd-test.yaml index f96a1822..6c7d2915 100644 --- a/helm/yaks/crds/crd-test.yaml +++ b/helm/yaks/crds/crd-test.yaml @@ -20,8 +20,7 @@ metadata: labels: app: yaks annotations: - controller-gen.kubebuilder.io/version: v0.6.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: tests.yaks.citrusframework.org spec: group: yaks.citrusframework.org @@ -66,14 +65,19 @@ spec: description: Test is the Schema for the tests API. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -120,8 +124,10 @@ spec: verbose: type: boolean type: object - secret: - type: string + secrets: + items: + type: string + type: array selenium: description: SeleniumSpec --. properties: diff --git a/java/docs/configuration.adoc b/java/docs/configuration.adoc index c8d5969b..b2977bca 100644 --- a/java/docs/configuration.adoc +++ b/java/docs/configuration.adoc @@ -331,35 +331,37 @@ We can create a secret from that file and label it so that it will be picked up kubectl create secret generic my-secret --from-file=mysecret.properties ---- -Once the secret is created you can bind it to tests by their name. Given the test `my-test.feature` you can bind the secret to the test -by adding a label as follows: +Once the secret is created you can bind it to a test via labels on the secret. +Given the test named `my-test.feature` you can bind the secret to the test by adding a label as follows: +.Bind secret to a test via labels [source,shell script] ---- # Bind secret to the "my-test" test case kubectl label secret my-secret yaks.citrusframework.org/test=my-test ---- -For multiple secrets and variants of secrets on different environments (e.g. dev, test, staging) you can add a secret id and label that one -explicitly in addition to the test name. +When running a test the YAKS operator searches for all secrets labelled with the test name to automatically mount the secret to the test pod container. +All secret volumes get mounted to the test pod in `/etc/yaks/secrets` folder. +You can access this folder in the test in order to load the secrets and their content. -[source,shell script] ----- -# Bind secret to the named configuration "staging" of the "my-test" test case -kubectl label secret my-secret yaks.citrusframework.org/test=my-test yaks.citrusframework.org/test.configuration=staging ----- - -With that in place you just need to set the secret id in your `yaks-config.yaml` for that test. +Instead of using the label based binding you can also specify a list of secret names on the test runtime config. +Each secret gets mounted to the test pod container. +With that in place you just need to set the secret name in your `yaks-config.yaml` for that test. .yaks-config.yaml [source,yaml] ---- config: runtime: - secret: staging + secrets: + - my-secret ---- -You can now write a test and use the secret properties as normal test variables: +This assumes that there is a secret named `my-secret` available in the test namespace. +You can now write a test and load the content of the secret (e.g. files). +Also, property files in the secret get automatically loaded as test variables, +so you can reference the secret properties with the normal test variable syntax: .my-test.feature [source,gherkin] diff --git a/java/docs/steps-kamelet.adoc b/java/docs/steps-kamelet.adoc index eedaa57f..a648bb5b 100644 --- a/java/docs/steps-kamelet.adoc +++ b/java/docs/steps-kamelet.adoc @@ -10,16 +10,16 @@ YAKS provides steps to manage Kamelets. [[kamelet-api-version]] === API version -The default Kamelet API version used to create and manage resources is `v1alpha1`. You can overwrite this +The default Kamelet API version used to create and manage resources is `v1`. You can overwrite this version with a environment variable set on the YAKS configuration. .Overwrite Kamelet API version [source,bash] ---- -YAKS_KAMELET_API_VERSION=v1 +YAKS_KAMELET_API_VERSION=v1alpha1 ---- -This sets the Kamelet API version for all operations. +This sets the Kamelet API version for all operations to `v1alpha1`. [[kamelet-create]] === Create Kamelets diff --git a/java/pom.xml b/java/pom.xml index 77e6a6fd..fd9e4854 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -98,9 +98,10 @@ 3.25.3 4.2.1 2.25.53 + 2.3.3 4.2.1 2.12.0 - 7.16.1 + 7.18.0 3.0.21 2.17.1 4.13.2 @@ -454,6 +455,13 @@ test + + + org.apache.camel.k + camel-k-crds + ${camel.k.crds.version} + + com.fasterxml.jackson.core jackson-core diff --git a/java/runtime/yaks-runtime-core/src/main/java/org/citrusframework/yaks/config/YaksAutoConfiguration.java b/java/runtime/yaks-runtime-core/src/main/java/org/citrusframework/yaks/config/YaksAutoConfiguration.java index e24a9b8a..759aa4c5 100644 --- a/java/runtime/yaks-runtime-core/src/main/java/org/citrusframework/yaks/config/YaksAutoConfiguration.java +++ b/java/runtime/yaks-runtime-core/src/main/java/org/citrusframework/yaks/config/YaksAutoConfiguration.java @@ -22,6 +22,7 @@ import org.citrusframework.functions.DefaultFunctionLibrary; import org.citrusframework.functions.FunctionLibrary; +import org.citrusframework.util.FileUtils; import org.citrusframework.variable.GlobalVariables; import org.citrusframework.variable.GlobalVariablesPropertyLoader; import org.citrusframework.yaks.report.SystemOutTestReporter; @@ -43,16 +44,16 @@ public GlobalVariables globalVariables() { public GlobalVariablesPropertyLoader globalVariablesPropertyLoader() { GlobalVariablesPropertyLoader propertyLoader = new GlobalVariablesPropertyLoader(); - // Load mounted secrets as global variables + // Load mounted property files from secrets as global variables URL mountedSecrets = Thread.currentThread().getContextClassLoader().getResource("secrets"); if (mountedSecrets != null) { File secretsDir = new File(mountedSecrets.getPath()); if (secretsDir.exists() && secretsDir.isDirectory()) { File[] propertyFiles = secretsDir.listFiles(); if (propertyFiles != null) { - Stream.of(propertyFiles).forEach(file -> { - propertyLoader.getPropertyFiles().add("file:" + file.getPath()); - }); + Stream.of(propertyFiles) + .filter(file -> "properties".equals(FileUtils.getFileExtension(file.getName()))) + .forEach(file -> propertyLoader.getPropertyFiles().add("file:" + file.getPath())); } } } diff --git a/java/steps/pom.xml b/java/steps/pom.xml index 9acb5d12..41ca3dd6 100644 --- a/java/steps/pom.xml +++ b/java/steps/pom.xml @@ -21,6 +21,7 @@ org.citrusframework.yaks yaks-parent 0.20.0-SNAPSHOT + ../pom.xml 4.0.0 diff --git a/java/steps/yaks-camel-k/pom.xml b/java/steps/yaks-camel-k/pom.xml index 0312d871..7536a1ac 100644 --- a/java/steps/yaks-camel-k/pom.xml +++ b/java/steps/yaks-camel-k/pom.xml @@ -67,6 +67,11 @@ kubernetes-client + + org.apache.camel.k + camel-k-crds + + com.squareup.okhttp3 okhttp diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/CamelKSettings.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/CamelKSettings.java index 5d441d52..66177a1f 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/CamelKSettings.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/CamelKSettings.java @@ -60,6 +60,10 @@ public final class CamelKSettings { private static final String SUPPORT_VARIABLES_IN_SOURCES_ENV = CAMELK_ENV_PREFIX + "SUPPORT_VARIABLES_IN_SOURCES"; private static final String SUPPORT_VARIABLES_IN_SOURCES_DEFAULT = "true"; + private static final String STOP_ON_ERROR_STATUS_PROPERTY = CAMELK_PROPERTY_PREFIX + "stop.on.error.status"; + private static final String STOP_ON_ERROR_STATUS_ENV = CAMELK_ENV_PREFIX + "STOP_ON_ERROR_STATUS"; + private static final String STOP_ON_ERROR_STATUS_DEFAULT = "true"; + private static final String PRINT_POD_LOGS_PROPERTY = CAMELK_PROPERTY_PREFIX + "print.pod.logs"; private static final String PRINT_POD_LOGS_ENV = CAMELK_ENV_PREFIX + "PRINT_POD_LOGS"; private static final String PRINT_POD_LOGS_DEFAULT = String.valueOf(KubernetesSettings.isPrintPodLogs()); @@ -137,6 +141,16 @@ public static boolean isSupportVariablesInSources() { System.getenv(SUPPORT_VARIABLES_IN_SOURCES_ENV) != null ? System.getenv(SUPPORT_VARIABLES_IN_SOURCES_ENV) : SUPPORT_VARIABLES_IN_SOURCES_DEFAULT)); } + /** + * When set to true YAKS will stop the integration verification when integration is in error state. + * When verifying the integration status and pod logs the retry mechanism stops when integration status condition is in error state. + * @return + */ + public static boolean isStopOnErrorStatus() { + return Boolean.parseBoolean(System.getProperty(STOP_ON_ERROR_STATUS_PROPERTY, + System.getenv(STOP_ON_ERROR_STATUS_ENV) != null ? System.getenv(STOP_ON_ERROR_STATUS_ENV) : STOP_ON_ERROR_STATUS_DEFAULT)); + } + /** * When set to true test will print pod logs e.g. while waiting for a pod log message. * @return diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/CamelKSteps.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/CamelKSteps.java index afd231c9..cc8438ae 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/CamelKSteps.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/CamelKSteps.java @@ -35,7 +35,6 @@ import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.ActionTimeoutException; import org.citrusframework.exceptions.CitrusRuntimeException; -import org.citrusframework.spi.Resource; import org.citrusframework.util.FileUtils; import org.citrusframework.yaks.camelk.actions.integration.CreateIntegrationAction; import org.citrusframework.yaks.kubernetes.KubernetesSupport; @@ -67,8 +66,11 @@ public class CamelKSteps { private Map properties; private List buildPropertyFiles; private Map buildProperties; + private List envVarFiles; + private Map envVars; private boolean supportVariablesInSources = CamelKSettings.isSupportVariablesInSources(); + private boolean stopOnErrorStatus = CamelKSettings.isStopOnErrorStatus(); @Before public void before(Scenario scenario) { @@ -80,6 +82,8 @@ public void before(Scenario scenario) { properties = new LinkedHashMap<>(); buildPropertyFiles = new ArrayList<>(); buildProperties = new LinkedHashMap<>(); + envVarFiles = new ArrayList<>(); + envVars = new LinkedHashMap<>(); if (!context.getVariables().containsKey(VariableNames.OPERATOR_NAMESPACE.value())) { context.setVariable(VariableNames.OPERATOR_NAMESPACE.value(), CamelKSettings.getOperatorNamespace()); @@ -106,6 +110,16 @@ public void enableVariableSupport() { supportVariablesInSources = true; } + @Given("^Disable stop on error status$") + public void disableStopOnErrorStatus() { + stopOnErrorStatus = false; + } + + @Given("^Enable stop on error status$") + public void enableStopOnErrorStatus() { + stopOnErrorStatus = true; + } + @Given("^Camel K resource polling configuration$") public void configureResourcePolling(Map configuration) { maxAttempts = Integer.parseInt(configuration.getOrDefault("maxAttempts", maxAttempts).toString()); @@ -156,6 +170,22 @@ public void addBuildProperties(DataTable propertyTable) { buildProperties.putAll(propertyTable.asMap(String.class, String.class)); } + @Given("^Camel K integration environment variable file ([^\\s]+)$") + public void addEnVarFile(String filePath) { + envVarFiles.add(filePath); + } + + @Given("^Camel K integration environment variable ([^\\s]+)=\"([^\"]*)\"$") + @Given("^Camel K integration environment variable ([^\\s]+) (?:is|=) \"([^\"]*)\"$") + public void addEnVar(String name, String value) { + envVars.put(name, value); + } + + @Given("^Camel K integration environment variables$") + public void addEnvVars(DataTable propertyTable) { + envVars.putAll(propertyTable.asMap(String.class, String.class)); + } + @Given("^(?:create|new) Camel K integration ([a-z0-9][a-z0-9-\\.]+[a-z0-9])\\.([a-z0-9-]+) with configuration:?$") public void createIntegration(String name, String language, Map configuration) { if (configuration.get("source") == null) { @@ -192,6 +222,8 @@ public void createIntegration(String name, String language, String source) { .propertyFiles(propertyFiles) .buildProperties(buildProperties) .buildPropertyFiles(buildPropertyFiles) + .envVars(envVars) + .envVarFiles(envVarFiles) .supportVariables(supportVariablesInSources) .source(name + "." + language, source)); @@ -242,6 +274,7 @@ public void integrationShouldPrintMultiline(String name, String message) { .client(k8sClient) .verifyIntegration(name) .printLogs(CamelKSettings.isPrintPodLogs()) + .stopOnErrorStatus(stopOnErrorStatus) .maxAttempts(maxAttempts) .delayBetweenAttempts(delayBetweenAttempts) .waitForLogMessage(message)); @@ -260,6 +293,7 @@ public void integrationShouldNotPrintMultiline(String name, String message) { .client(k8sClient) .verifyIntegration(name) .printLogs(CamelKSettings.isPrintPodLogs()) + .stopOnErrorStatus(stopOnErrorStatus) .maxAttempts(maxAttempts) .delayBetweenAttempts(delayBetweenAttempts) .waitForLogMessage(message))); @@ -274,6 +308,8 @@ private void createIntegration(String name, String language, String source, Map< .buildProperties(configuration.getOrDefault("build-properties", "").trim()) .buildProperties(buildProperties) .buildPropertyFiles(buildPropertyFiles) + .envVars(envVars) + .envVarFiles(envVarFiles) .properties(configuration.getOrDefault("properties", "").trim()) .properties(properties) .propertyFiles(propertyFiles) @@ -283,12 +319,7 @@ private void createIntegration(String name, String language, String source, Map< String openApiSpec = configuration.getOrDefault("openapi", ""); if (!openApiSpec.isEmpty()) { - try { - Resource file = ResourceUtils.resolve(openApiSpec, context); - create.openApi(FileUtils.getFileName(file.getLocation()), FileUtils.readToString(file)); - } catch (IOException e) { - throw new CitrusRuntimeException(String.format("Failed to read openapi spec form file path %s", openApiSpec)); - } + create.openApi(openApiSpec); } runner.run(create); diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/KameletBindingSteps.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/KameletBindingSteps.java new file mode 100644 index 00000000..a3b465de --- /dev/null +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/KameletBindingSteps.java @@ -0,0 +1,233 @@ +/* + * Copyright the original author or authors. + * + * Licensed 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 org.citrusframework.yaks.camelk; + +import java.util.HashMap; +import java.util.Map; + +import io.cucumber.java.Before; +import io.cucumber.java.Scenario; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.fabric8.kubernetes.client.KubernetesClient; +import org.apache.camel.v1alpha1.KameletBindingBuilder; +import org.apache.camel.v1alpha1.kameletbindingspec.SinkBuilder; +import org.apache.camel.v1alpha1.kameletbindingspec.SourceBuilder; +import org.apache.camel.v1alpha1.kameletbindingspec.source.Ref; +import org.apache.camel.v1alpha1.kameletbindingspec.source.RefBuilder; +import org.citrusframework.Citrus; +import org.citrusframework.TestCaseRunner; +import org.citrusframework.annotations.CitrusFramework; +import org.citrusframework.annotations.CitrusResource; +import org.citrusframework.context.TestContext; +import org.citrusframework.spi.Resource; +import org.citrusframework.yaks.kafka.KafkaSettings; +import org.citrusframework.yaks.knative.KnativeSettings; +import org.citrusframework.yaks.kubernetes.KubernetesSupport; +import org.citrusframework.yaks.util.ResourceUtils; + +import static org.citrusframework.container.FinallySequence.Builder.doFinally; +import static org.citrusframework.yaks.camelk.actions.CamelKActionBuilder.camelk; + +public class KameletBindingSteps { + + @CitrusResource + private TestCaseRunner runner; + + @CitrusFramework + private Citrus citrus; + + @CitrusResource + private TestContext context; + + private KubernetesClient k8sClient; + + // Binding endpoints + private SourceBuilder source; + private SinkBuilder sink; + + private Map sourceProperties; + private Map sinkProperties; + + @Before + public void before(Scenario scenario) { + if (k8sClient == null) { + k8sClient = KubernetesSupport.getKubernetesClient(citrus); + } + + initializeKameletBindingBuilder(); + } + + @Given("^KameletBinding source properties$") + public void setKameletBindingSourceProperties(Map properties) { + this.sourceProperties.putAll(properties); + } + + @Given("^KameletBinding sink properties$") + public void setKameletBindingSinkProperties(Map properties) { + this.sinkProperties.putAll(properties); + } + + @Given("^KameletBinding event source Kamelet ([a-z0-9-]+)$") + public void setKameletEventSource(String kameletName) { + Ref kameletRef = new RefBuilder() + .withName(kameletName) + .withApiVersion(CamelKSupport.CAMELK_CRD_GROUP + "/" + getKameletApiVersion()) + .withKind("Kamelet") + .withNamespace(getNamespace()) + .build(); + source = new SourceBuilder().withRef(kameletRef); + } + + @Given("^KameletBinding event sink uri ([^\\s]+)$") + public void setEventSinkUri(String uri) { + sink = new SinkBuilder().withUri(uri); + } + + @Given("^KameletBinding event sink Kafka topic ([^\\s]+)$") + public void setEventSinkKafkaTopic(String topic) { + org.apache.camel.v1alpha1.kameletbindingspec.sink.Ref sinkRef = + new org.apache.camel.v1alpha1.kameletbindingspec.sink.RefBuilder() + .withName(topic) + .withApiVersion("kafka.strimzi.io/" + KafkaSettings.getApiVersion()) + .withKind("KafkaTopic") + .withNamespace(KafkaSettings.getNamespace()) + .build(); + sink = new SinkBuilder().withRef(sinkRef); + } + + @Given("^KameletBinding event sink Knative channel ([^\\s]+)$") + public void setEventSinkKnativeChannel(String channel) { + setEventSinkKnativeChannel(channel, "InMemoryChannel"); + } + + @Given("^KameletBinding event sink Knative channel ([^\\s]+) of kind ([^\\s]+)$") + public void setEventSinkKnativeChannel(String channel, String channelKind) { + org.apache.camel.v1alpha1.kameletbindingspec.sink.Ref sinkRef = + new org.apache.camel.v1alpha1.kameletbindingspec.sink.RefBuilder() + .withName(channel) + .withApiVersion("messaging.knative.dev/" + KnativeSettings.getApiVersion()) + .withKind(channelKind) + .withNamespace(KnativeSettings.getNamespace()) + .build(); + sink = new SinkBuilder().withRef(sinkRef); + } + + @Given("^KameletBinding event sink Knative broker ([^\\s]+)$") + public void setEventSinkKnativeBroker(String broker) { + org.apache.camel.v1alpha1.kameletbindingspec.sink.Ref sinkRef = + new org.apache.camel.v1alpha1.kameletbindingspec.sink.RefBuilder() + .withName(broker) + .withApiVersion("eventing.knative.dev/" + KnativeSettings.getApiVersion()) + .withKind("Broker") + .withNamespace(KnativeSettings.getNamespace()) + .build(); + sink = new SinkBuilder().withRef(sinkRef); + } + + @Given("^load KameletBinding ([a-z0-9-]+).yaml$") + public void loadKameletBindingFromFile(String fileName) { + Resource resource = ResourceUtils.resolve(fileName + ".yaml", context); + runner.run(camelk() + .client(k8sClient) + .createKameletBinding(fileName) + .resource(resource)); + + if (isAutoRemoveResources()) { + runner.then(doFinally() + .actions(camelk().client(k8sClient) + .deleteKameletBinding(fileName))); + } + } + + @Given("^(?:create|new) KameletBinding ([a-z0-9-]+)$") + public void createNewKameletBinding(String name) { + KameletBindingBuilder builder = new KameletBindingBuilder(); + + builder.withNewMetadata() + .withName(name) + .endMetadata(); + + source.editOrNewProperties().addToAdditionalProperties(sourceProperties); + sink.editOrNewProperties().addToAdditionalProperties(sinkProperties); + + builder.withNewSpec() + .withSource(source.build()) + .withSink(sink.build()) + .endSpec(); + + runner.run(camelk() + .client(k8sClient) + .createKameletBinding(name) + .fromBuilder(builder)); + + initializeKameletBindingBuilder(); + + if (isAutoRemoveResources()) { + runner.then(doFinally() + .actions(camelk().client(k8sClient) + .deleteKameletBinding(name))); + } + } + + @Given("^delete KameletBinding ([a-z0-9-]+)$") + public void deleteKameletBinding(String name) { + runner.run(camelk() + .client(k8sClient) + .deleteKameletBinding(name)); + } + + @Given("^KameletBinding ([a-z0-9-]+) is available$") + @Then("^KameletBinding ([a-z0-9-]+) should be available$") + public void bindingShouldBeAvailable(String name) { + runner.run(camelk() + .client(k8sClient) + .verifyKameletBinding(name) + .isAvailable()); + } + + private void initializeKameletBindingBuilder() { + source = null; + sink = null; + sourceProperties = new HashMap<>(); + sinkProperties = new HashMap<>(); + } + + private String getKameletApiVersion() { + if (context.getVariables().containsKey(VariableNames.KAMELET_API_VERSION.value())) { + return context.getVariable(VariableNames.KAMELET_API_VERSION.value()); + } + + return KameletSettings.getKameletApiVersion(); + } + + private String getNamespace() { + if (context.getVariables().containsKey(VariableNames.KAMELET_NAMESPACE.value())) { + return context.getVariable(VariableNames.KAMELET_NAMESPACE.value()); + } + + return KameletSettings.getNamespace(); + } + + private boolean isAutoRemoveResources() { + if (context.getVariables().containsKey(VariableNames.AUTO_REMOVE_RESOURCES.value())) { + return context.getVariable(VariableNames.AUTO_REMOVE_RESOURCES.value(), Boolean.class); + } + + return CamelKSettings.isAutoRemoveResources(); + } +} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/KameletSteps.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/KameletSteps.java index 1e5ebc75..2883c901 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/KameletSteps.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/KameletSteps.java @@ -23,7 +23,16 @@ import io.cucumber.java.Scenario; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; +import io.fabric8.kubernetes.api.model.AnyTypeBuilder; import io.fabric8.kubernetes.client.KubernetesClient; +import org.apache.camel.v1.KameletBuilder; +import org.apache.camel.v1.KameletSpecBuilder; +import org.apache.camel.v1.kameletspec.DataTypes; +import org.apache.camel.v1.kameletspec.DefinitionBuilder; +import org.apache.camel.v1.kameletspec.SourcesBuilder; +import org.apache.camel.v1.kameletspec.datatypes.TypesBuilder; +import org.apache.camel.v1.kameletspec.definition.Properties; +import org.apache.camel.v1.kameletspec.definition.PropertiesBuilder; import org.citrusframework.Citrus; import org.citrusframework.TestCaseRunner; import org.citrusframework.annotations.CitrusFramework; @@ -31,12 +40,6 @@ import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.CitrusRuntimeException; import org.citrusframework.spi.Resource; -import org.citrusframework.yaks.camelk.model.Kamelet; -import org.citrusframework.yaks.camelk.model.KameletSpec; -import org.citrusframework.yaks.camelk.model.Pipe; -import org.citrusframework.yaks.camelk.model.PipeSpec; -import org.citrusframework.yaks.kafka.KafkaSettings; -import org.citrusframework.yaks.knative.KnativeSettings; import org.citrusframework.yaks.kubernetes.KubernetesSupport; import org.citrusframework.yaks.util.ResourceUtils; import org.springframework.util.StringUtils; @@ -61,15 +64,11 @@ public class KameletSteps { private String kameletApiVersion = KameletSettings.getKameletApiVersion(); // Kamelet builder - private Kamelet.Builder kamelet; - private KameletSpec.Definition definition; - - // Pipe endpoints - private PipeSpec.Endpoint source; - private PipeSpec.Endpoint sink; - - private Map sourceProperties; - private Map sinkProperties; + private KameletBuilder kamelet; + private KameletSpecBuilder kameletSpecBuilder; + private Map dataTypes; + private DefinitionBuilder definition; + private String kameletTemplate; private String namespace = KameletSettings.getNamespace(); @@ -83,17 +82,22 @@ public void before(Scenario scenario) { } initializeKameletBuilder(); - initializePipeBuilder(); } @Given("^Disable auto removal of Kamelet resources$") public void disableAutoRemove() { autoRemoveResources = false; + + // update the test variable + runner.run(createVariable(VariableNames.AUTO_REMOVE_RESOURCES.value(), "false")); } @Given("^Enable auto removal of Kamelet resources$") public void enableAutoRemove() { autoRemoveResources = true; + + // update the test variable + runner.run(createVariable(VariableNames.AUTO_REMOVE_RESOURCES.value(), "true")); } @Given("^Disable variable support in Kamelet sources$") @@ -124,27 +128,39 @@ public void setNamespace(String namespace) { @Given("^Kamelet dataType (in|out|error)(?:=| is )\"(.+)\"$") public void addType(String slot, String format) { + DataTypes dt; + if (dataTypes.containsKey(slot)) { + dt = dataTypes.get(slot); + } else { + dt = new DataTypes(); + dataTypes.put(slot, dt); + } + + if (dt.getTypes() == null) { + dt.setTypes(new HashMap<>()); + } + if (format.contains(":")) { String[] schemeAndFormat = format.split(":"); - kamelet.addDataType(slot, schemeAndFormat[0], schemeAndFormat[1]); + dt.getTypes().put(schemeAndFormat[1], new TypesBuilder().withScheme(schemeAndFormat[0]).withFormat(schemeAndFormat[1]).build()); } else { - kamelet.addDataType(slot, "camel", format); + dt.getTypes().put(format, new TypesBuilder().withScheme("camel").withFormat(format).build()); } } @Given("^Kamelet title \"(.+)\"$") public void setTitle(String title) { - definition.setTitle(title); + definition.withTitle(title); } @Given("^Kamelet source ([a-z0-9-]+).([a-z0-9-]+)$") public void setSource(String name, String language, String content) { - kamelet.source(name, language, content); + kameletSpecBuilder.withSources(new SourcesBuilder().withName(name).withLanguage(language).withContent(content).build()); } @Given("^Kamelet template") public void setFlow(String template) { - kamelet.template(template); + kameletTemplate = template; } @Given("^Kamelet property definition$") @@ -165,58 +181,19 @@ public void addPropertyDefinition(String propertyName, Map prope String required = propertyConfiguration.getOrDefault("required", Boolean.FALSE).toString(); if (Boolean.parseBoolean(required)) { - definition.getRequired().add(propertyName); + definition.addToRequired(propertyName); } - definition.getProperties().put(propertyName, - new KameletSpec.Definition.PropertyConfig(title, type, defaultValue, example)); - } - - @Given("^(?:Pipe|KameletBinding) source properties$") - public void setPipeSourceProperties(Map properties) { - this.sourceProperties.putAll(properties); - } - - @Given("^(?:Pipe|KameletBinding) sink properties$") - public void setPipeSinkProperties(Map properties) { - this.sinkProperties.putAll(properties); - } - - @Given("^bind Kamelet ([a-z0-9-]+) to uri ([^\\s]+)$") - public void bindKameletToUri(String kameletName, String uri) { - PipeSpec.Endpoint.ObjectReference sourceRef = - new PipeSpec.Endpoint.ObjectReference(CamelKSupport.CAMELK_CRD_GROUP + "/" + kameletApiVersion, "Kamelet", namespace, kameletName); - source = new PipeSpec.Endpoint(sourceRef); - - sink = new PipeSpec.Endpoint(uri); - } - - @Given("^bind Kamelet ([a-z0-9-]+) to Kafka topic ([^\\s]+)$") - public void bindKameletToKafka(String kameletName, String topic) { - PipeSpec.Endpoint.ObjectReference sourceRef = - new PipeSpec.Endpoint.ObjectReference(CamelKSupport.CAMELK_CRD_GROUP + "/" + kameletApiVersion, "Kamelet", namespace, kameletName); - source = new PipeSpec.Endpoint(sourceRef); - - PipeSpec.Endpoint.ObjectReference sinkRef = - new PipeSpec.Endpoint.ObjectReference("KafkaTopic", KafkaSettings.getNamespace(), topic); - sink = new PipeSpec.Endpoint(sinkRef); - } - - @Given("^bind Kamelet ([a-z0-9-]+) to Knative channel ([^\\s]+)$") - public void bindKameletToKnativeChannel(String kameletName, String channel) { - bindKameletToKnativeChannel(kameletName, channel, "InMemoryChannel"); - } - - @Given("^bind Kamelet ([a-z0-9-]+) to Knative channel ([^\\s]+) of kind ([^\\s]+)$") - public void bindKameletToKnativeChannel(String kameletName, String channel, String channelKind) { - PipeSpec.Endpoint.ObjectReference sourceRef = - new PipeSpec.Endpoint.ObjectReference(CamelKSupport.CAMELK_CRD_GROUP + "/" + kameletApiVersion, "Kamelet", namespace, kameletName); - source = new PipeSpec.Endpoint(sourceRef); + Properties property = new PropertiesBuilder().withTitle(title).withType(type).build(); + if (example != null) { + property.setExample(new AnyTypeBuilder().withValue(example).build()); + } - PipeSpec.Endpoint.ObjectReference sinkRef = - new PipeSpec.Endpoint.ObjectReference(channelKind, KnativeSettings.getNamespace(), channel); - sink = new PipeSpec.Endpoint(sinkRef); - } + if (defaultValue != null) { + property.set_default(new AnyTypeBuilder().withValue(defaultValue).build()); + } + definition.addToProperties(propertyName, property); + } @Given("^load Kamelet ([a-z0-9-]+).kamelet.yaml$") public void loadKameletFromFile(String fileName) { @@ -224,6 +201,7 @@ public void loadKameletFromFile(String fileName) { runner.run(camelk() .client(k8sClient) .createKamelet(fileName) + .namespace(namespace) .apiVersion(kameletApiVersion) .supportVariables(supportVariablesInSources) .resource(resource)); @@ -236,36 +214,26 @@ public void loadKameletFromFile(String fileName) { } } - @Given("^load (?:Pipe|KameletBinding) ([a-z0-9-]+).yaml$") - public void loadPipeFromFile(String fileName) { - Resource resource = ResourceUtils.resolve(fileName + ".yaml", context); - runner.run(camelk() - .client(k8sClient) - .createPipe(fileName) - .resource(resource)); - - if (autoRemoveResources) { - runner.then(doFinally() - .actions(camelk().client(k8sClient) - .deletePipe(fileName) - .apiVersion(kameletApiVersion))); - } - } - @Given("^(?:create|new) Kamelet ([a-z0-9-]+)$") public void createNewKamelet(String name) { - kamelet.name(name); + kamelet.withNewMetadata() + .withName(name) + .endMetadata(); if (definition.getTitle() == null || definition.getTitle().isEmpty()) { - definition.setTitle(StringUtils.capitalize(name)); + definition.withTitle(StringUtils.capitalize(name)); } - kamelet.definition(definition); + kameletSpecBuilder.withDefinition(definition.build()); + kameletSpecBuilder.withDataTypes(dataTypes); + + kamelet.withSpec(kameletSpecBuilder.build()); runner.run(camelk() .client(k8sClient) .createKamelet(name) .supportVariables(supportVariablesInSources) + .template(kameletTemplate) .fromBuilder(kamelet)); initializeKameletBuilder(); @@ -286,37 +254,10 @@ public void createNewKameletWithFlow(String name, String flow) { @Given("^(?:create|new) Kamelet ([a-z0-9-]+) with template") public void createNewKameletWithTemplate(String name, String template) { - kamelet.template(template); + kameletTemplate = template; createNewKamelet(name); } - @Given("^(?:create|new) (?:Pipe|KameletBinding) ([a-z0-9-]+)$") - public void createNewPipe(String name) { - Pipe.Builder pipe = new Pipe.Builder(); - pipe.name(name); - - source.getProperties().putAll(sourceProperties); - sink.getProperties().putAll(sinkProperties); - - pipe.source(source); - pipe.sink(sink); - - runner.run(camelk() - .client(k8sClient) - .createPipe(name) - .apiVersion(kameletApiVersion) - .fromBuilder(pipe)); - - initializePipeBuilder(); - - if (autoRemoveResources) { - runner.then(doFinally() - .actions(camelk().client(k8sClient) - .deletePipe(name) - .apiVersion(kameletApiVersion))); - } - } - @Given("^delete Kamelet ([a-z0-9-]+)$") public void deleteKamelet(String name) { runner.run(camelk() @@ -325,14 +266,6 @@ public void deleteKamelet(String name) { .apiVersion(kameletApiVersion)); } - @Given("^delete (?:Pipe|KameletBinding) ([a-z0-9-]+)$") - public void deletePipe(String name) { - runner.run(camelk() - .client(k8sClient) - .deletePipe(name) - .apiVersion(kameletApiVersion)); - } - @Given("^Kamelet ([a-z0-9-]+) is available$") @Then("^Kamelet ([a-z0-9-]+) should be available$") public void kameletShouldBeAvailable(String name) { @@ -354,25 +287,11 @@ public void kameletShouldBeAvailable(String name, String namespace) { .isAvailable()); } - @Given("^(?:Pipe|KameletBinding) ([a-z0-9-]+) is available$") - @Then("^(?:Pipe|KameletBinding) ([a-z0-9-]+) should be available$") - public void pipeShouldBeAvailable(String name) { - runner.run(camelk() - .client(k8sClient) - .verifyPipe(name) - .apiVersion(kameletApiVersion) - .isAvailable()); - } - private void initializeKameletBuilder() { - kamelet = new Kamelet.Builder(); - definition = new KameletSpec.Definition(); - } - - private void initializePipeBuilder() { - source = null; - sink = null; - sourceProperties = new HashMap<>(); - sinkProperties = new HashMap<>(); + kamelet = new KameletBuilder(); + definition = new DefinitionBuilder(); + kameletSpecBuilder = new KameletSpecBuilder(); + dataTypes = new HashMap<>(); + kameletTemplate = null; } } diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/PipeSteps.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/PipeSteps.java new file mode 100644 index 00000000..c98a4c07 --- /dev/null +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/PipeSteps.java @@ -0,0 +1,262 @@ +/* + * Copyright the original author or authors. + * + * Licensed 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 org.citrusframework.yaks.camelk; + +import java.util.HashMap; +import java.util.Map; + +import io.cucumber.java.Before; +import io.cucumber.java.Scenario; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.fabric8.kubernetes.client.KubernetesClient; +import org.apache.camel.v1.PipeBuilder; +import org.apache.camel.v1.pipespec.SinkBuilder; +import org.apache.camel.v1.pipespec.SourceBuilder; +import org.apache.camel.v1.pipespec.source.Ref; +import org.apache.camel.v1.pipespec.source.RefBuilder; +import org.citrusframework.Citrus; +import org.citrusframework.TestCaseRunner; +import org.citrusframework.annotations.CitrusFramework; +import org.citrusframework.annotations.CitrusResource; +import org.citrusframework.context.TestContext; +import org.citrusframework.spi.Resource; +import org.citrusframework.yaks.kafka.KafkaSettings; +import org.citrusframework.yaks.knative.KnativeSettings; +import org.citrusframework.yaks.kubernetes.KubernetesSupport; +import org.citrusframework.yaks.util.ResourceUtils; + +import static org.citrusframework.container.FinallySequence.Builder.doFinally; +import static org.citrusframework.yaks.camelk.actions.CamelKActionBuilder.camelk; + +public class PipeSteps { + + @CitrusResource + private TestCaseRunner runner; + + @CitrusFramework + private Citrus citrus; + + @CitrusResource + private TestContext context; + + private KubernetesClient k8sClient; + + // Pipe endpoints + private SourceBuilder source; + private SinkBuilder sink; + + private Map sourceProperties; + private Map sinkProperties; + + @Before + public void before(Scenario scenario) { + if (k8sClient == null) { + k8sClient = KubernetesSupport.getKubernetesClient(citrus); + } + + initializePipeBuilder(); + } + + @Given("^Pipe source properties$") + public void setPipeSourceProperties(Map properties) { + this.sourceProperties.putAll(properties); + } + + @Given("^Pipe sink properties$") + public void setPipeSinkProperties(Map properties) { + this.sinkProperties.putAll(properties); + } + + @Given("^Pipe event source Kamelet ([a-z0-9-]+)$") + public void setKameletEventSource(String kameletName) { + Ref kameletRef = new RefBuilder() + .withName(kameletName) + .withApiVersion(CamelKSupport.CAMELK_CRD_GROUP + "/" + getKameletApiVersion()) + .withKind("Kamelet") + .withNamespace(getNamespace()) + .build(); + source = new SourceBuilder().withRef(kameletRef); + } + + @Given("^Pipe event sink uri ([^\\s]+)$") + public void setEventSinkUri(String uri) { + sink = new SinkBuilder().withUri(uri); + } + + @Given("^Pipe event sink Kafka topic ([^\\s]+)$") + public void setEventSinkKafkaTopic(String topic) { + org.apache.camel.v1.pipespec.sink.Ref sinkRef = + new org.apache.camel.v1.pipespec.sink.RefBuilder() + .withName(topic) + .withApiVersion("kafka.strimzi.io/" + KafkaSettings.getApiVersion()) + .withKind("KafkaTopic") + .withNamespace(KafkaSettings.getNamespace()) + .build(); + sink = new SinkBuilder().withRef(sinkRef); + } + + @Given("^Pipe event sink Knative channel ([^\\s]+)$") + public void setEventSinkKnativeChannel(String channel) { + setEventSinkKnativeChannel(channel, "InMemoryChannel"); + } + + @Given("^Pipe event sink Knative channel ([^\\s]+) of kind ([^\\s]+)$") + public void setEventSinkKnativeChannel(String channel, String channelKind) { + org.apache.camel.v1.pipespec.sink.Ref sinkRef = + new org.apache.camel.v1.pipespec.sink.RefBuilder() + .withName(channel) + .withApiVersion("messaging.knative.dev/" + KnativeSettings.getApiVersion()) + .withKind(channelKind) + .withNamespace(KnativeSettings.getNamespace()) + .build(); + sink = new SinkBuilder().withRef(sinkRef); + } + + @Given("^Pipe event sink Knative broker ([^\\s]+)$") + public void setEventSinkKnativeBroker(String broker) { + org.apache.camel.v1.pipespec.sink.Ref sinkRef = + new org.apache.camel.v1.pipespec.sink.RefBuilder() + .withName(broker) + .withApiVersion("eventing.knative.dev/" + KnativeSettings.getApiVersion()) + .withKind("Broker") + .withNamespace(KnativeSettings.getNamespace()) + .build(); + sink = new SinkBuilder().withRef(sinkRef); + } + + @Given("^bind Kamelet ([a-z0-9-]+) to uri ([^\\s]+)$") + public void bindKameletToUri(String kameletName, String uri) { + setKameletEventSource(kameletName); + setEventSinkUri(uri); + } + + @Given("^bind Kamelet ([a-z0-9-]+) to Kafka topic ([^\\s]+)$") + public void bindKameletToKafka(String kameletName, String topic) { + setKameletEventSource(kameletName); + setEventSinkKafkaTopic(topic); + } + + @Given("^bind Kamelet ([a-z0-9-]+) to Knative channel ([^\\s]+)$") + public void bindKameletToKnativeChannel(String kameletName, String channel) { + bindKameletToKnativeChannel(kameletName, channel, "InMemoryChannel"); + } + + @Given("^bind Kamelet ([a-z0-9-]+) to Knative channel ([^\\s]+) of kind ([^\\s]+)$") + public void bindKameletToKnativeChannel(String kameletName, String channel, String channelKind) { + setKameletEventSource(kameletName); + setEventSinkKnativeChannel(channel, channelKind); + } + + @Given("^bind Kamelet ([a-z0-9-]+) to Knative broker ([^\\s]+)$") + public void bindKameletToKnativeBroker(String kameletName, String broker) { + setKameletEventSource(kameletName); + setEventSinkKnativeBroker(broker); + } + + @Given("^load Pipe ([a-z0-9-]+).yaml$") + public void loadPipeFromFile(String fileName) { + Resource resource = ResourceUtils.resolve(fileName + ".yaml", context); + runner.run(camelk() + .client(k8sClient) + .createPipe(fileName) + .resource(resource)); + + if (isAutoRemoveResources()) { + runner.then(doFinally() + .actions(camelk().client(k8sClient) + .deletePipe(fileName))); + } + } + + @Given("^(?:create|new) Pipe ([a-z0-9-]+)$") + public void createNewPipe(String name) { + PipeBuilder pipe = new PipeBuilder(); + + pipe.withNewMetadata() + .withName(name) + .endMetadata(); + + source.editOrNewProperties().addToAdditionalProperties(sourceProperties); + sink.editOrNewProperties().addToAdditionalProperties(sinkProperties); + + pipe.withNewSpec() + .withSource(source.build()) + .withSink(sink.build()) + .endSpec(); + + runner.run(camelk() + .client(k8sClient) + .createPipe(name) + .fromBuilder(pipe)); + + initializePipeBuilder(); + + if (isAutoRemoveResources()) { + runner.then(doFinally() + .actions(camelk().client(k8sClient) + .deletePipe(name))); + } + } + + @Given("^delete Pipe ([a-z0-9-]+)$") + public void deletePipe(String name) { + runner.run(camelk() + .client(k8sClient) + .deletePipe(name)); + } + + @Given("^Pipe ([a-z0-9-]+) is available$") + @Then("^Pipe ([a-z0-9-]+) should be available$") + public void pipeShouldBeAvailable(String name) { + runner.run(camelk() + .client(k8sClient) + .verifyPipe(name) + .isAvailable()); + } + + private void initializePipeBuilder() { + source = null; + sink = null; + sourceProperties = new HashMap<>(); + sinkProperties = new HashMap<>(); + } + + private String getKameletApiVersion() { + if (context.getVariables().containsKey(VariableNames.KAMELET_API_VERSION.value())) { + return context.getVariable(VariableNames.KAMELET_API_VERSION.value()); + } + + return KameletSettings.getKameletApiVersion(); + } + + private String getNamespace() { + if (context.getVariables().containsKey(VariableNames.KAMELET_NAMESPACE.value())) { + return context.getVariable(VariableNames.KAMELET_NAMESPACE.value()); + } + + return KameletSettings.getNamespace(); + } + + private boolean isAutoRemoveResources() { + if (context.getVariables().containsKey(VariableNames.AUTO_REMOVE_RESOURCES.value())) { + return context.getVariable(VariableNames.AUTO_REMOVE_RESOURCES.value(), Boolean.class); + } + + return CamelKSettings.isAutoRemoveResources(); + } +} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/VariableNames.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/VariableNames.java index ae07df55..6f465f29 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/VariableNames.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/VariableNames.java @@ -26,7 +26,8 @@ public enum VariableNames { KAMELET_API_VERSION("KAMELET_API_VERSION"), KAMELET_NAMESPACE("KAMELET_NAMESPACE"), - OPERATOR_NAMESPACE("CAMELK_OPERATOR_NAMESPACE"); + OPERATOR_NAMESPACE("CAMELK_OPERATOR_NAMESPACE"), + AUTO_REMOVE_RESOURCES("CAMELK_AUTO_REMOVE_RESOURCES"); private final String variableName; diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/CamelKActionBuilder.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/CamelKActionBuilder.java index 1dfd3e14..75beb9b3 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/CamelKActionBuilder.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/CamelKActionBuilder.java @@ -16,16 +16,19 @@ package org.citrusframework.yaks.camelk.actions; -import org.citrusframework.TestActionBuilder; import io.fabric8.kubernetes.client.KubernetesClient; +import org.citrusframework.TestActionBuilder; import org.citrusframework.yaks.camelk.actions.integration.CreateIntegrationAction; import org.citrusframework.yaks.camelk.actions.integration.DeleteIntegrationAction; import org.citrusframework.yaks.camelk.actions.integration.VerifyIntegrationAction; import org.citrusframework.yaks.camelk.actions.kamelet.CreateKameletAction; +import org.citrusframework.yaks.camelk.actions.kamelet.CreateKameletBindingAction; import org.citrusframework.yaks.camelk.actions.kamelet.CreatePipeAction; import org.citrusframework.yaks.camelk.actions.kamelet.DeleteKameletAction; +import org.citrusframework.yaks.camelk.actions.kamelet.DeleteKameletBindingAction; import org.citrusframework.yaks.camelk.actions.kamelet.DeletePipeAction; import org.citrusframework.yaks.camelk.actions.kamelet.VerifyKameletAction; +import org.citrusframework.yaks.camelk.actions.kamelet.VerifyKameletBindingAction; import org.citrusframework.yaks.camelk.actions.kamelet.VerifyPipeAction; import org.springframework.util.Assert; @@ -127,6 +130,30 @@ public DeletePipeAction.Builder deletePipe(String pipeName) { return builder; } + /** + * Create binding CRD in current namespace. + * @param bindingName the name of the binding. + */ + public CreateKameletBindingAction.Builder createKameletBinding(String bindingName) { + CreateKameletBindingAction.Builder builder = new CreateKameletBindingAction.Builder() + .client(kubernetesClient) + .binding(bindingName); + this.delegate = builder; + return builder; + } + + /** + * Delete binding CRD from current namespace. + * @param bindingName the name of the binding. + */ + public DeleteKameletBindingAction.Builder deleteKameletBinding(String bindingName) { + DeleteKameletBindingAction.Builder builder = new DeleteKameletBindingAction.Builder() + .client(kubernetesClient) + .binding(bindingName); + this.delegate = builder; + return builder; + } + /** * Verify that given integration is running. * @param integrationName the name of the Camel K integration. @@ -163,6 +190,18 @@ public VerifyPipeAction.Builder verifyPipe(String pipeName) { return builder; } + /** + * Verify that given binding CRD is available in current namespace. + * @param bindingName the name of the binding. + */ + public VerifyKameletBindingAction.Builder verifyKameletBinding(String bindingName) { + VerifyKameletBindingAction.Builder builder = new VerifyKameletBindingAction.Builder() + .client(kubernetesClient) + .isAvailable(bindingName); + this.delegate = builder; + return builder; + } + @Override public CamelKAction build() { Assert.notNull(delegate, "Missing delegate action to build"); diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/CreateIntegrationAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/CreateIntegrationAction.java index 7eec264b..16cb9719 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/CreateIntegrationAction.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/CreateIntegrationAction.java @@ -17,34 +17,34 @@ package org.citrusframework.yaks.camelk.actions.integration; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Collectors; +import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.Updatable; +import org.apache.camel.v1.Integration; +import org.apache.camel.v1.IntegrationBuilder; +import org.apache.camel.v1.IntegrationSpecBuilder; +import org.apache.camel.v1.integrationspec.ConfigurationBuilder; +import org.apache.camel.v1.integrationspec.SourcesBuilder; +import org.apache.camel.v1.integrationspec.Traits; import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.CitrusRuntimeException; -import org.citrusframework.util.FileUtils; import org.citrusframework.variable.VariableUtils; -import io.fabric8.kubernetes.client.KubernetesClient; import org.citrusframework.yaks.YaksSettings; import org.citrusframework.yaks.camelk.actions.AbstractCamelKAction; import org.citrusframework.yaks.camelk.jbang.CamelJBangSettings; import org.citrusframework.yaks.camelk.jbang.ProcessAndOutput; -import org.citrusframework.yaks.camelk.model.Integration; import org.citrusframework.yaks.camelk.model.IntegrationList; -import org.citrusframework.yaks.camelk.model.IntegrationSpec; import org.citrusframework.yaks.kubernetes.KubernetesSupport; import org.citrusframework.yaks.util.ResourceUtils; import org.slf4j.Logger; @@ -69,10 +69,12 @@ public class CreateIntegrationAction extends AbstractCamelKAction { private final List dependencies; private final List buildProperties; private final List buildPropertyFiles; + private final List envVars; + private final List envVarFiles; private final List properties; private final List propertyFiles; private final List traits; - private final Map openApis; + private final List openApis; private final boolean supportVariables; /** @@ -87,6 +89,8 @@ public CreateIntegrationAction(Builder builder) { this.dependencies = builder.dependencies; this.buildProperties = builder.buildProperties; this.buildPropertyFiles = builder.buildPropertyFiles; + this.envVars = builder.envVars; + this.envVarFiles = builder.envVarFiles; this.properties = builder.properties; this.propertyFiles = builder.propertyFiles; this.traits = builder.traits; @@ -107,21 +111,31 @@ public void doExecute(TestContext context) { resolvedSource = source; } - final Integration.Builder integrationBuilder = new Integration.Builder() - .name(name) - .source(context.replaceDynamicContentInString(fileName), resolvedSource); + final IntegrationBuilder integrationBuilder = new IntegrationBuilder() + .withNewMetadata() + .withName(name) + .endMetadata(); + + IntegrationSpecBuilder specBuilder = new IntegrationSpecBuilder(); + specBuilder.addToSources(new SourcesBuilder().withName(context.replaceDynamicContentInString(fileName)).withContent(resolvedSource).build()); List resolvedDependencies = resolveDependencies(resolvedSource, context.resolveDynamicValuesInList(dependencies)); if (!resolvedDependencies.isEmpty()) { - integrationBuilder.dependencies(resolvedDependencies); + specBuilder.addAllToDependencies(resolvedDependencies); } - addPropertyConfigurationSpec(integrationBuilder, context); - addBuildPropertyConfigurationSpec(integrationBuilder, resolvedSource, context); - addRuntimeConfigurationSpec(integrationBuilder, resolvedSource, context); - addTraitSpec(integrationBuilder, resolvedSource, context); - addOpenApiSpec(integrationBuilder, resolvedSource, context); + Map> traitConfigMap = new HashMap<>(); + addPropertyConfigurationSpec(specBuilder, context); + addRuntimeConfigurationSpec(specBuilder, resolvedSource, context); + addBuildPropertyConfigurationSpec(traitConfigMap, resolvedSource, context); + addEnvVarConfigurationSpec(traitConfigMap, resolvedSource, context); + addOpenApiSpec(traitConfigMap, resolvedSource, context); + addTraitSpec(traitConfigMap, resolvedSource, context); + + specBuilder.withTraits(KubernetesSupport.json().convertValue(traitConfigMap, Traits.class)); - final Integration integration = integrationBuilder.build(); + final Integration integration = integrationBuilder + .withSpec(specBuilder.build()) + .build(); if (YaksSettings.isLocal(clusterType(context))) { createLocalIntegration(integration, integration.getMetadata().getName(), context); } else { @@ -139,7 +153,7 @@ public void doExecute(TestContext context) { */ private static void createIntegration(KubernetesClient k8sClient, String namespace, Integration integration) { if (LOG.isDebugEnabled()) { - LOG.debug(KubernetesSupport.yaml().dumpAsMap(integration)); + LOG.debug(KubernetesSupport.yaml(new IntegrationValuePropertyMapper()).dumpAsMap(integration)); } k8sClient.resources(Integration.class, IntegrationList.class) @@ -156,7 +170,7 @@ private static void createIntegration(KubernetesClient k8sClient, String namespa */ private static void createLocalIntegration(Integration integration, String name, TestContext context) { try { - String integrationYaml = KubernetesSupport.yaml().dumpAsMap(integration); + String integrationYaml = KubernetesSupport.yaml(new IntegrationValuePropertyMapper()).dumpAsMap(integration); if (LOG.isDebugEnabled()) { LOG.debug(integrationYaml); @@ -168,7 +182,7 @@ private static void createLocalIntegration(Integration integration, String name, Path workDir = CamelJBangSettings.getWorkDir(); Files.createDirectories(workDir); Path file = workDir.resolve(String.format("i-%s.yaml", name)); - Files.write(file, integrationYaml.getBytes(StandardCharsets.UTF_8), + Files.writeString(file, integrationYaml, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); @@ -199,39 +213,35 @@ private static void createLocalIntegration(Integration integration, String name, private static String[] camelRunArgs(Integration integration) { List args = new ArrayList<>(); - if (integration.getSpec().getResources() != null) { - List openApiResources = integration.getSpec().getResources() - .stream() - .filter(r -> "openapi".equals(r.getType())) - .collect(Collectors.toList()); - - for (IntegrationSpec.Resource resource : openApiResources) { + if (integration.getSpec().getTraits().getOpenapi() != null) { + for (String openApi : integration.getSpec().getTraits().getOpenapi().getConfigmaps()) { args.add("--open-api"); - args.add(resource.getName()); + if (openApi.startsWith("configmap:")) { + args.add(openApi.substring("configmap:".length())); + } else { + args.add(openApi); + } } } return args.toArray(String[]::new); } - private void addOpenApiSpec(Integration.Builder integrationBuilder, String source, TestContext context) { + private void addOpenApiSpec(Map> traitConfigMap, String source, TestContext context) { + String traitName = "openapi.configmaps"; Pattern pattern = getModelinePattern("open-api"); Matcher depMatcher = pattern.matcher(source); while (depMatcher.find()) { String openApiSpecFile = depMatcher.group(1); - try { - integrationBuilder.openApi(openApiSpecFile, FileUtils.readToString(FileUtils.getFileResource(openApiSpecFile, context))); - } catch (IOException e) { - throw new CitrusRuntimeException(String.format("Failed to load OpenAPI spec from file '%s'", openApiSpecFile), e); - } + addTraitSpec("%s=%s".formatted(traitName, context.replaceDynamicContentInString(openApiSpecFile)), traitConfigMap); } - openApis.forEach((k, v) -> integrationBuilder.openApi(k, context.replaceDynamicContentInString(v))); + for (String openApi : openApis) { + addTraitSpec("%s=%s".formatted(traitName, context.replaceDynamicContentInString(openApi)), traitConfigMap); + } } - private void addTraitSpec(Integration.Builder integrationBuilder, String source, TestContext context) { - final Map traitConfigMap = new HashMap<>(); - + private void addTraitSpec(Map> traitConfigMap, String source, TestContext context) { if (traits != null && !traits.isEmpty()) { for (String t : context.resolveDynamicValuesInList(traits)) { addTraitSpec(t, traitConfigMap); @@ -243,36 +253,34 @@ private void addTraitSpec(Integration.Builder integrationBuilder, String source, while (depMatcher.find()) { addTraitSpec(depMatcher.group(1), traitConfigMap); } - - if (!traitConfigMap.isEmpty()) { - integrationBuilder.traits(traitConfigMap); - } } - private void addTraitSpec(String traitExpression, Map configMap) { + private void addTraitSpec(String traitExpression, Map> traitConfigMap) { //traitName.key=value final String[] trait = traitExpression.split("\\.",2); final String[] traitConfig = trait[1].split("=", 2); final String traitKey = traitConfig[0]; final Object traitValue = resolveTraitValue(traitKey, traitConfig[1].trim()); - if (configMap.containsKey(trait[0])) { - IntegrationSpec.TraitConfig config = configMap.get(trait[0]); + if (traitConfigMap.containsKey(trait[0])) { + Map config = traitConfigMap.get(trait[0]); - if (config.getConfiguration().containsKey(traitKey)) { - Object existingValue = config.getConfiguration().get(traitKey); + if (config.containsKey(traitKey)) { + Object existingValue = config.get(traitKey); if (existingValue instanceof List) { List values = (List) existingValue; values.add(traitValue.toString()); } else { - config.add(traitKey, Arrays.asList(existingValue.toString(), traitValue)); + config.put(traitKey, Arrays.asList(existingValue.toString(), traitValue)); } } else { - config.add(traitKey, initializeTraitValue(traitValue)); + config.put(traitKey, initializeTraitValue(traitValue)); } } else { - configMap.put(trait[0], new IntegrationSpec.TraitConfig(traitKey, initializeTraitValue(traitValue))); + Map config = new HashMap<>(); + config.put(traitKey, initializeTraitValue(traitValue)); + traitConfigMap.put(trait[0], config); } } @@ -306,18 +314,21 @@ private Object resolveTraitValue(String traitKey, String value) { return Boolean.valueOf(value); } - return value; + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return value; + } } - private void addPropertyConfigurationSpec(Integration.Builder integrationBuilder, TestContext context) { - final List configurationList = new ArrayList<>(); + private void addPropertyConfigurationSpec(IntegrationSpecBuilder specBuilder, TestContext context) { if (properties != null && !properties.isEmpty()) { for (String p : context.resolveDynamicValuesInList(properties)){ //key=value if (isValidPropertyFormat(p)) { final String[] property = p.split("=",2); - configurationList.add( - new IntegrationSpec.Configuration("property", createPropertySpec(property[0], property[1], context))); + specBuilder.addToConfiguration( + new ConfigurationBuilder().withType("property").withValue(createPropertySpec(property[0], property[1], context)).build()); } else { throw new IllegalArgumentException("Property " + p + " does not match format key=value"); } @@ -329,22 +340,17 @@ private void addPropertyConfigurationSpec(Integration.Builder integrationBuilder try { Properties props = new Properties(); props.load(ResourceUtils.resolve(pf, context).getInputStream()); - props.forEach((key, value) -> configurationList.add( - new IntegrationSpec.Configuration("property", createPropertySpec(key.toString(), value.toString(), context)))); + props.forEach((key, value) -> specBuilder.addToConfiguration( + new ConfigurationBuilder().withType("property").withValue(createPropertySpec(key.toString(), value.toString(), context)).build())); } catch (IOException e) { throw new CitrusRuntimeException("Failed to load property file", e); } } } - - if (!configurationList.isEmpty()) { - integrationBuilder.configuration(configurationList); - } } - private void addBuildPropertyConfigurationSpec(Integration.Builder integrationBuilder, String source, TestContext context) { + private void addBuildPropertyConfigurationSpec(Map> traitConfigMap, String source, TestContext context) { final String traitName = "builder.properties"; - final Map traitConfigMap = new HashMap<>(); if (buildProperties != null && !buildProperties.isEmpty()) { for (String p : context.resolveDynamicValuesInList(buildProperties)){ @@ -377,29 +383,55 @@ private void addBuildPropertyConfigurationSpec(Integration.Builder integrationBu while (depMatcher.find()) { addTraitSpec(String.format("%s=%s", traitName, depMatcher.group(1)), traitConfigMap); } + } - if (!traitConfigMap.isEmpty()) { - integrationBuilder.traits(traitConfigMap); + private void addEnvVarConfigurationSpec(Map> traitConfigMap, String source, TestContext context) { + final String traitName = "environment.vars"; + + if (envVars != null && !envVars.isEmpty()) { + for (String v : context.resolveDynamicValuesInList(envVars)){ + //key=value + if (isValidPropertyFormat(v)) { + final String[] property = v.split("=", 2); + addTraitSpec(String.format("%s=%s", traitName, createPropertySpec(property[0], property[1], context)), traitConfigMap); + } else { + throw new IllegalArgumentException("EnvVar " + v + " does not match format key=value"); + } + } } - } - private void addRuntimeConfigurationSpec(Integration.Builder integrationBuilder, String source, TestContext context) { - final List configurationList = new ArrayList<>(); + if (envVarFiles != null && !envVarFiles.isEmpty()) { + for (String vf : envVarFiles){ + try { + Properties props = new Properties(); + props.load(ResourceUtils.resolve(vf, context).getInputStream()); + props.forEach((key, value) -> addTraitSpec(String.format("%s=%s", + traitName, + createPropertySpec(key.toString(), value.toString(), context)), traitConfigMap)); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to load env var file", e); + } + } + } + + Pattern pattern = getModelinePattern("env"); + Matcher depMatcher = pattern.matcher(source); + while (depMatcher.find()) { + addTraitSpec(String.format("%s=%s", traitName, depMatcher.group(1)), traitConfigMap); + } + } + private void addRuntimeConfigurationSpec(IntegrationSpecBuilder specBuilder, String source, TestContext context) { Pattern pattern = getModelinePattern("config"); Matcher depMatcher = pattern.matcher(source); while (depMatcher.find()) { String[] config = depMatcher.group(1).split(":", 2); if (config.length == 2) { - configurationList.add(new IntegrationSpec.Configuration(config[0], config[1])); + specBuilder.addToConfiguration(new ConfigurationBuilder().withType(config[0]).withValue(context.replaceDynamicContentInString(config[1])).build()); } else { - configurationList.add(new IntegrationSpec.Configuration("property", depMatcher.group(1))); + specBuilder.addToConfiguration(new ConfigurationBuilder().withType("property").withValue(context.replaceDynamicContentInString(depMatcher.group(1))).build()); } } - - if (!configurationList.isEmpty()) { - integrationBuilder.configuration(configurationList); - } } private String createPropertySpec(String key, String value, TestContext context) { @@ -472,10 +504,12 @@ public static final class Builder extends AbstractCamelKAction.Builder dependencies = new ArrayList<>(); private final List buildProperties = new ArrayList<>(); private final List buildPropertyFiles = new ArrayList<>(); + private final List envVars = new ArrayList<>(); + private final List envVarFiles = new ArrayList<>(); private final List properties = new ArrayList<>(); private final List propertyFiles = new ArrayList<>(); private final List traits = new ArrayList<>(); - private final Map openApis = new LinkedHashMap<>(); + private final List openApis = new ArrayList<>(); private boolean supportVariables = true; public Builder integration(String integrationName) { @@ -509,8 +543,8 @@ public Builder source(String fileName, String source) { return this; } - public Builder openApi(String fileName, String content) { - this.openApis.put(fileName, content); + public Builder openApi(String configMap) { + this.openApis.add(configMap); return this; } @@ -561,7 +595,7 @@ public Builder buildPropertyFiles(List propertyFiles) { } public Builder buildProperties(String properties) { - if (properties != null && properties.length() > 0) { + if (properties != null && !properties.isEmpty()) { buildProperties(Arrays.asList(properties.split(","))); } @@ -578,6 +612,34 @@ public Builder buildProperties(Map properties) { return this; } + public Builder envVarFile(String envVarFile) { + this.envVarFiles.add(envVarFile); + return this; + } + + public Builder envVarFiles(List envVarFiles) { + this.envVarFiles.addAll(envVarFiles); + return this; + } + + public Builder envVars(String vars) { + if (vars != null && !vars.isEmpty()) { + envVars(Arrays.asList(vars.split(","))); + } + + return this; + } + + public Builder envVars(List vars) { + this.envVars.addAll(vars); + return this; + } + + public Builder envVars(Map vars) { + vars.forEach(this::envVar); + return this; + } + public Builder dependencies(List dependencies) { this.dependencies.addAll(dependencies); return this; @@ -598,6 +660,11 @@ public Builder buildProperty(String name, String value) { return this; } + public Builder envVar(String name, String value) { + this.envVars.add(name + "=" + value); + return this; + } + public Builder traits(String traits) { if (traits != null && traits.length() > 0) { traits(Arrays.asList(traits.split(","))); diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/DeleteIntegrationAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/DeleteIntegrationAction.java index 9b72b360..65ed6775 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/DeleteIntegrationAction.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/DeleteIntegrationAction.java @@ -16,12 +16,12 @@ package org.citrusframework.yaks.camelk.actions.integration; +import io.fabric8.kubernetes.client.KubernetesClient; +import org.apache.camel.v1.Integration; import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.CitrusRuntimeException; -import io.fabric8.kubernetes.client.KubernetesClient; import org.citrusframework.yaks.YaksSettings; import org.citrusframework.yaks.camelk.actions.AbstractCamelKAction; -import org.citrusframework.yaks.camelk.model.Integration; import org.citrusframework.yaks.camelk.model.IntegrationList; import static org.citrusframework.yaks.camelk.jbang.CamelJBang.camel; diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/IntegrationValuePropertyMapper.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/IntegrationValuePropertyMapper.java new file mode 100644 index 00000000..38ee8ca0 --- /dev/null +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/IntegrationValuePropertyMapper.java @@ -0,0 +1,44 @@ +/* + * Copyright the original author or authors. + * + * Licensed 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 org.citrusframework.yaks.camelk.actions.integration; + +import java.util.Collections; + +import org.citrusframework.yaks.kubernetes.KubernetesSupport; +import org.yaml.snakeyaml.introspector.Property; + +/** + * Helper to properly handle additional properties on Integration additional properties. + */ +class IntegrationValuePropertyMapper implements KubernetesSupport.PropertyValueMapper { + @Override + public Object map(Property property, Object propertyValue) { + if (propertyValue == null) { + return null; + } + + if (property.getName().equals("additionalProperties")) { + return Collections.emptyMap(); + } + + if (propertyValue instanceof org.apache.camel.v1.integrationspec.Flows flowsProps) { + return flowsProps.getAdditionalProperties(); + } + + return propertyValue; + } +} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/VerifyIntegrationAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/VerifyIntegrationAction.java index bd9f6bef..92118d3e 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/VerifyIntegrationAction.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/integration/VerifyIntegrationAction.java @@ -18,16 +18,21 @@ import java.util.Map; -import org.citrusframework.context.TestContext; -import org.citrusframework.exceptions.ActionTimeoutException; -import org.citrusframework.exceptions.CitrusRuntimeException; import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.api.model.PodCondition; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.client.dsl.PodResource; +import org.apache.camel.v1.Integration; +import org.apache.camel.v1.IntegrationStatus; +import org.apache.camel.v1.integrationstatus.Conditions; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.ActionTimeoutException; +import org.citrusframework.exceptions.CitrusRuntimeException; import org.citrusframework.yaks.YaksSettings; import org.citrusframework.yaks.camelk.CamelKSettings; import org.citrusframework.yaks.camelk.actions.AbstractCamelKAction; import org.citrusframework.yaks.camelk.jbang.ProcessAndOutput; +import org.citrusframework.yaks.camelk.model.IntegrationList; import org.citrusframework.yaks.kubernetes.KubernetesSupport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,6 +59,8 @@ public class VerifyIntegrationAction extends AbstractCamelKAction { private final String phase; private final boolean printLogs; + private final boolean stopOnErrorStatus; + /** * Constructor using given builder. * @param builder @@ -66,6 +73,7 @@ public VerifyIntegrationAction(Builder builder) { this.maxAttempts = builder.maxAttempts; this.delayBetweenAttempts = builder.delayBetweenAttempts; this.printLogs = builder.printLogs; + this.stopOnErrorStatus = builder.stopOnErrorStatus; } @Override @@ -139,6 +147,11 @@ private Long verifyLocalIntegrationStatus(String integration, String phase, Test if ((phase.equals("Stopped") && properties.isEmpty()) || (!properties.isEmpty() && properties.get("STATUS").equals(phase))) { LOG.info(String.format("Verified integration '%s' state '%s' - All values OK!", integration, phase)); return pid; + } else if (phase.equals("Error")) { + LOG.info(String.format("Integration '%s' is in state 'Error'", integration)); + if (stopOnErrorStatus) { + throw new CitrusRuntimeException(String.format("Failed to verify integration '%s' - is in state 'Error'", integration)); + } } } @@ -244,10 +257,23 @@ private Pod verifyIntegrationPod(String name, String phase, String namespace) { INTEGRATION_STATUS_LOG.info(String.format("Waiting for integration '%s' to be in state '%s'", name, phase)); for (int i = 0; i < maxAttempts; i++) { - Pod pod = getIntegrationPod(name, phase, namespace); - if (pod != null) { - LOG.info(String.format("Verified integration pod '%s' state '%s' - All values OK!", name, phase)); - return pod; + Integration integration = getIntegration(name, namespace); + if (integration != null && integration.getStatus() != null) { + if ("Error".equals(integration.getStatus().getPhase())) { + String readyConditionError = getReadyConditionErrorDetails(integration.getStatus()); + if (stopOnErrorStatus) { + INTEGRATION_STATUS_LOG.info(String.format("Integration '%s' is in state 'Error' - %s", name, readyConditionError)); + throw new CitrusRuntimeException(String.format("Failed to verify integration '%s' - is in state 'Error' - %s", name, readyConditionError)); + } else { + INTEGRATION_STATUS_LOG.info(String.format("Integration '%s' is in state 'Error' - %s. Will keep checking ...", name, readyConditionError)); + } + } else { + Pod pod = getIntegrationPod(name, phase, namespace); + if (pod != null) { + LOG.info(String.format("Verified integration pod '%s' state '%s' - All values OK!", name, phase)); + return pod; + } + } } LOG.info(String.format("Waiting for integration '%s' to be in state '%s'- retry in %s ms", name, phase, delayBetweenAttempts)); @@ -263,6 +289,13 @@ private Pod verifyIntegrationPod(String name, String phase, String namespace) { "is not in state '%s' after %d attempts", name, phase, maxAttempts))); } + private Integration getIntegration(String name, String namespace) { + return getKubernetesClient().resources(Integration.class, IntegrationList.class) + .inNamespace(namespace) + .withName(name) + .get(); + } + /** * Retrieve pod given state. * @param integration @@ -285,7 +318,18 @@ private Pod getIntegrationPod(final String integration, final String phase, fina boolean verified = KubernetesSupport.verifyPodStatus(pod, phase); if (!verified) { - INTEGRATION_STATUS_LOG.info(String.format("Integration '%s' not yet in state '%s'. Will keep checking ...", integration, phase)); + if (pod != null && pod.getStatus() != null && + "Error".equals(pod.getStatus().getPhase())) { + String readyConditionError = getReadyConditionErrorDetails(pod); + if (stopOnErrorStatus) { + INTEGRATION_STATUS_LOG.info(String.format("Integration '%s' is in state 'Error' - %s", integration, readyConditionError)); + throw new CitrusRuntimeException(String.format("Failed to verify integration '%s' - is in state 'Error' - %s", integration, readyConditionError)); + } else { + INTEGRATION_STATUS_LOG.info(String.format("Integration '%s' is in state 'Error' - %s. Will keep checking ...", integration, readyConditionError)); + } + } else { + INTEGRATION_STATUS_LOG.info(String.format("Integration '%s' not yet in state '%s'. Will keep checking ...", integration, phase)); + } } return verified; @@ -294,6 +338,26 @@ private Pod getIntegrationPod(final String integration, final String phase, fina .orElse(null); } + private String getReadyConditionErrorDetails(IntegrationStatus status) { + for (Conditions condition : status.getConditions()) { + if ("Ready".equals(condition.getType()) && "False".equalsIgnoreCase(condition.getStatus())) { + return "%s: %s".formatted(condition.getReason(), condition.getMessage()); + } + } + + return "Unknown error"; + } + + private String getReadyConditionErrorDetails(Pod pod) { + for (PodCondition condition : pod.getStatus().getConditions()) { + if ("Ready".equals(condition.getType()) && "False".equalsIgnoreCase(condition.getStatus())) { + return "%s: %s".formatted(condition.getReason(), condition.getMessage()); + } + } + + return "Unknown error"; + } + /** * Action builder. */ @@ -308,6 +372,8 @@ public static final class Builder extends AbstractCamelKAction.Builder dependencies; - private final Map dataTypes; + private final Map dataTypes; private final Resource resource; private final boolean supportVariables; @@ -89,7 +100,13 @@ private void createKamelet(TestContext context) { resolvedSource = FileUtils.readToString(resource); } - kamelet = KubernetesSupport.yaml().loadAs(resolvedSource, Kamelet.class); + if (IsJsonPredicate.getInstance().test(resolvedSource)) { + kamelet = KubernetesSupport.json().readValue(resolvedSource, Kamelet.class); + } else { + // need to make a detour over Json to support additional properties set on Pipe + Map raw = KubernetesSupport.yaml().load(resolvedSource); + kamelet = KubernetesSupport.json().convertValue(raw, Kamelet.class); + } } catch (IOException e) { throw new CitrusRuntimeException(String.format("Failed to load Kamelet from resource %s", name + ".kamelet.yaml"), e); } @@ -105,27 +122,36 @@ private void createKamelet(TestContext context) { definition.setProperties(context.resolveDynamicValuesInMap(definition.getProperties())); definition.setRequired(context.resolveDynamicValuesInList(definition.getRequired())); - final Kamelet.Builder builder = new Kamelet.Builder() - .name(context.replaceDynamicContentInString(name)) - .definition(definition); + final KameletBuilder builder = new KameletBuilder() + .withNewMetadata() + .withName(context.replaceDynamicContentInString(name)) + .endMetadata(); + + KameletSpecBuilder specBuilder = new KameletSpecBuilder() + .withDefinition(definition); if (template != null) { - builder.template(context.replaceDynamicContentInString(template)); + specBuilder.withTemplate(new TemplateBuilder() + .withAdditionalProperties(KubernetesSupport.yaml(new KameletValuePropertyMapper()).load(context.replaceDynamicContentInString(template))) + .build()); } if (source != null) { - builder.source(source.getName(), context.replaceDynamicContentInString(source.getContent())); + specBuilder.withSources(new SourcesBuilder() + .withName(source.getName()) + .withContent(context.replaceDynamicContentInString(source.getContent())) + .build()); } if (dependencies != null && !dependencies.isEmpty()) { - builder.dependencies(context.resolveDynamicValuesInList(dependencies)); + specBuilder.withDependencies(context.resolveDynamicValuesInList(dependencies)); } if (dataTypes != null && !dataTypes.isEmpty()) { - builder.dataTypes(context.resolveDynamicValuesInMap(dataTypes)); + specBuilder.withDataTypes(dataTypes); } - kamelet = builder.build(); + kamelet = builder.withSpec(specBuilder.build()).build(); } if (!kamelet.getMetadata().getLabels().containsKey(KameletSettings.KAMELET_TYPE_LABEL)) { @@ -150,12 +176,7 @@ private void createKamelet(TestContext context) { } if (getApiVersion(context).equals(CamelKSettings.V1ALPHA1)) { - KameletV1Alpha1 kameletV1Alpha1; - if (kamelet instanceof KameletV1Alpha1) { - kameletV1Alpha1 = (KameletV1Alpha1) kamelet; - } else { - kameletV1Alpha1 = new KameletV1Alpha1.Builder().from(kamelet).build(); - } + KameletV1Alpha1 kameletV1Alpha1 = KameletV1Alpha1.from(kamelet); getKubernetesClient().resources(KameletV1Alpha1.class, KameletV1Alpha1List.class) .inNamespace(kameletNamespace(context)) @@ -178,10 +199,10 @@ public static final class Builder extends AbstractKameletAction.Builder dependencies = new ArrayList<>(); - private KameletSpec.Definition definition = new KameletSpec.Definition(); - private final Map dataTypes = new HashMap<>(); + private Definition definition = new Definition(); + private final Map dataTypes = new HashMap<>(); private Resource resource; @@ -204,12 +225,18 @@ public Builder title(String title) { } public Builder source(String name, String language, String content) { - this.source = new KameletSpec.Source(name + "." + language, content); + this.source = new SourcesBuilder() + .withName(name + "." + language) + .withContent(content) + .build(); return this; } public Builder source(String name, String content) { - this.source = new KameletSpec.Source(name, content); + this.source = new SourcesBuilder() + .withName(name) + .withContent(content) + .build(); return this; } @@ -239,12 +266,12 @@ public Builder dependency(String dependency) { return this; } - public Builder definition(KameletSpec.Definition definition) { + public Builder definition(Definition definition) { this.definition = definition; return this; } - public Builder addProperty(String name, KameletSpec.Definition.PropertyConfig propertyConfig) { + public Builder addProperty(String name, Properties propertyConfig) { this.definition.getProperties().put(name, propertyConfig); return this; } @@ -263,30 +290,36 @@ public Builder errorType(String scheme, String format) { public Builder addDataType(String slot, String scheme, String format) { if (dataTypes.containsKey(slot)) { - this.dataTypes.get(slot).getTypes().put(format, new KameletSpec.DataTypeSpec(scheme, format)); + this.dataTypes.get(slot).getTypes().put(format, new TypesBuilder().withScheme(scheme).withFormat(format).build()); } else { - this.dataTypes.put(slot, new KameletSpec.DataTypesSpec(format, new KameletSpec.DataTypeSpec(scheme, format))); + Map dataTypes = new HashMap<>(); + dataTypes.put(format, new TypesBuilder().withScheme(scheme).withFormat(format).build()); + this.dataTypes.put(slot, new DataTypesBuilder().withTypes(dataTypes).build()); } return this; } - public Builder fromBuilder(Kamelet.Builder builder) { + public Builder fromBuilder(KameletBuilder builder) { Kamelet kamelet = builder.build(); name = kamelet.getMetadata().getName(); definition = kamelet.getSpec().getDefinition(); - dependencies.addAll(kamelet.getSpec().getDependencies()); - dataTypes.putAll(kamelet.getSpec().getDataTypes()); + + if (kamelet.getSpec().getDependencies() != null) { + dependencies.addAll(kamelet.getSpec().getDependencies()); + } + + if (kamelet.getSpec().getDataTypes() != null) { + dataTypes.putAll(kamelet.getSpec().getDataTypes()); + } if (kamelet.getSpec().getSources() != null && !kamelet.getSpec().getSources().isEmpty()) { source = kamelet.getSpec().getSources().get(0); } if (kamelet.getSpec().getTemplate() != null) { - template = KubernetesSupport.yaml().dumpAsMap(kamelet.getSpec().getTemplate()); - } else if (kamelet.getSpec().getFlow() != null) { - template = KubernetesSupport.yaml().dumpAsMap(kamelet.getSpec().getFlow()); + template = KubernetesSupport.yaml(new KameletValuePropertyMapper()).dumpAsMap(kamelet.getSpec().getTemplate()); } return this; diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/CreateKameletBindingAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/CreateKameletBindingAction.java new file mode 100644 index 00000000..450c7e9b --- /dev/null +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/CreateKameletBindingAction.java @@ -0,0 +1,285 @@ +/* + * Copyright the original author or authors. + * + * Licensed 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 org.citrusframework.yaks.camelk.actions.kamelet; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Map; + +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.dsl.Updatable; +import org.apache.camel.v1alpha1.KameletBinding; +import org.apache.camel.v1alpha1.KameletBindingBuilder; +import org.apache.camel.v1alpha1.KameletBindingSpecBuilder; +import org.apache.camel.v1alpha1.kameletbindingspec.Integration; +import org.apache.camel.v1alpha1.kameletbindingspec.Sink; +import org.apache.camel.v1alpha1.kameletbindingspec.SinkBuilder; +import org.apache.camel.v1alpha1.kameletbindingspec.Source; +import org.apache.camel.v1alpha1.kameletbindingspec.SourceBuilder; +import org.apache.camel.v1alpha1.kameletbindingspec.source.Ref; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.spi.Resource; +import org.citrusframework.util.FileUtils; +import org.citrusframework.util.IsJsonPredicate; +import org.citrusframework.yaks.YaksSettings; +import org.citrusframework.yaks.camelk.CamelKSettings; +import org.citrusframework.yaks.camelk.jbang.CamelJBangSettings; +import org.citrusframework.yaks.camelk.jbang.ProcessAndOutput; +import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBindingList; +import org.citrusframework.yaks.kubernetes.KubernetesSupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.citrusframework.yaks.camelk.jbang.CamelJBang.camel; + +/** + * Test action creates new Camel K binding with given name and source code. Uses given Kubernetes client to + * create a custom resource of type binding. + * + * @author Christoph Deppisch + */ +public class CreateKameletBindingAction extends AbstractKameletAction { + + /** Logger */ + private static final Logger LOG = LoggerFactory.getLogger(CreateKameletBindingAction.class); + + private final String bindingName; + private final Integration integration; + private final Source source; + private final Sink sink; + private final Resource resource; + + /** + * Constructor using given builder. + * @param builder + */ + public CreateKameletBindingAction(Builder builder) { + super("create-binding", builder); + this.bindingName = builder.bindingName; + this.integration = builder.integration; + this.source = builder.source; + this.sink = builder.sink; + this.resource = builder.resource; + } + + @Override + public void doExecute(TestContext context) { + final KameletBinding binding; + + String bindingName = context.replaceDynamicContentInString(this.bindingName); + LOG.info(String.format("Creating Camel K binding '%s'", bindingName)); + + if (resource != null) { + try { + String yamlOrJson = context.replaceDynamicContentInString(FileUtils.readToString(resource)); + if (IsJsonPredicate.getInstance().test(yamlOrJson)) { + binding = KubernetesSupport.json().readValue(yamlOrJson, KameletBinding.class); + } else { + // need to make a detour over Json to support additional properties set on Pipe + Map raw = KubernetesSupport.yaml().load(yamlOrJson); + binding = KubernetesSupport.json().convertValue(raw, KameletBinding.class); + } + } catch (IOException e) { + throw new CitrusRuntimeException(String.format("Failed to load binding from resource %s", bindingName + ".yaml"), e); + } + } else { + final KameletBindingBuilder builder = new KameletBindingBuilder() + .withNewMetadata() + .withName(bindingName) + .endMetadata(); + + KameletBindingSpecBuilder specBuilder = new KameletBindingSpecBuilder(); + if (integration != null) { + specBuilder.withIntegration(integration); + } + + if (source != null) { + if (source.getProperties() != null && source.getProperties().getAdditionalProperties() != null) { + context.resolveDynamicValuesInMap(source.getProperties().getAdditionalProperties()); + } + specBuilder.withSource(source); + } + + if (sink != null) { + if (sink.getUri() != null) { + sink.setUri(context.replaceDynamicContentInString(sink.getUri())); + } + + if (sink.getProperties() != null && sink.getProperties().getAdditionalProperties() != null) { + context.resolveDynamicValuesInMap(sink.getProperties().getAdditionalProperties()); + } + specBuilder.withSink(sink); + } + + binding = builder.withSpec(specBuilder.build()).build(); + } + + if (YaksSettings.isLocal(clusterType(context))) { + createLocal(KubernetesSupport.yaml(new KameletBindingValuePropertyMapper()).dumpAsMap(binding), bindingName, context); + } else { + createKameletBinding(getKubernetesClient(), namespace(context), binding, context); + } + + LOG.info(String.format("Successfully created binding '%s'", binding.getMetadata().getName())); + } + + /** + * Creates the Kamelet binding as a custom resource in given namespace. + * @param k8sClient + * @param namespace + * @param binding + * @param context + */ + private void createKameletBinding(KubernetesClient k8sClient, String namespace, KameletBinding binding, TestContext context) { + if (LOG.isDebugEnabled()) { + LOG.debug(KubernetesSupport.yaml(new KameletBindingValuePropertyMapper()).dumpAsMap(binding)); + } + + k8sClient.resources(KameletBinding.class, KameletBindingList.class) + .inNamespace(namespace) + .resource(binding) + .createOr(Updatable::update); + } + + /** + * Creates the binding with local JBang runtime. + * @param yaml + * @param name + * @param context + */ + private void createLocal(String yaml, String name, TestContext context) { + try { + if (LOG.isDebugEnabled()) { + LOG.debug(yaml); + } + + Path workDir = CamelJBangSettings.getWorkDir(); + Files.createDirectories(workDir); + Path file = workDir.resolve(String.format("i-%s.yaml", name)); + Files.writeString(file, yaml, + StandardOpenOption.WRITE, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING); + ProcessAndOutput pao = camel().run(name, file); + + if (!pao.getProcess().isAlive()) { + if (LOG.isDebugEnabled()) { + LOG.debug(pao.getOutput()); + } + + throw new CitrusRuntimeException(String.format("Failed to create binding - exit code %s", pao.getProcess().exitValue())); + } + + Long pid = pao.getCamelProcessId(); + context.setVariable(name + ":pid", pid); + context.setVariable(name + ":process:" + pid, pao); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to create binding file", e); + } + } + + /** + * Action builder. + */ + public static final class Builder extends AbstractKameletAction.Builder { + + private String bindingName; + private Integration integration; + private Source source; + private Sink sink; + private Resource resource; + + public Builder binding(String bindingName) { + apiVersion(CamelKSettings.V1ALPHA1); + this.bindingName = bindingName; + return this; + } + + public Builder integration(Integration integration) { + this.integration = integration; + return this; + } + + public Builder source(Source source) { + this.source = source; + return this; + } + + public Builder source(String uri) { + return source(new SourceBuilder().withUri(uri).build()); + } + + public Builder source(Ref ref, String properties) { + Map props = null; + if (properties != null && !properties.isEmpty()) { + props = KubernetesSupport.yaml().load(properties); + } + + return source(new SourceBuilder().withRef(ref) + .withNewProperties() + .addToAdditionalProperties(props) + .endProperties().build()); + } + + public Builder sink(Sink sink) { + this.sink = sink; + return this; + } + + public Builder sink(String uri) { + return sink(new SinkBuilder().withUri(uri).build()); + } + + public Builder sink(org.apache.camel.v1alpha1.kameletbindingspec.sink.Ref ref, String properties) { + Map props = null; + if (properties != null && !properties.isEmpty()) { + props = KubernetesSupport.yaml().load(properties); + } + + return sink(new SinkBuilder().withRef(ref) + .withNewProperties() + .addToAdditionalProperties(props) + .endProperties() + .build()); + } + + public Builder fromBuilder(KameletBindingBuilder builder) { + KameletBinding binding = builder.build(); + + bindingName = binding.getMetadata().getName(); + integration = binding.getSpec().getIntegration(); + source = binding.getSpec().getSource(); + sink = binding.getSpec().getSink(); + + return this; + } + + public Builder resource(Resource resource) { + this.resource = resource; + return this; + } + + @Override + public CreateKameletBindingAction build() { + return new CreateKameletBindingAction(this); + } + } + +} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/CreatePipeAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/CreatePipeAction.java index 67351ebb..a868845b 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/CreatePipeAction.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/CreatePipeAction.java @@ -17,7 +17,6 @@ package org.citrusframework.yaks.camelk.actions.kamelet; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; @@ -25,20 +24,24 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.Updatable; +import org.apache.camel.v1.Pipe; +import org.apache.camel.v1.PipeBuilder; +import org.apache.camel.v1.PipeSpecBuilder; +import org.apache.camel.v1.pipespec.Integration; +import org.apache.camel.v1.pipespec.Sink; +import org.apache.camel.v1.pipespec.SinkBuilder; +import org.apache.camel.v1.pipespec.Source; +import org.apache.camel.v1.pipespec.SourceBuilder; +import org.apache.camel.v1.pipespec.source.Ref; import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.CitrusRuntimeException; import org.citrusframework.spi.Resource; import org.citrusframework.util.FileUtils; +import org.citrusframework.util.IsJsonPredicate; import org.citrusframework.yaks.YaksSettings; -import org.citrusframework.yaks.camelk.CamelKSettings; import org.citrusframework.yaks.camelk.jbang.CamelJBangSettings; import org.citrusframework.yaks.camelk.jbang.ProcessAndOutput; -import org.citrusframework.yaks.camelk.model.IntegrationSpec; -import org.citrusframework.yaks.camelk.model.Pipe; import org.citrusframework.yaks.camelk.model.PipeList; -import org.citrusframework.yaks.camelk.model.PipeSpec; -import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBinding; -import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBindingList; import org.citrusframework.yaks.kubernetes.KubernetesSupport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,9 +60,9 @@ public class CreatePipeAction extends AbstractKameletAction { private static final Logger LOG = LoggerFactory.getLogger(CreatePipeAction.class); private final String pipeName; - private final IntegrationSpec integration; - private final PipeSpec.Endpoint source; - private final PipeSpec.Endpoint sink; + private final Integration integration; + private final Source source; + private final Sink sink; private final Resource resource; /** @@ -84,27 +87,33 @@ public void doExecute(TestContext context) { if (resource != null) { try { - if (getApiVersion(context).equals(CamelKSettings.V1ALPHA1)) { - pipe = KubernetesSupport.yaml().loadAs( - context.replaceDynamicContentInString(FileUtils.readToString(resource)), KameletBinding.class); + String yamlOrJson = context.replaceDynamicContentInString(FileUtils.readToString(resource)); + if (IsJsonPredicate.getInstance().test(yamlOrJson)) { + pipe = KubernetesSupport.json().readValue(yamlOrJson, Pipe.class); } else { - pipe = KubernetesSupport.yaml().loadAs( - context.replaceDynamicContentInString(FileUtils.readToString(resource)), Pipe.class); + // need to make a detour over Json to support additional properties set on Pipe + Map raw = KubernetesSupport.yaml().load(yamlOrJson); + pipe = KubernetesSupport.json().convertValue(raw, Pipe.class); } } catch (IOException e) { throw new CitrusRuntimeException(String.format("Failed to load pipe from resource %s", pipeName + ".yaml"), e); } } else { - final Pipe.Builder builder = new Pipe.Builder() - .name(pipeName); + final PipeBuilder builder = new PipeBuilder() + .withNewMetadata() + .withName(pipeName) + .endMetadata(); + PipeSpecBuilder specBuilder = new PipeSpecBuilder(); if (integration != null) { - builder.integration(integration); + specBuilder.withIntegration(integration); } if (source != null) { - source.setProperties(context.resolveDynamicValuesInMap(source.getProperties())); - builder.source(source); + if (source.getProperties() != null && source.getProperties().getAdditionalProperties() != null) { + context.resolveDynamicValuesInMap(source.getProperties().getAdditionalProperties()); + } + specBuilder.withSource(source); } if (sink != null) { @@ -112,15 +121,17 @@ public void doExecute(TestContext context) { sink.setUri(context.replaceDynamicContentInString(sink.getUri())); } - sink.setProperties(context.resolveDynamicValuesInMap(sink.getProperties())); - builder.sink(sink); + if (sink.getProperties() != null && sink.getProperties().getAdditionalProperties() != null) { + context.resolveDynamicValuesInMap(sink.getProperties().getAdditionalProperties()); + } + specBuilder.withSink(sink); } - pipe = builder.build(); + pipe = builder.withSpec(specBuilder.build()).build(); } if (YaksSettings.isLocal(clusterType(context))) { - createLocalPipe(pipe, pipeName, context); + createLocal(KubernetesSupport.yaml(new PipeValuePropertyMapper()).dumpAsMap(pipe), pipeName, context); } else { createPipe(getKubernetesClient(), namespace(context), pipe, context); } @@ -137,60 +148,31 @@ public void doExecute(TestContext context) { */ private void createPipe(KubernetesClient k8sClient, String namespace, Pipe pipe, TestContext context) { if (LOG.isDebugEnabled()) { - LOG.debug(KubernetesSupport.yaml().dumpAsMap(pipe)); + LOG.debug(KubernetesSupport.yaml(new PipeValuePropertyMapper()).dumpAsMap(pipe)); } - if (getApiVersion(context).equals(CamelKSettings.V1ALPHA1)) { - KameletBinding kb; - if (pipe instanceof KameletBinding) { - kb = (KameletBinding) pipe; - } else { - kb = new KameletBinding.Builder().from(pipe).build(); - } - - k8sClient.resources(KameletBinding.class, KameletBindingList.class) - .inNamespace(namespace) - .resource(kb) - .createOr(Updatable::update); - } else { - k8sClient.resources(Pipe.class, PipeList.class) - .inNamespace(namespace) - .resource(pipe) - .createOr(Updatable::update); - } + k8sClient.resources(Pipe.class, PipeList.class) + .inNamespace(namespace) + .resource(pipe) + .createOr(Updatable::update); } /** * Creates the pipe with local JBang runtime. - * @param pipe + * @param yaml * @param name * @param context */ - private void createLocalPipe(Pipe pipe, String name, TestContext context) { + private void createLocal(String yaml, String name, TestContext context) { try { - String pipeYaml; - - if (getApiVersion(context).equals(CamelKSettings.V1ALPHA1)) { - KameletBinding kb; - if (pipe instanceof KameletBinding) { - kb = (KameletBinding) pipe; - } else { - kb = new KameletBinding.Builder().from(pipe).build(); - } - - pipeYaml = KubernetesSupport.yaml().dumpAsMap(kb); - } else { - pipeYaml = KubernetesSupport.yaml().dumpAsMap(pipe); - } - if (LOG.isDebugEnabled()) { - LOG.debug(pipeYaml); + LOG.debug(yaml); } Path workDir = CamelJBangSettings.getWorkDir(); Files.createDirectories(workDir); Path file = workDir.resolve(String.format("i-%s.yaml", name)); - Files.write(file, pipeYaml.getBytes(StandardCharsets.UTF_8), + Files.writeString(file, yaml, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); @@ -218,64 +200,65 @@ private void createLocalPipe(Pipe pipe, String name, TestContext context) { public static final class Builder extends AbstractKameletAction.Builder { private String pipeName; - private IntegrationSpec integration; - private PipeSpec.Endpoint source; - private PipeSpec.Endpoint sink; + private Integration integration; + private Source source; + private Sink sink; private Resource resource; - public Builder binding(String pipeName) { - apiVersion(CamelKSettings.V1ALPHA1); - this.pipeName = pipeName; - return this; - } - public Builder pipe(String pipeName) { this.pipeName = pipeName; return this; } - public Builder integration(IntegrationSpec integration) { + public Builder integration(Integration integration) { this.integration = integration; return this; } - public Builder source(PipeSpec.Endpoint source) { + public Builder source(Source source) { this.source = source; return this; } public Builder source(String uri) { - return source(new PipeSpec.Endpoint(uri)); + return source(new SourceBuilder().withUri(uri).build()); } - public Builder source(PipeSpec.Endpoint.ObjectReference ref, String properties) { + public Builder source(Ref ref, String properties) { Map props = null; if (properties != null && !properties.isEmpty()) { props = KubernetesSupport.yaml().load(properties); } - return source(new PipeSpec.Endpoint(ref, props)); + return source(new SourceBuilder().withRef(ref) + .withNewProperties() + .addToAdditionalProperties(props) + .endProperties().build()); } - public Builder sink(PipeSpec.Endpoint sink) { + public Builder sink(Sink sink) { this.sink = sink; return this; } public Builder sink(String uri) { - return sink(new PipeSpec.Endpoint(uri)); + return sink(new SinkBuilder().withUri(uri).build()); } - public Builder sink(PipeSpec.Endpoint.ObjectReference ref, String properties) { + public Builder sink(org.apache.camel.v1.pipespec.sink.Ref ref, String properties) { Map props = null; if (properties != null && !properties.isEmpty()) { props = KubernetesSupport.yaml().load(properties); } - return sink(new PipeSpec.Endpoint(ref, props)); + return sink(new SinkBuilder().withRef(ref) + .withNewProperties() + .addToAdditionalProperties(props) + .endProperties() + .build()); } - public Builder fromBuilder(Pipe.Builder builder) { + public Builder fromBuilder(PipeBuilder builder) { Pipe pipe = builder.build(); pipeName = pipe.getMetadata().getName(); @@ -296,4 +279,5 @@ public CreatePipeAction build() { return new CreatePipeAction(this); } } + } diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletAction.java index 544eba7b..eb6451ac 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletAction.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletAction.java @@ -16,9 +16,9 @@ package org.citrusframework.yaks.camelk.actions.kamelet; +import org.apache.camel.v1.Kamelet; import org.citrusframework.context.TestContext; import org.citrusframework.yaks.camelk.CamelKSettings; -import org.citrusframework.yaks.camelk.model.Kamelet; import org.citrusframework.yaks.camelk.model.KameletList; import org.citrusframework.yaks.camelk.model.v1alpha1.KameletV1Alpha1; import org.citrusframework.yaks.camelk.model.v1alpha1.KameletV1Alpha1List; diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletBindingAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletBindingAction.java new file mode 100644 index 00000000..bae2df62 --- /dev/null +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletBindingAction.java @@ -0,0 +1,101 @@ +/* + * Copyright the original author or authors. + * + * Licensed 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 org.citrusframework.yaks.camelk.actions.kamelet; + +import io.fabric8.kubernetes.client.KubernetesClient; +import org.apache.camel.v1alpha1.KameletBinding; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.yaks.YaksSettings; +import org.citrusframework.yaks.camelk.CamelKSettings; +import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBindingList; + +import static org.citrusframework.yaks.camelk.jbang.CamelJBang.camel; + +/** + * @author Christoph Deppisch + */ +public class DeleteKameletBindingAction extends AbstractKameletAction { + + private final String bindingName; + + public DeleteKameletBindingAction(Builder builder) { + super("delete-binding", builder); + + this.bindingName = builder.bindingName; + } + + @Override + public void doExecute(TestContext context) { + String binding = context.replaceDynamicContentInString(bindingName); + + LOG.info(String.format("Deleting binding '%s'", binding)); + + if (YaksSettings.isLocal(clusterType(context))) { + deleteLocalBinding(binding, context); + } else { + deleteBinding(getKubernetesClient(), namespace(context), binding, context); + } + + LOG.info(String.format("Successfully deleted binding '%s'", binding)); + } + + private void deleteBinding(KubernetesClient k8sClient, String namespace, String name, TestContext context) { + k8sClient.resources(KameletBinding.class, KameletBindingList.class) + .inNamespace(namespace) + .withName(name) + .delete(); + } + + /** + * Deletes the Camel K integration from local JBang runtime. + * @param name + * @param context + */ + private static void deleteLocalBinding(String name, TestContext context) { + Long pid; + if (context.getVariables().containsKey(name + ":pid")) { + pid = context.getVariable(name + ":pid", Long.class); + } else { + pid = camel().getAll().stream() + .filter(props -> name.equals(props.get("NAME")) && !props.getOrDefault("PID", "").isBlank()) + .map(props -> Long.valueOf(props.get("PID"))).findFirst() + .orElseThrow(() -> new CitrusRuntimeException(String.format("Unable to retrieve binding process id %s:pid", name))); + } + + camel().stop(pid); + } + + /** + * Action builder. + */ + public static class Builder extends AbstractKameletAction.Builder { + + private String bindingName; + + public Builder binding(String name) { + apiVersion(CamelKSettings.V1ALPHA1); + this.bindingName = name; + return this; + } + + @Override + public DeleteKameletBindingAction build() { + return new DeleteKameletBindingAction(this); + } + } +} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeletePipeAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeletePipeAction.java index 0f38fe97..0a247a21 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeletePipeAction.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/DeletePipeAction.java @@ -16,14 +16,11 @@ package org.citrusframework.yaks.camelk.actions.kamelet; +import io.fabric8.kubernetes.client.KubernetesClient; +import org.apache.camel.v1.Pipe; import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.CitrusRuntimeException; -import io.fabric8.kubernetes.client.KubernetesClient; import org.citrusframework.yaks.YaksSettings; -import org.citrusframework.yaks.camelk.CamelKSettings; -import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBinding; -import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBindingList; -import org.citrusframework.yaks.camelk.model.Pipe; import org.citrusframework.yaks.camelk.model.PipeList; import static org.citrusframework.yaks.camelk.jbang.CamelJBang.camel; @@ -48,26 +45,19 @@ public void doExecute(TestContext context) { LOG.info(String.format("Deleting pipe '%s'", pipe)); if (YaksSettings.isLocal(clusterType(context))) { - deleteLocalBinding(pipe, context); + deleteLocalPipe(pipe, context); } else { - deleteBinding(getKubernetesClient(), namespace(context), pipe, context); + deletePipe(getKubernetesClient(), namespace(context), pipe, context); } LOG.info(String.format("Successfully deleted pipe '%s'", pipe)); } - private void deleteBinding(KubernetesClient k8sClient, String namespace, String name, TestContext context) { - if (getApiVersion(context).equals(CamelKSettings.V1ALPHA1)) { - k8sClient.resources(KameletBinding.class, KameletBindingList.class) - .inNamespace(namespace) - .withName(name) - .delete(); - } else { - k8sClient.resources(Pipe.class, PipeList.class) + private void deletePipe(KubernetesClient k8sClient, String namespace, String name, TestContext context) { + k8sClient.resources(Pipe.class, PipeList.class) .inNamespace(namespace) .withName(name) .delete(); - } } /** @@ -75,7 +65,7 @@ private void deleteBinding(KubernetesClient k8sClient, String namespace, String * @param name * @param context */ - private static void deleteLocalBinding(String name, TestContext context) { + private static void deleteLocalPipe(String name, TestContext context) { Long pid; if (context.getVariables().containsKey(name + ":pid")) { pid = context.getVariable(name + ":pid", Long.class); @@ -96,12 +86,6 @@ public static class Builder extends AbstractKameletAction.Builder { LOG.info(String.format("Verify Kamlet '%s' exists in namespace '%s'", name, namespace)); - Kamelet kamelet; + HasMetadata kamelet; if (getApiVersion(context).equals(CamelKSettings.V1ALPHA1)) { kamelet = getKubernetesClient().resources(KameletV1Alpha1.class, KameletV1Alpha1List.class) .inNamespace(namespace) @@ -91,7 +92,7 @@ private boolean findKamelet(String name, TestContext context, String ... namespa LOG.debug(String.format("Kamelet '%s' is not present in namespace '%s'", name, namespace)); } else { LOG.debug(String.format("Found Kamelet in namespace '%s'", namespace)); - LOG.debug(KubernetesSupport.yaml().dumpAsMap(kamelet)); + LOG.debug(KubernetesSupport.yaml(new KameletValuePropertyMapper()).dumpAsMap(kamelet)); } } diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyKameletBindingAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyKameletBindingAction.java new file mode 100644 index 00000000..da412cf9 --- /dev/null +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyKameletBindingAction.java @@ -0,0 +1,153 @@ +/* + * Copyright the original author or authors. + * + * Licensed 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 org.citrusframework.yaks.camelk.actions.kamelet; + +import java.util.Map; + +import org.apache.camel.v1alpha1.KameletBinding; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.ValidationException; +import org.citrusframework.yaks.YaksSettings; +import org.citrusframework.yaks.camelk.CamelKSettings; +import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBindingList; +import org.citrusframework.yaks.kubernetes.KubernetesSupport; + +import static org.citrusframework.yaks.camelk.jbang.CamelJBang.camel; + +/** + * Test action verifies Camel K binding is present in given namespace. + * + * @author Christoph Deppisch + */ +public class VerifyKameletBindingAction extends AbstractKameletAction { + + private final String bindingName; + + private final int maxAttempts; + private final long delayBetweenAttempts; + + /** + * Constructor using given builder. + * @param builder + */ + public VerifyKameletBindingAction(Builder builder) { + super("verify-binding", builder); + this.bindingName = builder.bindingName; + this.maxAttempts = builder.maxAttempts; + this.delayBetweenAttempts = builder.delayBetweenAttempts; + } + + @Override + public void doExecute(TestContext context) { + String name = context.replaceDynamicContentInString(this.bindingName); + + LOG.info(String.format("Verify binding '%s'", name)); + + if (YaksSettings.isLocal(clusterType(context))) { + verifyLocalKameletBinding(name, context); + } else { + verifyKameletBinding(namespace(context), name, context); + } + + LOG.info(String.format("Successfully verified binding '%s' - All values OK!", name)); + } + + private void verifyLocalKameletBinding(String name, TestContext context) { + Long pid = context.getVariable(name + ":pid", Long.class); + + for (int i = 0; i < maxAttempts; i++) { + Map properties = camel().get(pid); + if ((!properties.isEmpty() && properties.get("STATUS").equals("Running"))) { + LOG.info(String.format("Verified binding '%s' state 'Running' - All values OK!", name)); + return; + } + + LOG.info(String.format("Waiting for binding '%s' to be in state 'Running'- retry in %s ms", name, delayBetweenAttempts)); + try { + Thread.sleep(delayBetweenAttempts); + } catch (InterruptedException e) { + LOG.warn("Interrupted while waiting for binding", e); + } + } + + throw new ValidationException(String.format("Failed to retrieve binding '%s' in state 'Running'", name)); + } + + private void verifyKameletBinding(String namespace, String name, TestContext context) { + KameletBinding binding = null; + for (int i = 0; i < maxAttempts; i++) { + binding = getKubernetesClient().resources(KameletBinding.class, KameletBindingList.class) + .inNamespace(namespace) + .withName(name) + .get(); + + if (binding == null) { + LOG.info(String.format("Waiting for binding '%s' - retry in %s ms", name, delayBetweenAttempts)); + try { + Thread.sleep(delayBetweenAttempts); + } catch (InterruptedException e) { + LOG.warn("Interrupted while waiting for binding", e); + } + } else { + break; + } + } + + if (binding == null) { + throw new ValidationException(String.format("Failed to retrieve binding '%s' in namespace '%s'", name, namespace)); + } + + if (LOG.isDebugEnabled()) { + LOG.debug(KubernetesSupport.yaml(new KameletBindingValuePropertyMapper()).dumpAsMap(binding)); + } + } + + /** + * Action builder. + */ + public static final class Builder extends AbstractKameletAction.Builder { + + private String bindingName; + + private int maxAttempts = CamelKSettings.getMaxAttempts(); + private long delayBetweenAttempts = CamelKSettings.getDelayBetweenAttempts(); + + public Builder isAvailable() { + return this; + } + + public Builder isAvailable(String name) { + this.bindingName = name; + return this; + } + + public Builder maxAttempts(int maxAttempts) { + this.maxAttempts = maxAttempts; + return this; + } + + public Builder delayBetweenAttempts(long delayBetweenAttempts) { + this.delayBetweenAttempts = delayBetweenAttempts; + return this; + } + + @Override + public VerifyKameletBindingAction build() { + return new VerifyKameletBindingAction(this); + } + } +} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyPipeAction.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyPipeAction.java index 7df3db96..013c1ca3 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyPipeAction.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyPipeAction.java @@ -18,20 +18,18 @@ import java.util.Map; +import org.apache.camel.v1.Pipe; import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.ValidationException; import org.citrusframework.yaks.YaksSettings; import org.citrusframework.yaks.camelk.CamelKSettings; -import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBinding; -import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBindingList; -import org.citrusframework.yaks.camelk.model.Pipe; import org.citrusframework.yaks.camelk.model.PipeList; import org.citrusframework.yaks.kubernetes.KubernetesSupport; import static org.citrusframework.yaks.camelk.jbang.CamelJBang.camel; /** - * Test action verifies Camel K binding is present in given namespace. + * Test action verifies Camel K pipe is present in given namespace. * * @author Christoph Deppisch */ @@ -92,17 +90,10 @@ private void verifyLocalPipe(String name, TestContext context) { private void verifyPipe(String namespace, String name, TestContext context) { Pipe pipe = null; for (int i = 0; i < maxAttempts; i++) { - if (getApiVersion(context).equals(CamelKSettings.V1ALPHA1)) { - pipe = getKubernetesClient().resources(KameletBinding.class, KameletBindingList.class) - .inNamespace(namespace) - .withName(name) - .get(); - } else { - pipe = getKubernetesClient().resources(Pipe.class, PipeList.class) - .inNamespace(namespace) - .withName(name) - .get(); - } + pipe = getKubernetesClient().resources(Pipe.class, PipeList.class) + .inNamespace(namespace) + .withName(name) + .get(); if (pipe == null) { LOG.info(String.format("Waiting for pipe '%s' - retry in %s ms", name, delayBetweenAttempts)); @@ -121,7 +112,7 @@ private void verifyPipe(String namespace, String name, TestContext context) { } if (LOG.isDebugEnabled()) { - LOG.debug(KubernetesSupport.yaml().dumpAsMap(pipe)); + LOG.debug(KubernetesSupport.yaml(new PipeValuePropertyMapper()).dumpAsMap(pipe)); } } @@ -135,7 +126,6 @@ public static final class Builder extends AbstractKameletAction.Builder it.contains("--logging-color"))) { + // disable logging colors when writing logs to file + runArgs.add("--logging-color=false"); + } + return executeAsync(camel(runArgs.toArray(String[]::new)), outputFile); } else { return executeAsync(camel(runArgs.toArray(String[]::new))); diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/jbang/ProcessAndOutput.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/jbang/ProcessAndOutput.java index 3df20de7..473ac3b6 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/jbang/ProcessAndOutput.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/jbang/ProcessAndOutput.java @@ -86,7 +86,7 @@ private void readAllAndClose() { builder.append(line).append(System.lineSeparator()); } - if (builder.length() > 0) { + if (!builder.isEmpty()) { output += builder; } } catch (IOException e) { @@ -124,7 +124,7 @@ private void readChunk() { throw new CitrusRuntimeException("Failed to get JBang process output", e); } - if (builder.length() > 0) { + if (!builder.isEmpty()) { if (output == null) { output = builder.toString(); } else { diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/Integration.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/Integration.java deleted file mode 100644 index 61c1d393..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/Integration.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonInclude; -import io.fabric8.kubernetes.api.model.Namespaced; -import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.model.annotation.Group; -import io.fabric8.kubernetes.model.annotation.Version; -import org.citrusframework.yaks.camelk.CamelKSettings; -import org.citrusframework.yaks.camelk.CamelKSupport; - -@JsonInclude(JsonInclude.Include.NON_NULL) -@Group(CamelKSupport.CAMELK_CRD_GROUP) -@Version(CamelKSettings.API_VERSION_DEFAULT) -public class Integration extends CustomResource implements Namespaced { - - public Integration() { - super(); - this.spec = new IntegrationSpec(); - this.status = null; - } - - @Override - public String getApiVersion() { - return CamelKSupport.CAMELK_CRD_GROUP + "/" + CamelKSettings.getApiVersion(); - } - - /** - * Fluent builder - */ - public static class Builder { - private final Map traits = new LinkedHashMap<>(); - private final List resources = new ArrayList<>(); - private final List dependencies = new ArrayList<>(); - private final List configuration = new ArrayList<>(); - private String source; - private String fileName; - private String name; - - public Builder name(String name) { - this.name = name; - - if (fileName == null) { - this.fileName = name; - } - - return this; - } - - public Builder source(String source) { - this.source = source; - return this; - } - - public Builder source(String fileName, String source) { - this.source = source; - this.fileName = fileName; - return this; - } - - public Builder openApi(String fileName, String content) { - this.resources.add(new IntegrationSpec.Resource("openapi", null, fileName, content)); - return this; - } - - public Builder dependencies(List dependencies) { - this.dependencies.addAll(dependencies); - return this; - } - - public Builder traits(Map traits) { - this.traits.putAll(traits); - return this; - } - - public Builder trait(String name, IntegrationSpec.TraitConfig config) { - this.traits.put(name ,config); - return this; - } - - public Builder configuration(List configuration) { - this.configuration.addAll(configuration); - return this; - } - - public Integration build() { - Integration i = new Integration(); - i.getMetadata().setName(sanitizeIntegrationName(name)); - i.getSpec().setSources(Collections.singletonList(new IntegrationSpec.Source(fileName, source))); - - if (!dependencies.isEmpty()) { - i.getSpec().setDependencies(dependencies); - } - - if (!traits.isEmpty()) { - i.getSpec().setTraits(traits); - } - - if (!configuration.isEmpty()) { - i.getSpec().setConfiguration(configuration); - } - - if (!resources.isEmpty()) { - i.getSpec().setResources(resources); - } - - return i; - } - - private String sanitizeIntegrationName(String name) { - String sanitized; - - if (name.contains(".")) { - sanitized = name.substring(0, name.indexOf(".")); - } else { - sanitized = name; - } - - sanitized = sanitized.replaceAll("([a-z])([A-Z]+)", "$1-$2").toLowerCase(); - return sanitized.replaceAll("[^a-z0-9-]", ""); - } - } -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationList.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationList.java index 4b58dc2a..b4167a39 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationList.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationList.java @@ -17,6 +17,7 @@ package org.citrusframework.yaks.camelk.model; import io.fabric8.kubernetes.api.model.DefaultKubernetesResourceList; +import org.apache.camel.v1.Integration; /** * @author Christoph Deppisch diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationSpec.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationSpec.java deleted file mode 100644 index c6c505c0..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationSpec.java +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import io.fabric8.kubernetes.api.model.KubernetesResource; - -@JsonDeserialize(using = JsonDeserializer.None.class) -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonPropertyOrder({"replicas", "flows", "sources", "resources", "kit", "dependencies", "profile", "traits", - "configuration", "repositories", "serviceAccountName"}) -public class IntegrationSpec implements KubernetesResource { - - @JsonProperty("replicas") - private Integer replicas; - @JsonProperty("flows") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List> flows; - @JsonProperty("sources") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List sources; - @JsonProperty("resources") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List resources; - @JsonProperty("kit") - private String kit; - @JsonProperty("dependencies") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List dependencies; - @JsonProperty("profile") - private String profile; - @JsonProperty("traits") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map traits; - @JsonProperty("configuration") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List configuration; - @JsonProperty("repositories") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List repositories; - @JsonProperty("serviceAccountName") - private String serviceAccountName; - - public Integer getReplicas() { - return replicas; - } - - public void setReplicas(Integer replicas) { - this.replicas = replicas; - } - - public List> getFlows() { - return flows; - } - - public void setFlows(List> flows) { - this.flows = flows; - } - - public List getSources() { - return sources; - } - - public void setSources(List sources) { - this.sources = sources; - } - - public List getResources() { - return resources; - } - - public void setResources(List resources) { - this.resources = resources; - } - - public String getKit() { - return kit; - } - - public void setKit(String kit) { - this.kit = kit; - } - - public List getDependencies() { - return dependencies; - } - - public void setDependencies(List dependencies) { - this.dependencies = dependencies; - } - - public String getProfile() { - return profile; - } - - public void setProfile(String profile) { - this.profile = profile; - } - - public Map getTraits() { - return traits; - } - - public void setTraits(Map traits) { - this.traits = traits; - } - - public List getConfiguration() { - return configuration; - } - - public void setConfiguration(List configuration) { - this.configuration = configuration; - } - - public List getRepositories() { - return repositories; - } - - public void setRepositories(List repositories) { - this.repositories = repositories; - } - - public String getServiceAccountName() { - return serviceAccountName; - } - - public void setServiceAccountName(String serviceAccountName) { - this.serviceAccountName = serviceAccountName; - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"type", "value"}) - public static class Configuration implements KubernetesResource { - @JsonProperty("type") - private String type; - @JsonProperty("value") - private String value; - - public Configuration() { - super(); - } - - public Configuration(String type, String value) { - this.type = type; - this.value = value; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getValue() { - return value; - } - - public void setValue(String defaultValue) { - this.value = defaultValue; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"configuration"}) - public static class TraitConfig implements KubernetesResource { - @JsonProperty("configuration") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map configuration = new HashMap<>(); - - public TraitConfig() { - // default constructor - } - - public TraitConfig(String key, Object value) { - add(key, value); - } - - public Map getConfiguration() { - return configuration; - } - - public void setConfiguration(Map configuration) { - this.configuration = configuration; - } - - public void add(String key, Object value) { - this.configuration.put(key, value); - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"language", "loader", "type", "name", "path", "rawContent", "content", - "contentType", "contentRef", "contentKey", "compression", "property-names", "interceptors"}) - public static class Source extends DataSpec implements KubernetesResource { - @JsonProperty("language") - private String language; - @JsonProperty("loader") - private String loader; - @JsonProperty("type") - private String type; - @JsonProperty("interceptors") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List interceptors; - @JsonProperty("property-names") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List propertyNames; - - public Source() { - super(); - } - - public Source(String name, String content) { - super(name, content); - } - - public String getLanguage() { - return language; - } - - public void setLanguage(String language) { - this.language = language; - } - - public String getLoader() { - return loader; - } - - public void setLoader(String loader) { - this.loader = loader; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public List getInterceptors() { - return interceptors; - } - - public void setInterceptors(List interceptors) { - this.interceptors = interceptors; - } - - public List getPropertyNames() { - return propertyNames; - } - - public void setPropertyNames(List propertyNames) { - this.propertyNames = propertyNames; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"type", "mountPath", "name", "path", "rawContent", "content", - "contentType", "contentRef", "contentKey", "compression"}) - public static class Resource extends DataSpec implements KubernetesResource { - @JsonProperty("type") - private String type; - @JsonProperty("mountPath") - private String mountPath; - - public Resource() { - super(); - } - - public Resource(String type, String mountPath, String name, String content) { - super(name, content); - this.mountPath = mountPath; - this.type = type; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getMountPath() { - return mountPath; - } - - public void setMountPath(String mountPath) { - this.mountPath = mountPath; - } - } - - private static class DataSpec { - @JsonProperty("name") - private String name; - @JsonProperty("path") - private String path; - @JsonProperty("content") - private String content; - @JsonProperty("contentRef") - private String contentRef; - @JsonProperty("contentType") - private String contentType; - @JsonProperty("contentKey") - private String contentKey; - @JsonProperty("compression") - private String compression; - @JsonProperty("rawContent") - private String rawContent; - - public DataSpec() { - super(); - } - - public DataSpec(String name, String content) { - this.content = content; - this.name = name; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - public String getContentRef() { - return contentRef; - } - - public void setContentRef(String contentRef) { - this.contentRef = contentRef; - } - - public String getContentKey() { - return contentKey; - } - - public void setContentKey(String contentKey) { - this.contentKey = contentKey; - } - - public String getCompression() { - return compression; - } - - public void setCompression(String compression) { - this.compression = compression; - } - - public String getRawContent() { - return rawContent; - } - - public void setRawContent(String rawContent) { - this.rawContent = rawContent; - } - } -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationStatus.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationStatus.java deleted file mode 100644 index 22687280..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/IntegrationStatus.java +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model; - -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import io.fabric8.kubernetes.api.model.KubernetesResource; - -@JsonDeserialize(using = JsonDeserializer.None.class) -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonPropertyOrder({"phase", "digest", "image", "dependencies", "profile", "integrationKit", "kit", "lastInitTimestamp", "platform", "generatedSources", "generatedResources", - "failure", "runtimeProvider", "configuration", "conditions", "version", "replicas", "selector", "capabilities", "observedGeneration"}) -public class IntegrationStatus implements KubernetesResource { - - @JsonProperty("phase") - private String phase; - @JsonProperty("digest") - private String digest; - @JsonProperty("image") - private String image; - @JsonProperty("dependencies") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List dependencies; - @JsonProperty("profile") - private String profile; - @JsonProperty("integrationKit") - private IntegrationKit integrationKit; - @JsonProperty("kit") - private String kit; - @JsonProperty("lastInitTimestamp") - private String lastInitTimestamp; - @JsonProperty("platform") - private String platform; - @JsonProperty("generatedSources") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List generatedSources; - @JsonProperty("generatedResources") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List generatedResources; - @JsonProperty("failure") - private String failure; - @JsonProperty("runtimeVersion") - private String runtimeVersion; - @JsonProperty("runtimeProvider") - private String runtimeProvider; - @JsonProperty("configuration") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List configuration; - @JsonProperty("conditions") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List conditions; - @JsonProperty("version") - private String version; - @JsonProperty("replicas") - private int replicas; - @JsonProperty("selector") - private String selector; - @JsonProperty("capabilities") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List capabilities; - @JsonProperty("observedGeneration") - private Integer observedGeneration; - - public String getPhase() { - return phase; - } - - public void setPhase(String phase) { - this.phase = phase; - } - - public String getDigest() { - return digest; - } - - public void setDigest(String digest) { - this.digest = digest; - } - - public String getImage() { - return image; - } - - public void setImage(String image) { - this.image = image; - } - - public List getDependencies() { - return dependencies; - } - - public void setDependencies(List dependencies) { - this.dependencies = dependencies; - } - - public String getProfile() { - return profile; - } - - public void setProfile(String profile) { - this.profile = profile; - } - - @Deprecated - public String getKit() { - return kit; - } - - @Deprecated - public void setKit(String kit) { - this.kit = kit; - } - - public IntegrationKit getIntegrationKit() { - return integrationKit; - } - - public void setIntegrationKit(IntegrationKit integrationKit) { - this.integrationKit = integrationKit; - } - - public String getLastInitTimestamp() { - return lastInitTimestamp; - } - - public void setLastInitTimestamp(String lastInitTimestamp) { - this.lastInitTimestamp = lastInitTimestamp; - } - - public String getPlatform() { - return platform; - } - - public void setPlatform(String platform) { - this.platform = platform; - } - - public List getGeneratedSources() { - return generatedSources; - } - - public void setGeneratedSources(List generatedSources) { - this.generatedSources = generatedSources; - } - - public List getGeneratedResources() { - return generatedResources; - } - - public void setGeneratedResources(List generatedResources) { - this.generatedResources = generatedResources; - } - - public String getFailure() { - return failure; - } - - public void setFailure(String failure) { - this.failure = failure; - } - - public String getRuntimeVersion() { - return runtimeVersion; - } - - public void setRuntimeVersion(String runtimeVersion) { - this.runtimeVersion = runtimeVersion; - } - - public String getRuntimeProvider() { - return runtimeProvider; - } - - public void setRuntimeProvider(String runtimeProvider) { - this.runtimeProvider = runtimeProvider; - } - - public List getConfiguration() { - return configuration; - } - - public void setConfiguration(List configuration) { - this.configuration = configuration; - } - - public List getConditions() { - return conditions; - } - - public void setConditions(List conditions) { - this.conditions = conditions; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public int getReplicas() { - return replicas; - } - - public void setReplicas(int replicas) { - this.replicas = replicas; - } - - public String getSelector() { - return selector; - } - - public void setSelector(String selector) { - this.selector = selector; - } - - public List getCapabilities() { - return capabilities; - } - - public void setCapabilities(List capabilities) { - this.capabilities = capabilities; - } - - public Integer getObservedGeneration() { - return observedGeneration; - } - - public void setObservedGeneration(Integer observedGeneration) { - this.observedGeneration = observedGeneration; - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"type", "status", "lastUpdateTime", "lastTransitionTime", "reason", "message"}) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Condition implements KubernetesResource { - @JsonProperty("type") - private String type; - @JsonProperty("status") - private String status; - @JsonProperty("lastUpdateTime") - private String lastUpdateTime; - @JsonProperty("lastTransitionTime") - private String lastTransitionTime; - @JsonProperty("reason") - private String reason; - @JsonProperty("message") - private String message; - - public Condition() { - super(); - } - - public Condition(String type, String status, String reason, String message) { - this.type = type; - this.status = status; - this.reason = reason; - this.message = message; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getLastUpdateTime() { - return lastUpdateTime; - } - - public void setLastUpdateTime(String lastUpdateTime) { - this.lastUpdateTime = lastUpdateTime; - } - - public String getLastTransitionTime() { - return lastTransitionTime; - } - - public void setLastTransitionTime(String lastTransitionTime) { - this.lastTransitionTime = lastTransitionTime; - } - - public String getReason() { - return reason; - } - - public void setReason(String reason) { - this.reason = reason; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"type", "value"}) - public static class Configuration implements KubernetesResource { - @JsonProperty("type") - private String type; - @JsonProperty("value") - private String value; - - public Configuration() { - super(); - } - - public Configuration(String type, String value) { - this.type = type; - this.value = value; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getValue() { - return value; - } - - public void setValue(String defaultValue) { - this.value = value; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"language", "loader", "type", "name", "content", "contentRef", "contentKey", "compression", - "property-names", "interceptors"}) - public static class Source extends DataSpec implements KubernetesResource { - @JsonProperty("language") - private String language; - @JsonProperty("loader") - private String loader; - @JsonProperty("type") - private String type; - @JsonProperty("interceptors") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List interceptors; - @JsonProperty("property-names") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List propertyNames; - - public Source() { - super(); - } - - public Source(String name, String content) { - super(name, content); - } - - public String getLanguage() { - return language; - } - - public void setLanguage(String language) { - this.language = language; - } - - public String getLoader() { - return loader; - } - - public void setLoader(String loader) { - this.loader = loader; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public List getInterceptors() { - return interceptors; - } - - public void setInterceptors(List interceptors) { - this.interceptors = interceptors; - } - - public List getPropertyNames() { - return propertyNames; - } - - public void setPropertyNames(List propertyNames) { - this.propertyNames = propertyNames; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"type", "mountPath", "name", "content", "contentRef", "contentKey", "compression"}) - public static class Resource extends DataSpec implements KubernetesResource { - @JsonProperty("type") - private String type; - @JsonProperty("mountPath") - private String mountPath; - - public Resource() { - super(); - } - - public Resource(String type, String mountPath, String name, String content) { - super(name, content); - this.mountPath = mountPath; - this.type = type; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getMountPath() { - return mountPath; - } - - public void setMountPath(String mountPath) { - this.mountPath = mountPath; - } - } - - private static class DataSpec { - @JsonProperty("name") - private String name; - @JsonProperty("content") - private String content; - @JsonProperty("contentRef") - private String contentRef; - @JsonProperty("contentKey") - private String contentKey; - @JsonProperty("compression") - private String compression; - - public DataSpec() { - super(); - } - - public DataSpec(String name, String content) { - this.content = content; - this.name = name; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getContentRef() { - return contentRef; - } - - public void setContentRef(String contentRef) { - this.contentRef = contentRef; - } - - public String getContentKey() { - return contentKey; - } - - public void setContentKey(String contentKey) { - this.contentKey = contentKey; - } - - public String getCompression() { - return compression; - } - - public void setCompression(String compression) { - this.compression = compression; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"apiVersion", "fieldPath", "kind", "name", "namespace", "resourceVersion", "uid"}) - public static class IntegrationKit implements KubernetesResource { - @JsonProperty("apiVersion") - private String apiVersion; - @JsonProperty("fieldPath") - private String fieldPath; - @JsonProperty("kind") - private String kind; - @JsonProperty("name") - private String name; - @JsonProperty("namespace") - private String namespace; - @JsonProperty("resourceVersion") - private String resourceVersion; - @JsonProperty("uid") - private String uid; - - public IntegrationKit() { - super(); - } - - public IntegrationKit(String apiVersion, String kind, String name) { - this.apiVersion = apiVersion; - this.kind = kind; - this.name = name; - } - - public String getApiVersion() { - return apiVersion; - } - - public void setApiVersion(String apiVersion) { - this.apiVersion = apiVersion; - } - - public String getFieldPath() { - return fieldPath; - } - - public void setFieldPath(String fieldPath) { - this.fieldPath = fieldPath; - } - - public String getKind() { - return kind; - } - - public void setKind(String kind) { - this.kind = kind; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getNamespace() { - return namespace; - } - - public void setNamespace(String namespace) { - this.namespace = namespace; - } - - public String getResourceVersion() { - return resourceVersion; - } - - public void setResourceVersion(String resourceVersion) { - this.resourceVersion = resourceVersion; - } - - public String getUid() { - return uid; - } - - public void setUid(String uid) { - this.uid = uid; - } - } -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/Kamelet.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/Kamelet.java deleted file mode 100644 index 908acd84..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/Kamelet.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonInclude; -import io.fabric8.kubernetes.api.model.Namespaced; -import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.model.annotation.Group; -import io.fabric8.kubernetes.model.annotation.Version; -import org.citrusframework.yaks.camelk.CamelKSettings; -import org.citrusframework.yaks.camelk.CamelKSupport; -import org.citrusframework.yaks.kubernetes.KubernetesSupport; -import org.springframework.util.StringUtils; - -/** - * @author Christoph Deppisch - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -@Group(CamelKSupport.CAMELK_CRD_GROUP) -@Version(CamelKSettings.V1) -public class Kamelet extends CustomResource implements Namespaced { - - public Kamelet() { - super(); - this.spec = new KameletSpec(); - this.status = null; - } - - /** - * Fluent builder - */ - public static class Builder { - protected String name; - private String template; - private KameletSpec.Definition definition = new KameletSpec.Definition(); - private final Map dataTypes = new HashMap<>(); - private List dependencies = new ArrayList<>(); - private KameletSpec.Source source; - - private final Map labels = new LinkedHashMap<>(); - private final Map annotations = new LinkedHashMap<>(); - - public Builder name(String name) { - this.name = name; - definition.setTitle(StringUtils.capitalize(name)); - return this; - } - - public Builder definition(KameletSpec.Definition definition) { - this.definition = definition; - return this; - } - - public Builder source(String name, String language, String content) { - this.source = new KameletSpec.Source(name + "." + language, content); - return this; - } - - public Builder source(String name, String content) { - this.source = new KameletSpec.Source(name, content); - return this; - } - - public Builder template(String template) { - this.template = template; - return this; - } - - @Deprecated - public Builder flow(String flow) { - this.template = flow; - return this; - } - - public Builder dependencies(List dependencies) { - this.dependencies = Collections.unmodifiableList(dependencies); - return this; - } - - public Builder dataTypes(Map types) { - this.dataTypes.putAll(types); - return this; - } - - public Builder addDataType(String slot, String scheme, String format) { - if (dataTypes.containsKey(slot)) { - this.dataTypes.get(slot).getTypes().put(format, new KameletSpec.DataTypeSpec(scheme, format)); - } else { - this.dataTypes.put(slot, new KameletSpec.DataTypesSpec(format, new KameletSpec.DataTypeSpec(scheme, format))); - } - - return this; - } - - public Builder labels(Map labels) { - this.labels.putAll(labels); - return this; - } - - public Builder addLabel(String name, String value) { - this.labels.put(name, value); - return this; - } - - public Builder annotations(Map annotations) { - this.annotations.putAll(annotations); - return this; - } - - public Builder addAnnotation(String name, String value) { - this.annotations.put(name, value); - return this; - } - - public Kamelet build() { - Kamelet kamelet = new Kamelet(); - kamelet.getMetadata().setName(name); - kamelet.getSpec().setDefinition(definition); - - kamelet.getMetadata().getAnnotations().putAll(annotations); - kamelet.getMetadata().getLabels().putAll(labels); - - if (template != null && !template.isEmpty()) { - kamelet.getSpec().setTemplate(KubernetesSupport.yaml().load(template)); - } - - if (source != null) { - kamelet.getSpec().setSources(Collections.singletonList(source)); - } - - kamelet.getSpec().setDependencies(dependencies); - kamelet.getSpec().setDataTypes(dataTypes); - return kamelet; - } - } -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletList.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletList.java index d4c83877..2133a6f7 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletList.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletList.java @@ -17,6 +17,7 @@ package org.citrusframework.yaks.camelk.model; import io.fabric8.kubernetes.api.model.DefaultKubernetesResourceList; +import org.apache.camel.v1.Kamelet; /** * @author Christoph Deppisch diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletSpec.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletSpec.java deleted file mode 100644 index 6237b394..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletSpec.java +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema; -import io.fabric8.kubernetes.api.model.KubernetesResource; - -@JsonDeserialize(using = JsonDeserializer.None.class) -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonPropertyOrder({"definition", "dataTypes", "dependencies", "sources", "authorization", "flow", "template"}) -public class KameletSpec implements KubernetesResource { - - @JsonProperty("definition") - private Definition definition; - @JsonProperty("dataTypes") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map dataTypes; - @JsonProperty("dependencies") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List dependencies; - @JsonProperty("sources") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List sources; - @JsonProperty("authorization") - private AuthorizationSpec authorization; - @JsonProperty("flow") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map flow; - @JsonProperty("template") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map template; - - public Definition getDefinition() { - return definition; - } - - public void setDefinition(Definition definition) { - this.definition = definition; - } - - public List getSources() { - return sources; - } - - public void setSources(List sources) { - this.sources = sources; - } - - public AuthorizationSpec getAuthorization() { - return authorization; - } - - public void setAuthorization(AuthorizationSpec authorization) { - this.authorization = authorization; - } - - public List getDependencies() { - return dependencies; - } - - public void setDependencies(List dependencies) { - this.dependencies = dependencies; - } - - public Map getDataTypes() { - return dataTypes; - } - - public void setDataTypes(Map dataTypes) { - this.dataTypes = dataTypes; - } - - @Deprecated - public Map getFlow() { - return flow; - } - - @Deprecated - public void setFlow(Map flow) { - this.flow = flow; - } - - public Map getTemplate() { - return template; - } - - public void setTemplate(Map template) { - this.template = template; - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"name", "content"}) - public static class Source implements KubernetesResource { - @JsonProperty("content") - private String content; - @JsonProperty("name") - private String name; - - public Source() { - super(); - } - - public Source(String name, String content) { - this.content = content; - this.name = name; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"default", "types", "headers"}) - public static class DataTypesSpec implements KubernetesResource { - @JsonProperty("default") - private String defaultType; - - @JsonProperty("types") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map types = new HashMap<>(); - - @JsonProperty("headers") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map headers = new HashMap<>(); - - public DataTypesSpec() { - super(); - } - - public DataTypesSpec(String defaultType, DataTypeSpec... types) { - this.defaultType = defaultType; - for (DataTypeSpec spec : types) { - this.types.put(spec.format, spec); - } - } - - public Map getTypes() { - return types; - } - - public void setTypes(Map types) { - this.types = types; - } - - public String getDefaultType() { - return defaultType; - } - - public void setDefaultType(String defaultType) { - this.defaultType = defaultType; - } - - public Map getHeaders() { - return headers; - } - - public void setHeaders(Map headers) { - this.headers = headers; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"scheme", "format", "description", "mediaType", "headers", "dependencies", "schema"}) - public static class DataTypeSpec implements KubernetesResource { - @JsonProperty("scheme") - private String scheme; - - @JsonProperty("format") - private String format; - - @JsonProperty("description") - private String description; - - @JsonProperty("mediaType") - private String mediaType; - - @JsonProperty("headers") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map headers; - - @JsonProperty("dependencies") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List dependencies; - - @JsonProperty("schema") - private ObjectSchema schema; - - public DataTypeSpec() { - super(); - } - - public DataTypeSpec(String scheme, String format) { - this.scheme = scheme; - this.format = format; - } - - public String getScheme() { - return scheme; - } - - public void setScheme(String scheme) { - this.scheme = scheme; - } - - public String getFormat() { - return format; - } - - public void setFormat(String format) { - this.format = format; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getMediaType() { - return mediaType; - } - - public void setMediaType(String mediaType) { - this.mediaType = mediaType; - } - - public ObjectSchema getSchema() { - return schema; - } - - public void setSchema(ObjectSchema schema) { - this.schema = schema; - } - - public Map getHeaders() { - return headers; - } - - public void setHeaders(Map headers) { - this.headers = headers; - } - - public List getDependencies() { - return dependencies; - } - - public void setDependencies(List dependencies) { - this.dependencies = dependencies; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"type", "title", "description", "required", "default"}) - public static class HeaderSpec implements KubernetesResource { - @JsonProperty("type") - private String type; - - @JsonProperty("title") - private String title; - - @JsonProperty("description") - private String description; - - @JsonProperty("required") - private boolean required; - - @JsonProperty("default") - private String defaultValue; - - public HeaderSpec() { - super(); - } - - public HeaderSpec(String type, String title, boolean required, String defaultValue) { - this.type = type; - this.title = title; - this.required = required; - this.defaultValue = defaultValue; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public boolean isRequired() { - return required; - } - - public void setRequired(boolean required) { - this.required = required; - } - - public String getDefaultValue() { - return defaultValue; - } - - public void setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"title", "description", "required", "properties", "type"}) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Definition implements KubernetesResource { - @JsonProperty("title") - private String title; - @JsonProperty("description") - private String description; - @JsonProperty("type") - private String type; - @JsonProperty("required") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List required = new ArrayList<>(); - @JsonProperty("properties") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map properties = new HashMap<>(); - - public void setTitle(String title) { - this.title = title; - } - - public String getTitle() { - return title; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getDescription() { - return description; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public List getRequired() { - return required; - } - - public void setRequired(List required) { - this.required = required; - } - - public Map getProperties() { - return properties; - } - - public void setProperties(Map properties) { - this.properties = properties; - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"title", "description", "type", "default", "example"}) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class PropertyConfig implements KubernetesResource { - @JsonProperty("title") - private String title; - @JsonProperty("description") - private String description; - @JsonProperty("type") - private String type; - @JsonProperty("default") - private Object defaultValue; - @JsonProperty("example") - private Object example; - - public PropertyConfig() { - super(); - } - - public PropertyConfig(String title, String type, Object defaultValue, Object example) { - this.title = title; - this.type = type; - this.defaultValue = defaultValue; - this.example = example; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public Object getDefault() { - return defaultValue; - } - - public void setDefault(Object defaultValue) { - this.defaultValue = defaultValue; - } - - public Object getExample() { - return example; - } - - public void setExample(Object example) { - this.example = example; - } - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - public static class AuthorizationSpec implements KubernetesResource { - } -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletStatus.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletStatus.java deleted file mode 100644 index 24a22807..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/KameletStatus.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model; - -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import io.fabric8.kubernetes.api.model.KubernetesResource; - -@JsonDeserialize(using = JsonDeserializer.None.class) -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonPropertyOrder({"phase", "conditions", "properties", "observedGeneration"}) -public class KameletStatus implements KubernetesResource { - - @JsonProperty("phase") - private String phase; - @JsonProperty("conditions") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List conditions; - @JsonProperty("properties") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List properties; - @JsonProperty("observedGeneration") - private Integer observedGeneration; - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"type", "status", "lastUpdateTime", "lastTransitionTime", "reason", "message"}) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Condition implements KubernetesResource { - @JsonProperty("type") - private String type; - @JsonProperty("status") - private String status; - @JsonProperty("lastUpdateTime") - private String lastUpdateTime; - @JsonProperty("lastTransitionTime") - private String lastTransitionTime; - @JsonProperty("reason") - private String reason; - @JsonProperty("message") - private String message; - - public Condition() { - super(); - } - - public Condition(String type, String status, String reason, String message) { - this.type = type; - this.status = status; - this.reason = reason; - this.message = message; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getLastUpdateTime() { - return lastUpdateTime; - } - - public void setLastUpdateTime(String lastUpdateTime) { - this.lastUpdateTime = lastUpdateTime; - } - - public String getLastTransitionTime() { - return lastTransitionTime; - } - - public void setLastTransitionTime(String lastTransitionTime) { - this.lastTransitionTime = lastTransitionTime; - } - - public String getReason() { - return reason; - } - - public void setReason(String reason) { - this.reason = reason; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"name", "default"}) - public static class Property implements KubernetesResource { - @JsonProperty("name") - private String name; - @JsonProperty("default") - private String defaultValue; - - public Property() { - super(); - } - - public Property(String name, String defaultValue) { - this.name = name; - this.defaultValue = defaultValue; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDefaultValue() { - return defaultValue; - } - - public void setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - } - } - - public String getPhase() { - return phase; - } - - public void setPhase(String phase) { - this.phase = phase; - } - - public List getProperties() { - return properties; - } - - public void setProperties(List properties) { - this.properties = properties; - } - - public List getConditions() { - return conditions; - } - - public void setConditions(List conditions) { - this.conditions = conditions; - } - - public Integer getObservedGeneration() { - return observedGeneration; - } - - public void setObservedGeneration(Integer observedGeneration) { - this.observedGeneration = observedGeneration; - } -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/Pipe.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/Pipe.java deleted file mode 100644 index 208453df..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/Pipe.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonInclude; -import io.fabric8.kubernetes.api.model.Namespaced; -import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.model.annotation.Group; -import io.fabric8.kubernetes.model.annotation.Version; -import org.citrusframework.yaks.camelk.CamelKSettings; -import org.citrusframework.yaks.camelk.CamelKSupport; -import org.citrusframework.yaks.kubernetes.KubernetesSupport; - -/** - * @author Christoph Deppisch - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -@Group(CamelKSupport.CAMELK_CRD_GROUP) -@Version(CamelKSettings.V1) -public class Pipe extends CustomResource implements Namespaced { - - public Pipe() { - super(); - this.spec = new PipeSpec(); - this.status = null; - } - - /** - * Fluent builder - */ - public static class Builder { - protected String name; - private int replicas; - private IntegrationSpec integration; - private PipeSpec.Endpoint source; - private PipeSpec.Endpoint sink; - private final List steps = new ArrayList<>(); - - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder integration(IntegrationSpec integration) { - this.integration = integration; - return this; - } - - public Builder source(PipeSpec.Endpoint source) { - this.source = source; - return this; - } - - public Builder source(String uri) { - return source(new PipeSpec.Endpoint(uri)); - } - - public Builder source(PipeSpec.Endpoint.ObjectReference ref, String properties) { - Map props = null; - if (properties != null && !properties.isEmpty()) { - props = KubernetesSupport.yaml().load(properties); - } - - return source(new PipeSpec.Endpoint(ref, props)); - } - - public Builder sink(PipeSpec.Endpoint sink) { - this.sink = sink; - return this; - } - - public Builder sink(String uri) { - return sink(new PipeSpec.Endpoint(uri)); - } - - public Builder sink(PipeSpec.Endpoint.ObjectReference ref, String properties) { - Map props = null; - if (properties != null && !properties.isEmpty()) { - props = KubernetesSupport.yaml().load(properties); - } - - return sink(new PipeSpec.Endpoint(ref, props)); - } - - public Builder steps(PipeSpec.Endpoint... step) { - this.steps.addAll(Arrays.asList(step)); - return this; - } - - public Builder addStep(PipeSpec.Endpoint step) { - this.steps.add(step); - return this; - } - - public Builder addStep(String uri) { - return addStep(new PipeSpec.Endpoint(uri)); - } - - public Builder addStep(PipeSpec.Endpoint.ObjectReference ref, String properties) { - Map props = null; - if (properties != null && !properties.isEmpty()) { - props = KubernetesSupport.yaml().load(properties); - } - - return addStep(new PipeSpec.Endpoint(ref, props)); - } - - public Builder replicas(int replicas) { - this.replicas = replicas; - return this; - } - - public Pipe build() { - Pipe pipe = new Pipe(); - pipe.getMetadata().setName(name); - - if (replicas > 0) { - pipe.getSpec().setReplicas(replicas); - } - - if (integration != null) { - pipe.getSpec().setIntegration(integration); - } - - if (source != null) { - pipe.getSpec().setSource(source); - } - - if (sink != null) { - pipe.getSpec().setSink(sink); - } - - if (!steps.isEmpty()) { - pipe.getSpec().setSteps(steps.toArray(new PipeSpec.Endpoint[]{})); - } - - return pipe; - } - } -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeList.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeList.java index 6fc8177a..0c9cd7a9 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeList.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeList.java @@ -17,6 +17,7 @@ package org.citrusframework.yaks.camelk.model; import io.fabric8.kubernetes.api.model.DefaultKubernetesResourceList; +import org.apache.camel.v1.Pipe; /** * @author Christoph Deppisch diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeSpec.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeSpec.java deleted file mode 100644 index e70e53dc..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeSpec.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model; - -import java.util.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import io.fabric8.kubernetes.api.model.KubernetesResource; - -@JsonDeserialize(using = JsonDeserializer.None.class) -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonPropertyOrder({"integration", "replicas", "source", "steps", "sink"}) -public class PipeSpec implements KubernetesResource { - - @JsonProperty("integration") - private IntegrationSpec integration; - - @JsonProperty("source") - private Endpoint source; - - @JsonProperty("sink") - private Endpoint sink; - - @JsonProperty("steps") - private Endpoint[] steps; - - @JsonProperty("replicas") - private Integer replicas; - - public void setReplicas(Integer replicas) { - this.replicas = replicas; - } - - public Integer getReplicas() { - return replicas; - } - - public void setSource(Endpoint source) { - this.source = source; - } - - public Endpoint getSource() { - return source; - } - - public void setSink(Endpoint sink) { - this.sink = sink; - } - - public Endpoint getSink() { - return sink; - } - - public Endpoint[] getSteps() { - return steps; - } - - public void setSteps(Endpoint[] steps) { - this.steps = steps; - } - - public void setIntegration(IntegrationSpec integration) { - this.integration = integration; - } - - public IntegrationSpec getIntegration() { - return integration; - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"ref", "uri", "properties", "dataTypes"}) - public static class Endpoint implements KubernetesResource { - @JsonProperty("ref") - private ObjectReference ref; - - @JsonProperty("uri") - private String uri; - - @JsonProperty("properties") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map properties = new HashMap<>(); - - @JsonProperty("dataTypes") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private Map dataTypes = new HashMap<>(); - - public Endpoint() { - } - - public Endpoint(ObjectReference ref) { - this.ref = ref; - } - - public Endpoint(ObjectReference ref, Map properties) { - this.ref = ref; - this.properties = properties; - } - - public Endpoint(String uri) { - this.uri = uri; - } - - public ObjectReference getRef() { - return ref; - } - - public void setRef(ObjectReference ref) { - this.ref = ref; - } - - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - } - - public Map getProperties() { - return properties; - } - - public void setProperties(Map properties) { - this.properties = properties; - } - - public Map getDataTypes() { - return dataTypes; - } - - public void setDataTypes(Map dataTypes) { - this.dataTypes = dataTypes; - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"scheme", "format"}) - public static class DataTypeRef implements KubernetesResource { - @JsonProperty("scheme") - private String scheme; - - @JsonProperty("format") - private String format; - - public DataTypeRef() { - super(); - } - - public DataTypeRef(String scheme, String format) { - this.scheme = scheme; - this.format = format; - } - - public String getScheme() { - return scheme; - } - - public void setScheme(String scheme) { - this.scheme = scheme; - } - - public String getFormat() { - return format; - } - - public void setFormat(String format) { - this.format = format; - } - } - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"name", "kind", "namespace", "uid", "apiVersion", "resourceVersion", "fieldPath"}) - public static class ObjectReference implements KubernetesResource { - @JsonProperty("name") - private String name; - @JsonProperty("kind") - private String kind; - @JsonProperty("namespace") - private String namespace; - @JsonProperty("uid") - private String uid; - @JsonProperty("apiVersion") - private String apiVersion; - @JsonProperty("resourceVersion") - private String resourceVersion; - @JsonProperty("fieldPath") - private String fieldPath; - - public ObjectReference() { - super(); - } - - public ObjectReference(String apiVersion, String kind, String namespace, String name) { - this.apiVersion = apiVersion; - this.kind = kind; - this.namespace = namespace; - this.name = name; - } - - public ObjectReference(String kind, String namespace, String name) { - this.kind = kind; - this.namespace = namespace; - this.name = name; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getKind() { - return kind; - } - - public void setKind(String kind) { - this.kind = kind; - } - - public String getNamespace() { - return namespace; - } - - public void setNamespace(String namespace) { - this.namespace = namespace; - } - - public String getUid() { - return uid; - } - - public void setUid(String uid) { - this.uid = uid; - } - - public String getApiVersion() { - return apiVersion; - } - - public void setApiVersion(String apiVersion) { - this.apiVersion = apiVersion; - } - - public String getResourceVersion() { - return resourceVersion; - } - - public void setResourceVersion(String resourceVersion) { - this.resourceVersion = resourceVersion; - } - - public String getFieldPath() { - return fieldPath; - } - - public void setFieldPath(String fieldPath) { - this.fieldPath = fieldPath; - } - } - } - -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeStatus.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeStatus.java deleted file mode 100644 index 1a02880f..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/PipeStatus.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model; - -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import io.fabric8.kubernetes.api.model.KubernetesResource; - -@JsonDeserialize(using = JsonDeserializer.None.class) -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonPropertyOrder({"phase", "conditions", "observedGeneration"}) -public class PipeStatus implements KubernetesResource { - - @JsonProperty("phase") - private String phase; - @JsonProperty("conditions") - @JsonInclude(JsonInclude.Include.NON_EMPTY) - private List conditions; - @JsonProperty("observedGeneration") - private Integer observedGeneration; - - @JsonDeserialize(using = JsonDeserializer.None.class) - @JsonInclude(JsonInclude.Include.NON_NULL) - @JsonPropertyOrder({"type", "status", "lastUpdateTime", "lastTransitionTime", "reason", "message"}) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Condition implements KubernetesResource { - @JsonProperty("type") - private String type; - @JsonProperty("status") - private String status; - @JsonProperty("lastUpdateTime") - private String lastUpdateTime; - @JsonProperty("lastTransitionTime") - private String lastTransitionTime; - @JsonProperty("reason") - private String reason; - @JsonProperty("message") - private String message; - - public Condition() { - super(); - } - - public Condition(String type, String status, String reason, String message) { - this.type = type; - this.status = status; - this.reason = reason; - this.message = message; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getLastUpdateTime() { - return lastUpdateTime; - } - - public void setLastUpdateTime(String lastUpdateTime) { - this.lastUpdateTime = lastUpdateTime; - } - - public String getLastTransitionTime() { - return lastTransitionTime; - } - - public void setLastTransitionTime(String lastTransitionTime) { - this.lastTransitionTime = lastTransitionTime; - } - - public String getReason() { - return reason; - } - - public void setReason(String reason) { - this.reason = reason; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - } - - public String getPhase() { - return phase; - } - - public void setPhase(String phase) { - this.phase = phase; - } - - public List getConditions() { - return conditions; - } - - public void setConditions(List conditions) { - this.conditions = conditions; - } - - public Integer getObservedGeneration() { - return observedGeneration; - } - - public void setObservedGeneration(Integer observedGeneration) { - this.observedGeneration = observedGeneration; - } -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletBinding.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletBinding.java deleted file mode 100644 index 1fb62d0b..00000000 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletBinding.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk.model.v1alpha1; - -import com.fasterxml.jackson.annotation.JsonInclude; -import io.fabric8.kubernetes.model.annotation.Group; -import io.fabric8.kubernetes.model.annotation.Version; -import org.citrusframework.yaks.camelk.CamelKSettings; -import org.citrusframework.yaks.camelk.CamelKSupport; -import org.citrusframework.yaks.camelk.model.IntegrationSpec; -import org.citrusframework.yaks.camelk.model.Pipe; -import org.citrusframework.yaks.camelk.model.PipeSpec; - -/** - * @author Christoph Deppisch - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -@Group(CamelKSupport.CAMELK_CRD_GROUP) -@Version(CamelKSettings.V1ALPHA1) -public class KameletBinding extends Pipe { - - /** - * Fluent builder - */ - public static class Builder extends Pipe.Builder { - - Pipe.Builder delegate = new Pipe.Builder(); - - public Builder name(String name) { - this.name = name; - delegate.name(name); - return this; - } - - public Builder integration(IntegrationSpec integration) { - delegate.integration(integration); - return this; - } - - public Builder source(PipeSpec.Endpoint source) { - delegate.source(source); - return this; - } - - public Builder source(String uri) { - delegate.source(uri); - return this; - } - - public Builder source(PipeSpec.Endpoint.ObjectReference ref, String properties) { - delegate.source(ref, properties); - return this; - } - - public Builder sink(PipeSpec.Endpoint sink) { - delegate.sink(sink); - return this; - } - - public Builder sink(String uri) { - delegate.sink(uri); - return this; - } - - public Builder sink(PipeSpec.Endpoint.ObjectReference ref, String properties) { - delegate.sink(ref, properties); - return this; - } - - public Builder steps(PipeSpec.Endpoint... step) { - delegate.steps(step); - return this; - } - - public Builder addStep(PipeSpec.Endpoint step) { - delegate.addStep(step); - return this; - } - - public Builder addStep(String uri) { - delegate.addStep(new PipeSpec.Endpoint(uri)); - return this; - } - - public Builder addStep(PipeSpec.Endpoint.ObjectReference ref, String properties) { - delegate.addStep(ref, properties); - return this; - } - - public Builder replicas(int replicas) { - delegate.replicas(replicas); - return this; - } - - public Builder from(Pipe pipe) { - delegate.name(pipe.getMetadata().getName()); - delegate.source(pipe.getSpec().getSource()); - delegate.sink(pipe.getSpec().getSink()); - - if (pipe.getSpec().getSteps() != null) { - delegate.steps(pipe.getSpec().getSteps()); - } - - delegate.integration(pipe.getSpec().getIntegration()); - - if (pipe.getSpec().getReplicas() != null) { - delegate.replicas(pipe.getSpec().getReplicas()); - } - - return this; - } - - public KameletBinding build() { - Pipe b = this.delegate.build(); - - KameletBinding binding = new KameletBinding(); - binding.setMetadata(b.getMetadata()); - - binding.setSpec(b.getSpec()); - binding.setStatus(b.getStatus()); - - return binding; - } - } -} diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletBindingList.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletBindingList.java index 7ea3da3e..320d32e5 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletBindingList.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletBindingList.java @@ -17,6 +17,7 @@ package org.citrusframework.yaks.camelk.model.v1alpha1; import io.fabric8.kubernetes.api.model.DefaultKubernetesResourceList; +import org.apache.camel.v1alpha1.KameletBinding; /** * @author Christoph Deppisch diff --git a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletV1Alpha1.java b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletV1Alpha1.java index 2f56bcde..68b71fe4 100644 --- a/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletV1Alpha1.java +++ b/java/steps/yaks-camel-k/src/main/java/org/citrusframework/yaks/camelk/model/v1alpha1/KameletV1Alpha1.java @@ -16,126 +16,25 @@ package org.citrusframework.yaks.camelk.model.v1alpha1; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonInclude; -import io.fabric8.kubernetes.api.model.Namespaced; -import io.fabric8.kubernetes.model.annotation.Group; -import io.fabric8.kubernetes.model.annotation.Kind; -import io.fabric8.kubernetes.model.annotation.Version; -import org.citrusframework.yaks.camelk.CamelKSettings; -import org.citrusframework.yaks.camelk.CamelKSupport; -import org.citrusframework.yaks.camelk.model.Kamelet; -import org.citrusframework.yaks.camelk.model.KameletSpec; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.apache.camel.v1alpha1.Kamelet; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.yaks.kubernetes.KubernetesSupport; /** * @author Christoph Deppisch */ -@JsonInclude(JsonInclude.Include.NON_NULL) -@Group(CamelKSupport.CAMELK_CRD_GROUP) -@Kind("Kamelet") -@Version(CamelKSettings.V1ALPHA1) -public class KameletV1Alpha1 extends Kamelet implements Namespaced { - - public KameletV1Alpha1() { - super(); - this.spec = new KameletSpec(); - this.status = null; - } - - /** - * Fluent builder - */ - public static class Builder extends Kamelet.Builder { - - Kamelet.Builder delegate = new Kamelet.Builder(); - - public Builder name(String name) { - this.name = name; - delegate.name(name); - return this; - } - - public Builder definition(KameletSpec.Definition definition) { - delegate.definition(definition); - return this; - } - - public Builder source(String name, String language, String content) { - delegate.source(name, language, content); - return this; - } - - public Builder source(String name, String content) { - delegate.source(name, content); - return this; - } - - public Builder template(String template) { - delegate.template(template); - return this; - } - - @Deprecated - public Builder flow(String flow) { - delegate.flow(flow); - return this; - } - - public Builder dependencies(List dependencies) { - delegate.dependencies(dependencies); - return this; - } - - public Builder dataTypes(Map types) { - delegate.dataTypes(types); - return this; - } - - public Builder addDataType(String slot, String scheme, String format) { - delegate.addDataType(slot, scheme, format); - return this; - } - - public Builder from(Kamelet kamelet) { - delegate.name(kamelet.getMetadata().getName()); - - delegate.annotations(kamelet.getMetadata().getAnnotations()); - delegate.labels(kamelet.getMetadata().getLabels()); - - if (kamelet.getSpec() != null) { - if (kamelet.getSpec().getDefinition() != null) { - delegate.definition(kamelet.getSpec().getDefinition()); - } - - if (kamelet.getSpec().getSources() != null && !kamelet.getSpec().getSources().isEmpty()) { - KameletSpec.Source source = kamelet.getSpec().getSources().get(0); - delegate.source(source.getName(), source.getContent()); - } - - if (kamelet.getSpec().getDependencies() != null) { - delegate.dependencies(kamelet.getSpec().getDependencies()); - } - - if (kamelet.getSpec().getDataTypes() != null) { - delegate.dataTypes(kamelet.getSpec().getDataTypes()); - } - } - - return this; - } - - public KameletV1Alpha1 build() { - Kamelet k = delegate.build(); +public class KameletV1Alpha1 extends Kamelet { - KameletV1Alpha1 kamelet = new KameletV1Alpha1(); - kamelet.setMetadata(k.getMetadata()); + public static KameletV1Alpha1 from(org.apache.camel.v1.Kamelet kamelet) { + try { + String kameletJson = KubernetesSupport.json().writerFor(org.apache.camel.v1.Kamelet.class).writeValueAsString(kamelet); - kamelet.setSpec(k.getSpec()); - kamelet.setStatus(k.getStatus()); + kameletJson = kameletJson.replaceAll("v1", "v1alpha1"); - return kamelet; + return KubernetesSupport.json().readValue(kameletJson, KameletV1Alpha1.class); + } catch (JsonProcessingException e) { + throw new CitrusRuntimeException("Failed to convert Kamelet to version 'v1alpha1'", e); } } } diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/CamelKTestSteps.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/CamelKTestSteps.java index 153554a4..fc2eaa9d 100644 --- a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/CamelKTestSteps.java +++ b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/CamelKTestSteps.java @@ -18,14 +18,17 @@ import java.util.Collections; -import org.citrusframework.Citrus; -import org.citrusframework.annotations.CitrusFramework; import io.cucumber.java.Before; import io.cucumber.java.Scenario; import io.cucumber.java.en.Given; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodBuilder; import io.fabric8.kubernetes.client.KubernetesClient; +import org.apache.camel.v1.Integration; +import org.apache.camel.v1.IntegrationBuilder; +import org.citrusframework.Citrus; +import org.citrusframework.annotations.CitrusFramework; +import org.citrusframework.yaks.camelk.model.IntegrationList; import org.citrusframework.yaks.kubernetes.KubernetesSupport; /** @@ -52,6 +55,17 @@ public void createIntegrationPod(String integrationName) { @Given("^Camel K integration pod ([a-z0-9-]+) in phase (Running|Stopped)$") public void createIntegrationPod(String integrationName, String phase) { + Integration integration = new IntegrationBuilder() + .withNewMetadata() + .withName(integrationName) + .endMetadata() + .withNewStatus() + .withPhase(phase) + .endStatus() + .build(); + + k8sClient.resources(Integration.class, IntegrationList.class).inNamespace(CamelKSettings.getNamespace()).resource(integration).create(); + Pod pod = new PodBuilder() .withNewMetadata() .withName(integrationName) diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/IntegrationBuilderTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/IntegrationBuilderTest.java deleted file mode 100644 index 712961a4..00000000 --- a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/IntegrationBuilderTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.citrusframework.spi.Resources; -import org.citrusframework.util.FileUtils; -import org.citrusframework.yaks.camelk.model.Integration; -import org.citrusframework.yaks.camelk.model.IntegrationSpec; -import org.citrusframework.yaks.kubernetes.KubernetesSupport; -import org.junit.Assert; -import org.junit.Test; -import org.springframework.util.StringUtils; - -public class IntegrationBuilderTest { - - @Test - public void shouldSanitizeIntegrationNames() { - Integration i = new Integration.Builder() - .name("SomeCamelCaseSource.java") - .source("from(\"timer:x\").log('${body}')") - .build(); - - Assert.assertEquals(i.getMetadata().getName(), "some-camel-case-source"); - Assert.assertEquals(i.getSpec().getSources().get(0).getName(), "SomeCamelCaseSource.java"); - - i = new Integration.Builder() - .name("ThisIsATest%&/$_!.java") - .source("from(\"timer:x\").log('${body}')") - .build(); - - Assert.assertEquals(i.getMetadata().getName(), "this-is-atest"); - } - - @Test - public void shouldSupportExplicitIntegrationNames() { - Integration i = new Integration.Builder() - .name("some-integration") - .source("SomeCamelCaseSource.java", "from(\"timer:x\").log('${body}')") - .build(); - - Assert.assertEquals(i.getMetadata().getName(), "some-integration"); - Assert.assertEquals(i.getSpec().getSources().get(0).getName(), "SomeCamelCaseSource.java"); - - i = new Integration.Builder() - .name("ThisIsATest%&/$_!.java") - .source("from(\"timer:x\").log('${body}')") - .build(); - - Assert.assertEquals(i.getMetadata().getName(), "this-is-atest"); - } - - @Test - public void buildComplexIntegrationTest() throws IOException { - Map traits = new HashMap<>(); - IntegrationSpec.TraitConfig quarkus = new IntegrationSpec.TraitConfig("enabled", true); - quarkus.add("native", "true"); - traits.put("quarkus", quarkus); - traits.put("route", new IntegrationSpec.TraitConfig("enabled", true)); - - IntegrationSpec.TraitConfig builder = new IntegrationSpec.TraitConfig("properties", Arrays.asList("quarkus.foo=bar", "quarkus.verbose=true")); - builder.add("verbose", true); - traits.put("builder", builder); - - List dependencies = Arrays.asList("mvn:fake.dependency:id:version-1", "camel:jackson"); - Integration i = new Integration.Builder() - .name("bar.groovy") - .source("from(\"timer:x\").log('${body}')") - .traits(traits) - .dependencies(dependencies) - .build(); - - final String json = KubernetesSupport.json().writeValueAsString(i); - Assert.assertEquals(StringUtils.trimAllWhitespace( - FileUtils.readToString(Resources.create("integration.json", IntegrationBuilderTest.class))), json); - } - - @Test - public void buildOpenApiIntegrationTest() throws IOException { - Integration i = new Integration.Builder() - .name("openapi.groovy") - .source("from(\"timer:x\").log('${body}')") - .openApi("openapi.yaml", FileUtils.readToString(FileUtils.getFileResource("classpath:openapi.yaml"))) - .build(); - - final String json = StringUtils.trimAllWhitespace(KubernetesSupport.json().writeValueAsString(i)); - Assert.assertEquals(StringUtils.trimAllWhitespace( - FileUtils.readToString(Resources.create("integration-api.json", IntegrationBuilderTest.class))), json); - } -} diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/KameletBuilderTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/KameletBuilderTest.java deleted file mode 100644 index e96049b0..00000000 --- a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/KameletBuilderTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk; - -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.citrusframework.spi.Resources; -import org.citrusframework.util.FileUtils; -import org.citrusframework.yaks.camelk.model.Kamelet; -import org.citrusframework.yaks.camelk.model.KameletSpec; -import org.citrusframework.yaks.kubernetes.KubernetesSupport; -import org.junit.Assert; -import org.junit.Test; -import org.springframework.util.StringUtils; - -public class KameletBuilderTest { - - @Test - public void buildComplexKamelet() throws IOException { - Map dataTypes = new HashMap<>(); - dataTypes.put("out", new KameletSpec.DataTypesSpec("text", - new KameletSpec.DataTypeSpec("camel", "binary"), - new KameletSpec.DataTypeSpec("camel", "text"))); - - KameletSpec.Definition definition = new KameletSpec.Definition(); - definition.setTitle("Timer Source"); - definition.getProperties().put("period", new KameletSpec.Definition.PropertyConfig("Period", "integer", 1000, null)); - definition.getProperties().put("message", new KameletSpec.Definition.PropertyConfig("Message", "string", null, "hello world")); - definition.getRequired().add("message"); - - Kamelet kamelet = new Kamelet.Builder() - .name("time-source") - .addLabel(KameletSettings.KAMELET_TYPE_LABEL, "source") - .definition(definition) - .dataTypes(dataTypes) - .dependencies(Collections.singletonList("mvn:fake.dependency:id:version-1")) - .template("from:\n" + - " uri: timer:tick\n" + - " parameters:\n" + - " period: \"#property:period\"\n" + - " steps:\n" + - " - set-body:\n" + - " constant: \"{{message}}\"\n" + - " - to: \"kamelet:sink\"") - .build(); - - final String json = KubernetesSupport.json().writeValueAsString(kamelet); - Assert.assertEquals(StringUtils.trimAllWhitespace( - FileUtils.readToString(Resources.create("kamelet.json", KameletBuilderTest.class))), - StringUtils.trimAllWhitespace(json)); - } - - @Test - public void shouldDeserializeKamelet() throws IOException { - Kamelet deserialized = new ObjectMapper().readValue( - FileUtils.readToString(Resources.create("timer-source.kamelet.json")), Kamelet.class); - - Assert.assertNull(deserialized.getSpec().getFlow()); - Assert.assertNotNull(deserialized.getSpec().getTemplate()); - Assert.assertEquals(1L, deserialized.getSpec().getTemplate().size()); - } -} diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/PipeBuilderTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/PipeBuilderTest.java deleted file mode 100644 index 89fa0977..00000000 --- a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/PipeBuilderTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed 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 org.citrusframework.yaks.camelk; - -import java.io.IOException; - -import org.citrusframework.spi.Resources; -import org.citrusframework.util.FileUtils; -import org.citrusframework.yaks.camelk.model.Pipe; -import org.citrusframework.yaks.camelk.model.PipeSpec; -import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBinding; -import org.citrusframework.yaks.kafka.KafkaSettings; -import org.citrusframework.yaks.kubernetes.KubernetesSupport; -import org.junit.Assert; -import org.junit.Test; -import org.springframework.util.StringUtils; - -public class PipeBuilderTest { - - @Test - public void buildComplexBinding() throws IOException { - PipeSpec.Endpoint.ObjectReference sourceRef = new PipeSpec.Endpoint.ObjectReference(); - sourceRef.setName("timer-source"); - sourceRef.setKind("Kamelet"); - sourceRef.setNamespace(CamelKSettings.getNamespace()); - - PipeSpec.Endpoint source = new PipeSpec.Endpoint(sourceRef); - source.getProperties().put("message", "Hello World"); - source.getDataTypes().put("out", new PipeSpec.Endpoint.DataTypeRef("camel", "string")); - - PipeSpec.Endpoint.ObjectReference sinkRef = new PipeSpec.Endpoint.ObjectReference(); - sinkRef.setName("hello-topic"); - sinkRef.setKind("KafkaTopic"); - sinkRef.setNamespace(KafkaSettings.getNamespace()); - - PipeSpec.Endpoint sink = new PipeSpec.Endpoint(sinkRef); - - KameletBinding pipe = new KameletBinding.Builder() - .name("time-source-kafka") - .source(source) - .sink(sink) - .build(); - - final String json = KubernetesSupport.json().writeValueAsString(pipe); - Assert.assertEquals(StringUtils.trimAllWhitespace( - FileUtils.readToString(Resources.create("kamelet-binding.json", PipeBuilderTest.class))), - StringUtils.trimAllWhitespace(json)); - } - - @Test - public void buildComplexPipe() throws IOException { - PipeSpec.Endpoint.ObjectReference sourceRef = new PipeSpec.Endpoint.ObjectReference(); - sourceRef.setName("timer-source"); - sourceRef.setKind("Kamelet"); - sourceRef.setNamespace(CamelKSettings.getNamespace()); - - PipeSpec.Endpoint source = new PipeSpec.Endpoint(sourceRef); - source.getProperties().put("message", "Hello World"); - source.getDataTypes().put("out", new PipeSpec.Endpoint.DataTypeRef("camel", "string")); - - PipeSpec.Endpoint.ObjectReference sinkRef = new PipeSpec.Endpoint.ObjectReference(); - sinkRef.setName("hello-topic"); - sinkRef.setKind("KafkaTopic"); - sinkRef.setNamespace(KafkaSettings.getNamespace()); - - PipeSpec.Endpoint sink = new PipeSpec.Endpoint(sinkRef); - - Pipe pipe = new Pipe.Builder() - .name("time-source-kafka") - .source(source) - .sink(sink) - .build(); - - final String json = KubernetesSupport.json().writeValueAsString(pipe); - Assert.assertEquals(StringUtils.trimAllWhitespace( - FileUtils.readToString(Resources.create("pipe.json", PipeBuilderTest.class))), - StringUtils.trimAllWhitespace(json)); - } -} diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/integration/CreateIntegrationActionTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/integration/CreateIntegrationActionTest.java index cdc092cd..0d5aae00 100644 --- a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/integration/CreateIntegrationActionTest.java +++ b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/integration/CreateIntegrationActionTest.java @@ -16,23 +16,21 @@ package org.citrusframework.yaks.camelk.actions.integration; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -import org.citrusframework.context.TestContext; -import org.citrusframework.context.TestContextFactory; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesCrudDispatcher; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import io.fabric8.mockwebserver.Context; import okhttp3.mockwebserver.MockWebServer; +import org.apache.camel.v1.Integration; +import org.citrusframework.context.TestContext; +import org.citrusframework.context.TestContextFactory; import org.citrusframework.yaks.YaksClusterType; import org.citrusframework.yaks.camelk.jbang.ProcessAndOutput; -import org.citrusframework.yaks.camelk.model.Integration; import org.citrusframework.yaks.kubernetes.KubernetesSettings; import org.junit.Assert; import org.junit.Test; @@ -63,22 +61,20 @@ public void shouldCreateIntegrationWithTraits() { .client(kubernetesClient) .integration("helloworld") .source("from('timer:tick?period=1000').setBody().constant('Hello world from Camel K!').to('log:info')") - .traits("quarkus.enabled=true,quarkus.native=true,route.enabled=true,openapi.configmaps=[spec]") + .traits("quarkus.enabled=true,quarkus.nativeBaseImage=java-native,route.enabled=true,openapi.configmaps=[spec]") .build(); action.execute(context); Integration integration = kubernetesClient.resources(Integration.class).inNamespace(KubernetesSettings.getNamespace()).withName("helloworld").get(); - Assert.assertTrue(integration.getSpec().getTraits().containsKey("quarkus")); - Assert.assertEquals(2, integration.getSpec().getTraits().get("quarkus").getConfiguration().size()); - Assert.assertEquals(true, integration.getSpec().getTraits().get("quarkus").getConfiguration().get("enabled")); - Assert.assertEquals("true", integration.getSpec().getTraits().get("quarkus").getConfiguration().get("native")); - Assert.assertTrue(integration.getSpec().getTraits().containsKey("route")); - Assert.assertEquals(1, integration.getSpec().getTraits().get("route").getConfiguration().size()); - Assert.assertEquals(true, integration.getSpec().getTraits().get("route").getConfiguration().get("enabled")); - Assert.assertTrue(integration.getSpec().getTraits().containsKey("openapi")); - Assert.assertEquals(1, integration.getSpec().getTraits().get("openapi").getConfiguration().size()); - Assert.assertEquals(Collections.singletonList("spec"), integration.getSpec().getTraits().get("openapi").getConfiguration().get("configmaps")); + Assert.assertNotNull(integration.getSpec().getTraits().getQuarkus()); + Assert.assertTrue(integration.getSpec().getTraits().getQuarkus().getEnabled()); + Assert.assertEquals("java-native", integration.getSpec().getTraits().getQuarkus().getNativeBaseImage()); + Assert.assertNotNull(integration.getSpec().getTraits().getRoute()); + Assert.assertTrue(integration.getSpec().getTraits().getRoute().getEnabled()); + Assert.assertNotNull(integration.getSpec().getTraits().getOpenapi()); + Assert.assertEquals(1L, integration.getSpec().getTraits().getOpenapi().getConfigmaps().size()); + Assert.assertEquals("spec", integration.getSpec().getTraits().getOpenapi().getConfigmaps().get(0)); } @Test @@ -88,21 +84,21 @@ public void shouldCreateIntegrationWithTraitModeline() { .integration("foo") .fileName("foo.groovy") .source("// camel-k: trait=quarkus.enabled=true\n" + - "// camel-k: trait=quarkus.native=true\n" + + "// camel-k: trait=quarkus.nativeBaseImage=native-java\n" + "// camel-k: trait=route.enabled=true\n" + + "// camel-k: trait=container.port=8443\n" + "from('timer:tick?period=1000').setBody().constant('Hello world from Camel K!').to('log:info')") .build(); action.execute(context); Integration integration = kubernetesClient.resources(Integration.class).inNamespace(KubernetesSettings.getNamespace()).withName("foo").get(); - Assert.assertTrue(integration.getSpec().getTraits().containsKey("quarkus")); - Assert.assertEquals(2, integration.getSpec().getTraits().get("quarkus").getConfiguration().size()); - Assert.assertEquals(true, integration.getSpec().getTraits().get("quarkus").getConfiguration().get("enabled")); - Assert.assertEquals("true", integration.getSpec().getTraits().get("quarkus").getConfiguration().get("native")); - Assert.assertTrue(integration.getSpec().getTraits().containsKey("route")); - Assert.assertEquals(1, integration.getSpec().getTraits().get("route").getConfiguration().size()); - Assert.assertEquals(true, integration.getSpec().getTraits().get("route").getConfiguration().get("enabled")); + Assert.assertNotNull(integration.getSpec().getTraits().getQuarkus()); + Assert.assertTrue(integration.getSpec().getTraits().getQuarkus().getEnabled()); + Assert.assertEquals("native-java", integration.getSpec().getTraits().getQuarkus().getNativeBaseImage()); + Assert.assertNotNull(integration.getSpec().getTraits().getRoute()); + Assert.assertTrue(integration.getSpec().getTraits().getRoute().getEnabled()); + Assert.assertEquals(8443L, integration.getSpec().getTraits().getContainer().getPort().longValue()); } @Test @@ -119,11 +115,8 @@ public void shouldCreateIntegrationWithBuildProperties() { action.execute(context); Integration integration = kubernetesClient.resources(Integration.class).inNamespace(KubernetesSettings.getNamespace()).withName("helloworld").get(); - Assert.assertEquals(1, integration.getSpec().getTraits().size()); - Assert.assertTrue(integration.getSpec().getTraits().containsKey("builder")); - Assert.assertEquals(1, integration.getSpec().getTraits().get("builder").getConfiguration().size()); - Assert.assertEquals(ArrayList.class, integration.getSpec().getTraits().get("builder").getConfiguration().get("properties").getClass()); - List values = (List) integration.getSpec().getTraits().get("builder").getConfiguration().get("properties"); + Assert.assertNotNull(integration.getSpec().getTraits().getBuilder()); + List values = integration.getSpec().getTraits().getBuilder().getProperties(); Assert.assertEquals(2, values.size()); Assert.assertEquals("quarkus.foo=bar", values.get(0)); Assert.assertEquals("quarkus.verbose=true", values.get(1)); @@ -143,16 +136,55 @@ public void shouldCreateIntegrationWithBuildPropertyModeline() { action.execute(context); Integration integration = kubernetesClient.resources(Integration.class).inNamespace(KubernetesSettings.getNamespace()).withName("foo").get(); - Assert.assertEquals(1, integration.getSpec().getTraits().size()); - Assert.assertTrue(integration.getSpec().getTraits().containsKey("builder")); - Assert.assertEquals(1, integration.getSpec().getTraits().get("builder").getConfiguration().size()); - Assert.assertEquals(ArrayList.class, integration.getSpec().getTraits().get("builder").getConfiguration().get("properties").getClass()); - List values = (List) integration.getSpec().getTraits().get("builder").getConfiguration().get("properties"); + Assert.assertNotNull(integration.getSpec().getTraits().getBuilder()); + List values = integration.getSpec().getTraits().getBuilder().getProperties(); Assert.assertEquals(2, values.size()); Assert.assertEquals("quarkus.foo=bar", values.get(0)); Assert.assertEquals("quarkus.verbose=true", values.get(1)); } + @Test + public void shouldCreateIntegrationWithEnvVars() { + CreateIntegrationAction action = new CreateIntegrationAction.Builder() + .client(kubernetesClient) + .integration("helloworld") + .fileName("helloworld.groovy") + .source("from('timer:tick?period=1000').setBody().constant('Hello world from Camel K!').to('log:info')") + .envVar("QUARKUS_FOO", "bar") + .envVar("QUARKUS_VERBOSE", "true") + .build(); + + action.execute(context); + + Integration integration = kubernetesClient.resources(Integration.class).inNamespace(KubernetesSettings.getNamespace()).withName("helloworld").get(); + Assert.assertNotNull(integration.getSpec().getTraits().getEnvironment()); + List values = integration.getSpec().getTraits().getEnvironment().getVars(); + Assert.assertEquals(2, values.size()); + Assert.assertEquals("QUARKUS_FOO=bar", values.get(0)); + Assert.assertEquals("QUARKUS_VERBOSE=true", values.get(1)); + } + + @Test + public void shouldCreateIntegrationWithEnvVarModeline() { + CreateIntegrationAction action = new CreateIntegrationAction.Builder() + .client(kubernetesClient) + .integration("foo") + .fileName("foo.groovy") + .source("// camel-k: env=QUARKUS_FOO=bar\n" + + "// camel-k: env=QUARKUS_VERBOSE=true\n" + + "from('timer:tick?period=1000').setBody().constant('Hello world from Camel K!').to('log:info')") + .build(); + + action.execute(context); + + Integration integration = kubernetesClient.resources(Integration.class).inNamespace(KubernetesSettings.getNamespace()).withName("foo").get(); + Assert.assertNotNull(integration.getSpec().getTraits().getEnvironment()); + List values = integration.getSpec().getTraits().getEnvironment().getVars(); + Assert.assertEquals(2, values.size()); + Assert.assertEquals("QUARKUS_FOO=bar", values.get(0)); + Assert.assertEquals("QUARKUS_VERBOSE=true", values.get(1)); + } + @Test public void shouldCreateIntegrationWithConfigModeline() { CreateIntegrationAction action = new CreateIntegrationAction.Builder() @@ -175,7 +207,7 @@ public void shouldCreateIntegrationWithConfigModeline() { } @Test - public void shouldCreateLocalJBangIntegration() { + public void shouldCreateLocalIntegration() { camel().version(); CreateIntegrationAction action = new CreateIntegrationAction.Builder() .client(kubernetesClient) diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/CreateKameletBindingActionTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/CreateKameletBindingActionTest.java new file mode 100644 index 00000000..cfa0ae4f --- /dev/null +++ b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/CreateKameletBindingActionTest.java @@ -0,0 +1,122 @@ +/* + * Copyright the original author or authors. + * + * Licensed 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 org.citrusframework.yaks.camelk.actions.kamelet; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesCrudDispatcher; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import io.fabric8.mockwebserver.Context; +import okhttp3.mockwebserver.MockWebServer; +import org.apache.camel.v1alpha1.KameletBinding; +import org.citrusframework.context.TestContext; +import org.citrusframework.context.TestContextFactory; +import org.citrusframework.spi.Resources; +import org.citrusframework.yaks.YaksClusterType; +import org.citrusframework.yaks.camelk.CamelKSettings; +import org.citrusframework.yaks.camelk.actions.integration.CreateIntegrationActionTest; +import org.citrusframework.yaks.kubernetes.KubernetesSettings; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.awaitility.Awaitility.await; +import static org.citrusframework.yaks.camelk.jbang.CamelJBang.camel; + +public class CreateKameletBindingActionTest { + + /** Logger */ + private static final Logger LOG = LoggerFactory.getLogger(CreateIntegrationActionTest.class); + + private final KubernetesMockServer k8sServer = new KubernetesMockServer(new Context(), new MockWebServer(), + new HashMap<>(), new KubernetesCrudDispatcher(), false); + + private final KubernetesClient kubernetesClient = k8sServer.createClient(); + + private final TestContext context = TestContextFactory.newInstance().getObject(); + + @BeforeClass + public static void setup() { + camel().version(); + } + + @Test + public void shouldCreateBinding() { + CreateKameletBindingAction action = new CreateKameletBindingAction.Builder() + .client(kubernetesClient) + .apiVersion(CamelKSettings.V1ALPHA1) + .binding("kafka-source-binding") + .resource(Resources.fromClasspath("kafka-source-binding.yaml")) + .build(); + + context.setVariable("YAKS_NAMESPACE", "default"); + context.setVariable("bootstrap.server.host", "my-cluster-kafka-bootstrap"); + context.setVariable("bootstrap.server.port", "9092"); + context.setVariable("topic", "my-topic"); + + action.execute(context); + + KameletBinding binding = kubernetesClient.resources(KameletBinding.class).inNamespace(KubernetesSettings.getNamespace()).withName("kafka-source-binding").get(); + Assert.assertNotNull(binding.getSpec().getSource().getRef()); + Assert.assertEquals("kafka-source", binding.getSpec().getSource().getRef().getName()); + Assert.assertNotNull(binding.getSpec().getSource().getProperties()); + Assert.assertEquals(6L, binding.getSpec().getSource().getProperties().getAdditionalProperties().size()); + Assert.assertNotNull(binding.getSpec().getSink().getUri()); + } + + @Test + public void shouldCreateLocalBinding() { + System.setProperty("yaks.jbang.camel.dump.integration.output", "true"); + + CreateKameletBindingAction action = new CreateKameletBindingAction.Builder() + .client(kubernetesClient) + .apiVersion(CamelKSettings.V1ALPHA1) + .binding("timer-to-log-binding") + .clusterType(YaksClusterType.LOCAL) + .resource(Resources.fromClasspath("timer-to-log-binding.yaml")) + .build(); + + action.execute(context); + + Assert.assertNotNull(context.getVariable("timer-to-log-binding:pid")); + + Long pid = context.getVariable("timer-to-log-binding:pid", Long.class); + + try { + await().atMost(30000L, TimeUnit.MILLISECONDS).until(() -> { + Map integration = camel().get(pid); + + if (integration.isEmpty() || integration.get("STATUS").equals("Starting")) { + LOG.info("Waiting for Camel integration to start ..."); + return false; + } + + Assert.assertEquals("timer-to-log-binding", integration.get("NAME")); + Assert.assertEquals("Running", integration.get("STATUS")); + + return true; + }); + } finally { + camel().stop(pid); + } + } +} diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/CreatePipeActionTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/CreatePipeActionTest.java index 7bdd6e38..9a936464 100644 --- a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/CreatePipeActionTest.java +++ b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/CreatePipeActionTest.java @@ -20,19 +20,18 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import org.citrusframework.context.TestContext; -import org.citrusframework.context.TestContextFactory; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesCrudDispatcher; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import io.fabric8.mockwebserver.Context; import okhttp3.mockwebserver.MockWebServer; +import org.apache.camel.v1.Pipe; +import org.citrusframework.context.TestContext; +import org.citrusframework.context.TestContextFactory; import org.citrusframework.spi.Resources; import org.citrusframework.yaks.YaksClusterType; import org.citrusframework.yaks.camelk.CamelKSettings; import org.citrusframework.yaks.camelk.actions.integration.CreateIntegrationActionTest; -import org.citrusframework.yaks.camelk.model.v1alpha1.KameletBinding; -import org.citrusframework.yaks.camelk.model.Pipe; import org.citrusframework.yaks.kubernetes.KubernetesSettings; import org.junit.Assert; import org.junit.BeforeClass; @@ -61,41 +60,22 @@ public static void setup() { } @Test - public void shouldCreateBinding() { - CreatePipeAction action = new CreatePipeAction.Builder() - .client(kubernetesClient) - .apiVersion(CamelKSettings.V1ALPHA1) - .binding("kafka-source-binding") - .resource(Resources.fromClasspath("kafka-source-binding.yaml")) - .build(); - - context.setVariable("YAKS_NAMESPACE", "default"); - context.setVariable("bootstrap.server.host", "my-cluster-kafka-bootstrap"); - context.setVariable("bootstrap.server.port", "9092"); - context.setVariable("topic", "my-topic"); - - action.execute(context); + public void shouldCreateLocalPipe() { + System.setProperty("yaks.jbang.camel.dump.integration.output", "true"); - KameletBinding binding = kubernetesClient.resources(KameletBinding.class).inNamespace(KubernetesSettings.getNamespace()).withName("kafka-source-binding").get(); - Assert.assertNotNull(binding.getSpec().getSource().getRef()); - Assert.assertNotNull(binding.getSpec().getSink().getUri()); - } - - @Test - public void shouldCreateLocalJBangBinding() { CreatePipeAction action = new CreatePipeAction.Builder() .client(kubernetesClient) - .apiVersion(CamelKSettings.V1ALPHA1) - .binding("timer-to-log-binding") + .apiVersion(CamelKSettings.V1) + .pipe("timer-to-log-pipe") .clusterType(YaksClusterType.LOCAL) - .resource(Resources.fromClasspath("timer-to-log-binding.yaml")) + .resource(Resources.fromClasspath("timer-to-log-pipe.yaml")) .build(); action.execute(context); - Assert.assertNotNull(context.getVariable("timer-to-log-binding:pid")); + Assert.assertNotNull(context.getVariable("timer-to-log-pipe:pid")); - Long pid = context.getVariable("timer-to-log-binding:pid", Long.class); + Long pid = context.getVariable("timer-to-log-pipe:pid", Long.class); try { await().atMost(30000L, TimeUnit.MILLISECONDS).until(() -> { @@ -106,7 +86,7 @@ public void shouldCreateLocalJBangBinding() { return false; } - Assert.assertEquals("timer-to-log-binding", integration.get("NAME")); + Assert.assertEquals("timer-to-log-pipe", integration.get("NAME")); Assert.assertEquals("Running", integration.get("STATUS")); return true; @@ -135,6 +115,9 @@ public void shouldCreatePipe() { Pipe pipe = kubernetesClient.resources(Pipe.class).inNamespace(KubernetesSettings.getNamespace()).withName("kafka-source-pipe").get(); Assert.assertNotNull(pipe); Assert.assertNotNull(pipe.getSpec().getSource().getRef()); + Assert.assertEquals("kafka-source", pipe.getSpec().getSource().getRef().getName()); + Assert.assertNotNull(pipe.getSpec().getSource().getProperties()); + Assert.assertEquals(6L, pipe.getSpec().getSource().getProperties().getAdditionalProperties().size()); Assert.assertNotNull(pipe.getSpec().getSink().getUri()); } } diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletBindingActionTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletBindingActionTest.java new file mode 100644 index 00000000..adacd633 --- /dev/null +++ b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/DeleteKameletBindingActionTest.java @@ -0,0 +1,103 @@ +/* + * Copyright the original author or authors. + * + * Licensed 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 org.citrusframework.yaks.camelk.actions.kamelet; + + +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.concurrent.TimeUnit; + +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesCrudDispatcher; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import io.fabric8.mockwebserver.Context; +import okhttp3.mockwebserver.MockWebServer; +import org.citrusframework.context.TestContext; +import org.citrusframework.context.TestContextFactory; +import org.citrusframework.yaks.YaksClusterType; +import org.citrusframework.yaks.camelk.CamelKSettings; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.core.io.ClassPathResource; + +import static org.awaitility.Awaitility.await; +import static org.citrusframework.yaks.camelk.jbang.CamelJBang.camel; + +public class DeleteKameletBindingActionTest { + + private final KubernetesMockServer k8sServer = new KubernetesMockServer(new Context(), new MockWebServer(), + new HashMap<>(), new KubernetesCrudDispatcher(), false); + + private final KubernetesClient kubernetesClient = k8sServer.createClient(); + + private final TestContext context = TestContextFactory.newInstance().getObject(); + + private static Path sampleBinding; + + @BeforeClass + public static void setup() throws IOException { + sampleBinding = new ClassPathResource("timer-to-log-binding.yaml").getFile().toPath(); + camel().version(); + } + + @Test + public void shouldDeleteLocalBinding() { + Long pid = camel().run("timer-to-log-binding.yaml", sampleBinding).getCamelProcessId(); + + try { + await().atMost(30000L, TimeUnit.MILLISECONDS).until(() -> !camel().get(pid).isEmpty()); + + DeleteKameletBindingAction action = new DeleteKameletBindingAction.Builder() + .client(kubernetesClient) + .apiVersion(CamelKSettings.V1ALPHA1) + .binding("timer-to-log-binding.yaml") + .clusterType(YaksClusterType.LOCAL) + .build(); + + context.setVariable("timer-to-log-binding.yaml:pid", pid); + + action.execute(context); + + await().atMost(15000L, TimeUnit.MILLISECONDS).until(() -> camel().get(pid).isEmpty()); + } finally { + camel().stop(pid); + } + } + + @Test + public void shouldDeleteLocalBindingByName() { + Long pid = camel().run("timer-to-log-binding.yaml", sampleBinding).getCamelProcessId(); + + try { + await().atMost(30000L, TimeUnit.MILLISECONDS).until(() -> !camel().get(pid).isEmpty()); + + DeleteKameletBindingAction action = new DeleteKameletBindingAction.Builder() + .client(kubernetesClient) + .apiVersion(CamelKSettings.V1ALPHA1) + .binding("timer-to-log-binding.yaml") + .clusterType(YaksClusterType.LOCAL) + .build(); + + action.execute(context); + + await().atMost(15000L, TimeUnit.MILLISECONDS).until(() -> camel().get(pid).isEmpty()); + } finally { + camel().stop(pid); + } + } +} diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/DeletePipeActionTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/DeletePipeActionTest.java index 4a2b1064..9953321b 100644 --- a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/DeletePipeActionTest.java +++ b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/DeletePipeActionTest.java @@ -47,17 +47,17 @@ public class DeletePipeActionTest { private final TestContext context = TestContextFactory.newInstance().getObject(); - private static Path sampleBinding; + private static Path samplePipe; @BeforeClass public static void setup() throws IOException { - sampleBinding = new ClassPathResource("timer-to-log-binding.yaml").getFile().toPath(); + samplePipe = new ClassPathResource("timer-to-log-pipe.yaml").getFile().toPath(); camel().version(); } @Test - public void shouldDeleteLocalJBangBinding() { - Long pid = camel().run("timer-to-log-binding.yaml", sampleBinding).getCamelProcessId(); + public void shouldDeleteLocalPipe() { + Long pid = camel().run("timer-to-log-pipe.yaml", samplePipe).getCamelProcessId(); try { await().atMost(30000L, TimeUnit.MILLISECONDS).until(() -> !camel().get(pid).isEmpty()); @@ -65,11 +65,11 @@ public void shouldDeleteLocalJBangBinding() { DeletePipeAction action = new DeletePipeAction.Builder() .client(kubernetesClient) .apiVersion(CamelKSettings.V1ALPHA1) - .binding("timer-to-log-binding.yaml") + .pipe("timer-to-log-pipe.yaml") .clusterType(YaksClusterType.LOCAL) .build(); - context.setVariable("timer-to-log-binding.yaml:pid", pid); + context.setVariable("timer-to-log-pipe.yaml:pid", pid); action.execute(context); @@ -80,8 +80,8 @@ public void shouldDeleteLocalJBangBinding() { } @Test - public void shouldDeleteLocalJBangBindingByName() { - Long pid = camel().run("timer-to-log-binding.yaml", sampleBinding).getCamelProcessId(); + public void shouldDeleteLocalPipeByName() { + Long pid = camel().run("timer-to-log-pipe.yaml", samplePipe).getCamelProcessId(); try { await().atMost(30000L, TimeUnit.MILLISECONDS).until(() -> !camel().get(pid).isEmpty()); @@ -89,7 +89,7 @@ public void shouldDeleteLocalJBangBindingByName() { DeletePipeAction action = new DeletePipeAction.Builder() .client(kubernetesClient) .apiVersion(CamelKSettings.V1ALPHA1) - .binding("timer-to-log-binding.yaml") + .pipe("timer-to-log-pipe.yaml") .clusterType(YaksClusterType.LOCAL) .build(); diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyKameletBindingActionTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyKameletBindingActionTest.java new file mode 100644 index 00000000..63803860 --- /dev/null +++ b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyKameletBindingActionTest.java @@ -0,0 +1,76 @@ +/* + * Copyright the original author or authors. + * + * Licensed 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 org.citrusframework.yaks.camelk.actions.kamelet; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashMap; + +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesCrudDispatcher; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import io.fabric8.mockwebserver.Context; +import okhttp3.mockwebserver.MockWebServer; +import org.citrusframework.context.TestContext; +import org.citrusframework.context.TestContextFactory; +import org.citrusframework.yaks.YaksClusterType; +import org.citrusframework.yaks.camelk.jbang.ProcessAndOutput; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.core.io.ClassPathResource; + +import static org.citrusframework.yaks.camelk.jbang.CamelJBang.camel; + +public class VerifyKameletBindingActionTest { + + private final KubernetesMockServer k8sServer = new KubernetesMockServer(new Context(), new MockWebServer(), + new HashMap<>(), new KubernetesCrudDispatcher(), false); + + private final KubernetesClient kubernetesClient = k8sServer.createClient(); + + private final TestContext context = TestContextFactory.newInstance().getObject(); + + private static Path sampleBinding; + + @BeforeClass + public static void setup() throws IOException { + sampleBinding = new ClassPathResource("timer-to-log-binding.yaml").getFile().toPath(); + camel().version(); + } + + @Test + public void shouldVerifyLocalBinding() { + ProcessAndOutput pao = camel().run("timer-to-log-binding", sampleBinding); + Long pid = pao.getCamelProcessId(); + + try { + VerifyKameletBindingAction action = new VerifyKameletBindingAction.Builder() + .client(kubernetesClient) + .isAvailable("timer-to-log-binding") + .clusterType(YaksClusterType.LOCAL) + .maxAttempts(10) + .build(); + + context.setVariable("timer-to-log-binding:pid", pid); + context.setVariable("timer-to-log-binding:process:" + pid, pao); + + action.execute(context); + } finally { + camel().stop(pid); + } + } +} diff --git a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyPipeActionTest.java b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyPipeActionTest.java index 355c4bbb..91582aa0 100644 --- a/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyPipeActionTest.java +++ b/java/steps/yaks-camel-k/src/test/java/org/citrusframework/yaks/camelk/actions/kamelet/VerifyPipeActionTest.java @@ -44,29 +44,29 @@ public class VerifyPipeActionTest { private final TestContext context = TestContextFactory.newInstance().getObject(); - private static Path sampleBinding; + private static Path samplePipe; @BeforeClass public static void setup() throws IOException { - sampleBinding = new ClassPathResource("timer-to-log-binding.yaml").getFile().toPath(); + samplePipe = new ClassPathResource("timer-to-log-pipe.yaml").getFile().toPath(); camel().version(); } @Test - public void shouldVerifyLocalJBangIntegration() { - ProcessAndOutput pao = camel().run("timer-to-log-binding", sampleBinding); + public void shouldVerifyLocalPipe() { + ProcessAndOutput pao = camel().run("timer-to-log-pipe", samplePipe); Long pid = pao.getCamelProcessId(); try { VerifyPipeAction action = new VerifyPipeAction.Builder() .client(kubernetesClient) - .isAvailable("timer-to-log-binding") + .isAvailable("timer-to-log-pipe") .clusterType(YaksClusterType.LOCAL) .maxAttempts(10) .build(); - context.setVariable("timer-to-log-binding:pid", pid); - context.setVariable("timer-to-log-binding:process:" + pid, pao); + context.setVariable("timer-to-log-pipe:pid", pid); + context.setVariable("timer-to-log-pipe:process:" + pid, pao); action.execute(context); } finally { diff --git a/java/steps/yaks-camel-k/src/test/resources/kafka-source-pipe.yaml b/java/steps/yaks-camel-k/src/test/resources/kafka-source-pipe.yaml index 6697c7d7..fb0de789 100644 --- a/java/steps/yaks-camel-k/src/test/resources/kafka-source-pipe.yaml +++ b/java/steps/yaks-camel-k/src/test/resources/kafka-source-pipe.yaml @@ -22,7 +22,7 @@ spec: source: ref: kind: Kamelet - apiVersion: camel.apache.org/v1alpha1 + apiVersion: camel.apache.org/v1 name: kafka-source properties: bootstrapServers: ${bootstrap.server.host}.${YAKS_NAMESPACE}:${bootstrap.server.port} diff --git a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.kamelet.feature b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.kamelet.feature index 2a46e4ae..2bad9d17 100644 --- a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.kamelet.feature +++ b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.kamelet.feature @@ -48,29 +48,3 @@ from: Given load Kamelet timer-source.kamelet.yaml And load Camel K integration timer-to-log.groovy Then Kamelet timer-source should be available - - Scenario: Bind Kamelet to Kafka - Given KameletBinding source properties - | message | Hello World | - And bind Kamelet timer-source to Kafka topic hello-topic - When create KameletBinding timer-source-kafka - Then KameletBinding timer-source-kafka should be available - - Scenario: Bind Kamelet to Knative - Given KameletBinding source properties - | message | Hello World | - And bind Kamelet timer-source to Knative channel hello-topic of kind InMemoryChannel - When create KameletBinding timer-source-knative - Then KameletBinding timer-source-knative should be available - - Scenario: Bind Kamelet to Uri - Given KameletBinding source properties - | message | Hello World | - And bind Kamelet timer-source to uri https://greeting-service.svc.cluster.local - When create KameletBinding timer-source-uri - Then KameletBinding timer-source-uri should be available - - Scenario: Create KameletBinding from file - Given load KameletBinding kamelet-binding.yaml - Then KameletBinding timer-source-binding should be available - diff --git a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.kameletbinding.feature b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.kameletbinding.feature new file mode 100644 index 00000000..1119b1da --- /dev/null +++ b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.kameletbinding.feature @@ -0,0 +1,30 @@ +Feature: KameletBinding + + Scenario: Bind Kamelet to Kafka + Given KameletBinding source properties + | message | Hello World | + Given KameletBinding event source Kamelet timer-source + And KameletBinding event sink Kafka topic hello-topic + When create KameletBinding timer-source-kafka + Then KameletBinding timer-source-kafka should be available + + Scenario: Bind Kamelet to Knative channel + Given KameletBinding source properties + | message | Hello World | + Given KameletBinding event source Kamelet timer-source + And KameletBinding event sink Knative channel hello-topic of kind InMemoryChannel + When create KameletBinding timer-source-knative + Then KameletBinding timer-source-knative should be available + + Scenario: Bind Kamelet to Uri + Given KameletBinding source properties + | message | Hello World | + Given KameletBinding event source Kamelet timer-source + And KameletBinding event sink uri https://greeting-service.svc.cluster.local + When create KameletBinding timer-source-uri + Then KameletBinding timer-source-uri should be available + + Scenario: Create KameletBinding from file + Given load KameletBinding kamelet-binding.yaml + Then KameletBinding timer-source-binding should be available + diff --git a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.pipe.feature b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.pipe.feature new file mode 100644 index 00000000..2b001464 --- /dev/null +++ b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/camelk.pipe.feature @@ -0,0 +1,28 @@ +Feature: Pipe + + Scenario: Bind Kamelet to Kafka + Given Pipe source properties + | message | Hello World | + And bind Kamelet timer-source to Kafka topic hello-topic + When create Pipe timer-source-kafka + Then Pipe timer-source-kafka should be available + + Scenario: Bind Kamelet to Knative + Given Pipe source properties + | message | Hello World | + And bind Kamelet timer-source to Knative channel hello-topic of kind InMemoryChannel + When create Pipe timer-source-knative + Then Pipe timer-source-knative should be available + + Scenario: Bind Kamelet to Uri + Given Pipe source properties + | message | Hello World | + And bind Kamelet timer-source to uri https://greeting-service.svc.cluster.local + When create Pipe timer-source-uri + Then Pipe timer-source-uri should be available + + Scenario: Create Pipe from file + Given Kamelet API version v1alpha1 + Given load Pipe pipe.yaml + Then Pipe timer-source-pipe should be available + diff --git a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/integration.json b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/integration.json deleted file mode 100644 index 342189ca..00000000 --- a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/integration.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "apiVersion": "camel.apache.org/v1", - "kind": "Integration", - "metadata": { - "name": "bar" - }, - "spec": { - "sources": [ - { - "name": "bar.groovy", - "content": "from(\"timer:x\").log('${body}')" - } - ], - "dependencies": [ - "mvn:fake.dependency:id:version-1", - "camel:jackson" - ], - "traits": { - "route": { - "configuration": { - "enabled": true - } - }, - "quarkus": { - "configuration": { - "native": "true", - "enabled": true - } - }, - "builder":{ - "configuration": { - "properties": ["quarkus.foo=bar","quarkus.verbose=true"], - "verbose": true - } - } - } - } -} diff --git a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/kamelet-binding.json b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/kamelet-binding.json deleted file mode 100644 index 4983af69..00000000 --- a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/kamelet-binding.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "apiVersion": "camel.apache.org/v1alpha1", - "kind": "KameletBinding", - "metadata": { - "name": "time-source-kafka" - }, - "spec": { - "source": { - "ref": { - "name": "timer-source", - "kind": "Kamelet", - "namespace": "default" - }, - "properties": { - "message": "Hello World" - }, - "dataTypes": { - "out": { - "scheme": "camel", - "format": "string" - } - } - }, - "sink": { - "ref": { - "name": "hello-topic", - "kind": "KafkaTopic", - "namespace": "default" - } - } - } -} diff --git a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/kamelet.json b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/kamelet.json deleted file mode 100644 index 09f4d1fd..00000000 --- a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/kamelet.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "apiVersion": "camel.apache.org/v1", - "kind": "Kamelet", - "metadata": { - "labels": { - "camel.apache.org/kamelet.type": "source" - }, - "name": "time-source" - }, - "spec": { - "definition": { - "title": "Timer Source", - "required": [ - "message" - ], - "properties": { - "period": { - "title": "Period", - "type": "integer", - "default": 1000 - }, - "message": { - "title": "Message", - "type": "string", - "example": "hello world" - } - } - }, - "dataTypes": { - "out": { - "default": "text", - "types": { - "binary": { - "scheme": "camel", - "format": "binary" - }, - "text": { - "scheme": "camel", - "format": "text" - } - } - } - }, - "dependencies": [ - "mvn:fake.dependency:id:version-1" - ], - "template": { - "from": { - "uri": "timer:tick", - "parameters": { - "period": "#property:period" - }, - "steps": [ - { - "set-body": { - "constant": "{{message}}" - } - }, - { - "to": "kamelet:sink" - } - ] - } - } - } -} diff --git a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/pipe.json b/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/pipe.json deleted file mode 100644 index ad53e06f..00000000 --- a/java/steps/yaks-camel-k/src/test/resources/org/citrusframework/yaks/camelk/pipe.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "apiVersion": "camel.apache.org/v1", - "kind": "Pipe", - "metadata": { - "name": "time-source-kafka" - }, - "spec": { - "source": { - "ref": { - "name": "timer-source", - "kind": "Kamelet", - "namespace": "default" - }, - "properties": { - "message": "Hello World" - }, - "dataTypes": { - "out": { - "scheme": "camel", - "format": "string" - } - } - }, - "sink": { - "ref": { - "name": "hello-topic", - "kind": "KafkaTopic", - "namespace": "default" - } - } - } -} diff --git a/java/steps/yaks-camel-k/src/test/resources/pipe.yaml b/java/steps/yaks-camel-k/src/test/resources/pipe.yaml new file mode 100644 index 00000000..8a7958e5 --- /dev/null +++ b/java/steps/yaks-camel-k/src/test/resources/pipe.yaml @@ -0,0 +1,33 @@ +# --------------------------------------------------------------------------- +# Copyright the original author or authors. +# +# Licensed 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. +# --------------------------------------------------------------------------- + +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: timer-source-pipe +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source + properties: + message: "Hello world!" + sink: + ref: + kind: KafkaTopic + apiVersion: kafka.strimzi.io/v1beta1 + name: hello-topic diff --git a/java/steps/yaks-camel-k/src/test/resources/timer-source.kamelet.yaml b/java/steps/yaks-camel-k/src/test/resources/timer-source.kamelet.yaml index 82cf5c3e..87745416 100644 --- a/java/steps/yaks-camel-k/src/test/resources/timer-source.kamelet.yaml +++ b/java/steps/yaks-camel-k/src/test/resources/timer-source.kamelet.yaml @@ -14,7 +14,7 @@ # limitations under the License. # --------------------------------------------------------------------------- -apiVersion: camel.apache.org/v1alpha1 +apiVersion: camel.apache.org/v1 kind: Kamelet metadata: name: timer-source diff --git a/java/steps/yaks-camel-k/src/test/resources/timer-to-log-pipe.yaml b/java/steps/yaks-camel-k/src/test/resources/timer-to-log-pipe.yaml index 3fa2366d..7fa04b66 100644 --- a/java/steps/yaks-camel-k/src/test/resources/timer-to-log-pipe.yaml +++ b/java/steps/yaks-camel-k/src/test/resources/timer-to-log-pipe.yaml @@ -22,7 +22,7 @@ spec: source: ref: kind: Kamelet - apiVersion: camel.apache.org/v1alpha1 + apiVersion: camel.apache.org/v1 name: timer-source properties: message: "Hello world!" diff --git a/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpClientSteps.java b/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpClientSteps.java index 9561d06c..ee7d3fa1 100644 --- a/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpClientSteps.java +++ b/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpClientSteps.java @@ -21,9 +21,10 @@ import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; import java.util.HashMap; import java.util.Map; -import javax.net.ssl.SSLContext; import io.cucumber.datatable.DataTable; import io.cucumber.java.Before; @@ -33,12 +34,14 @@ import io.cucumber.java.en.When; import org.apache.hc.client5.http.auth.AuthScope; import org.apache.hc.client5.http.auth.UsernamePasswordCredentials; +import org.apache.hc.client5.http.impl.DefaultSchemePortResolver; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.client5.http.ssl.TrustAllStrategy; +import org.apache.hc.core5.ssl.SSLContextBuilder; import org.apache.hc.core5.ssl.SSLContexts; import org.citrusframework.Citrus; import org.citrusframework.CitrusSettings; @@ -55,12 +58,13 @@ import org.citrusframework.http.client.HttpClientBuilder; import org.citrusframework.http.message.HttpMessage; import org.citrusframework.util.FileUtils; +import org.citrusframework.util.StringUtils; import org.citrusframework.variable.dictionary.DataDictionary; +import org.citrusframework.yaks.YaksSettings; import org.citrusframework.yaks.util.ResourceUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMethod; import static org.citrusframework.TestActionBuilder.logger; @@ -110,6 +114,10 @@ public class HttpClientSteps implements HttpSteps { private String authUser = HttpSettings.getClientAuthUser(); private String authPassword = HttpSettings.getClientAuthPassword(); + private boolean useSslKeyStore = HttpSettings.isUseSslKeyStore(); + private String sslKeyStorePath = HttpSettings.getSslKeyStorePath(); + private String sslKeyStorePassword = HttpSettings.getSslKeyStorePassword(); + @Before public void before(Scenario scenario) { if (httpClient == null) { @@ -156,6 +164,22 @@ public void setUrl(String url) { this.requestUrl = resolvedUrl; } + @Given("^HTTP client (enable|disable) SSL keystore$") + public void setSecureKeyStore(String mode) { + this.useSslKeyStore = "enable".equals(mode); + } + + @Given("^HTTP client SSL keystore path ([^\\s]+)$") + public void setSslKeyStorePath(String sslKeyStorePath) { + this.sslKeyStorePath = sslKeyStorePath; + this.useSslKeyStore = true; + } + + @Given("^HTTP client SSL keystore password ([^\\s]+)$") + public void setSslKeyStorePassword(String sslKeyStorePassword) { + this.sslKeyStorePassword = sslKeyStorePassword; + } + @Given("^HTTP client (enable|disable) basic auth$") public void setBasicAuth(String mode) { if ("enable".equals(mode)) { @@ -438,13 +462,17 @@ private HttpComponentsClientHttpRequestFactory sslRequestFactory() { */ private org.apache.hc.client5.http.classic.HttpClient sslClient() { try { - SSLContext sslcontext = SSLContexts + SSLContextBuilder sslContextBuilder = SSLContexts .custom() - .loadTrustMaterial(TrustAllStrategy.INSTANCE) - .build(); + .loadTrustMaterial(TrustAllStrategy.INSTANCE); + + if (useSslKeyStore && StringUtils.hasText(sslKeyStorePath)) { + sslContextBuilder.loadKeyMaterial(ResourceUtils.resolve(sslKeyStorePath, context).getURL(), + sslKeyStorePassword.toCharArray(), sslKeyStorePassword.toCharArray()); + } SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory( - sslcontext, NoopHostnameVerifier.INSTANCE); + sslContextBuilder.build(), NoopHostnameVerifier.INSTANCE); PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create() .setSSLSocketFactory(sslSocketFactory) @@ -453,7 +481,7 @@ private org.apache.hc.client5.http.classic.HttpClient sslClient() { return HttpClients.custom() .setConnectionManager(connectionManager) .build(); - } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) { + } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException | IOException | UnrecoverableKeyException | CertificateException e) { throw new CitrusRuntimeException("Failed to create http client for ssl connection", e); } } diff --git a/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpServerSteps.java b/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpServerSteps.java index 80a1330b..443dd1b8 100644 --- a/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpServerSteps.java +++ b/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpServerSteps.java @@ -49,6 +49,7 @@ import org.citrusframework.http.server.HttpServer; import org.citrusframework.http.server.HttpServerBuilder; import org.citrusframework.util.FileUtils; +import org.citrusframework.util.StringUtils; import org.citrusframework.variable.dictionary.DataDictionary; import org.citrusframework.yaks.util.ResourceUtils; import org.eclipse.jetty.http.HttpVersion; @@ -83,8 +84,6 @@ public class HttpServerSteps implements HttpSteps { private HttpServer httpServer; - private ServerConnector sslConnector; - private Map requestHeaders = new HashMap<>(); private Map responseHeaders = new HashMap<>(); private Map requestParams = new HashMap<>(); @@ -106,6 +105,9 @@ public class HttpServerSteps implements HttpSteps { private int serverPort = HttpSettings.getServerPort(); private String serverName = HttpSettings.getServerName(); + private boolean useSslConnector = HttpSettings.isUseSslConnector(); + private boolean useSslKeyStore = HttpSettings.isUseSslKeyStore(); + private String sslKeyStorePath = HttpSettings.getSslKeyStorePath(); private String sslKeyStorePassword = HttpSettings.getSslKeyStorePassword(); @@ -142,7 +144,6 @@ public void before(Scenario scenario) { bodyValidationExpressions = new HashMap<>(); outboundDictionary = null; inboundDictionary = null; - sslConnector = null; } @Given("^HTTP server \"([^\"\\s]+)\"$") @@ -227,16 +228,21 @@ public void setAuthPassword(String authPassword) { @Given("^HTTP server (enable|disable) SSL$") public void setSecureConnector(String mode) { - if ("enable".equals(mode)) { - this.sslConnector = sslConnector(); - } else { - this.sslConnector = null; + useSslConnector = "enable".equals(mode); + if (useSslConnector) { + this.useSslKeyStore = true; } } + @Given("^HTTP server (enable|disable) SSL keystore$") + public void setSecureKeyStore(String mode) { + this.useSslKeyStore = "enable".equals(mode); + } + @Given("^HTTP server SSL keystore path ([^\\s]+)$") public void setSslKeyStorePath(String sslKeyStorePath) { this.sslKeyStorePath = sslKeyStorePath; + this.useSslKeyStore = true; } @Given("^HTTP server SSL keystore password ([^\\s]+)$") @@ -454,8 +460,8 @@ public HttpServer getOrCreateHttpServer() { .name(serverName) .build(); - if (sslConnector != null) { - httpServer.setConnector(sslConnector); + if (useSslConnector) { + httpServer.setConnector(sslConnector()); } if ("basic".equals(authMethod)) { @@ -555,8 +561,10 @@ private HttpConfiguration httpConfiguration() { private SslContextFactory.Server sslContextFactory() { try { SslContextFactory.Server contextFactory = new SslContextFactory.Server(); - contextFactory.setKeyStorePath(getKeyStorePathPath()); - contextFactory.setKeyStorePassword(context.replaceDynamicContentInString(sslKeyStorePassword)); + if (useSslKeyStore && StringUtils.hasText(sslKeyStorePath)) { + contextFactory.setKeyStorePath(getKeyStorePathPath()); + contextFactory.setKeyStorePassword(context.replaceDynamicContentInString(sslKeyStorePassword)); + } return contextFactory; } catch (IOException e) { throw new CitrusRuntimeException("Failed to read keystore file in path: " + sslKeyStorePath); diff --git a/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpSettings.java b/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpSettings.java index b37dedec..2a5d4305 100644 --- a/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpSettings.java +++ b/java/steps/yaks-http/src/main/java/org/citrusframework/yaks/http/HttpSettings.java @@ -90,6 +90,14 @@ public class HttpSettings { private static final String SECURE_KEYSTORE_PASSWORD_ENV = HTTP_ENV_PREFIX + "SECURE_KEYSTORE_PASSWORD"; private static final String SECURE_KEYSTORE_PASSWORD_DEFAULT = "secret"; + private static final String USE_SECURE_CONNECTOR_PROPERTY = HTTP_PROPERTY_PREFIX + "use.secure.connector"; + private static final String USE_SECURE_CONNECTOR_ENV = HTTP_ENV_PREFIX + "USE_SECURE_CONNECTOR"; + private static final String USE_SECURE_CONNECTOR_DEFAULT = "false"; + + private static final String USE_SECURE_KEYSTORE_PROPERTY = HTTP_PROPERTY_PREFIX + "use.secure.keystore"; + private static final String USE_SECURE_KEYSTORE_ENV = HTTP_ENV_PREFIX + "USE_SECURE_KEYSTORE"; + private static final String USE_SECURE_KEYSTORE_DEFAULT = "false"; + private static final String HEADER_NAME_IGNORE_CASE_PROPERTY = HTTP_PROPERTY_PREFIX + "header.name.ignore.case"; private static final String HEADER_NAME_IGNORE_CASE_ENV = HTTP_ENV_PREFIX + "HEADER_NAME_IGNORE_CASE"; private static final String HEADER_NAME_IGNORE_CASE_DEFAULT = "false"; @@ -143,6 +151,18 @@ public static int getSecurePort() { System.getenv(SECURE_PORT_ENV) != null ? System.getenv(SECURE_PORT_ENV) : SECURE_PORT_DEFAULT)); } + public static boolean isUseSslConnector() { + return Boolean.parseBoolean(System.getProperty(USE_SECURE_CONNECTOR_PROPERTY, + System.getenv(USE_SECURE_CONNECTOR_ENV) != null ? System.getenv(USE_SECURE_CONNECTOR_ENV) : + USE_SECURE_CONNECTOR_DEFAULT)); + } + + public static boolean isUseSslKeyStore() { + return Boolean.parseBoolean(System.getProperty(USE_SECURE_KEYSTORE_PROPERTY, + System.getenv(USE_SECURE_KEYSTORE_ENV) != null ? System.getenv(USE_SECURE_KEYSTORE_ENV) : + USE_SECURE_KEYSTORE_DEFAULT)); + } + /** * SSL key store path. * @return diff --git a/java/steps/yaks-kafka/src/main/java/org/citrusframework/yaks/kafka/KafkaSettings.java b/java/steps/yaks-kafka/src/main/java/org/citrusframework/yaks/kafka/KafkaSettings.java index 677c0c0b..98706abc 100644 --- a/java/steps/yaks-kafka/src/main/java/org/citrusframework/yaks/kafka/KafkaSettings.java +++ b/java/steps/yaks-kafka/src/main/java/org/citrusframework/yaks/kafka/KafkaSettings.java @@ -34,6 +34,10 @@ public class KafkaSettings { private static final String ENDPOINT_NAME_ENV = KAFKA_ENV_PREFIX + "ENDPOINT_NAME"; private static final String ENDPOINT_NAME_DEFAULT = "yaks-kafka-endpoint"; + private static final String API_VERSION_PROPERTY = KAFKA_PROPERTY_PREFIX + "api.version"; + private static final String API_VERSION_ENV = KAFKA_ENV_PREFIX + "API_VERSION"; + private static final String API_VERSION_DEFAULT = "v1beta1"; + static final String NAMESPACE_PROPERTY = KAFKA_PROPERTY_PREFIX + "namespace"; static final String NAMESPACE_ENV = KAFKA_ENV_PREFIX + "NAMESPACE"; @@ -67,4 +71,13 @@ public static String getNamespace() { return System.getProperty(NAMESPACE_PROPERTY, System.getenv(NAMESPACE_ENV) != null ? System.getenv(NAMESPACE_ENV) : YaksSettings.getDefaultNamespace()); } + + /** + * Api version for current Kafka Strimzi installation. + * @return + */ + public static String getApiVersion() { + return System.getProperty(API_VERSION_PROPERTY, + System.getenv(API_VERSION_ENV) != null ? System.getenv(API_VERSION_ENV) : API_VERSION_DEFAULT); + } } diff --git a/java/steps/yaks-kubernetes/src/main/java/org/citrusframework/yaks/kubernetes/KubernetesSupport.java b/java/steps/yaks-kubernetes/src/main/java/org/citrusframework/yaks/kubernetes/KubernetesSupport.java index 111a8458..94f4d97f 100644 --- a/java/steps/yaks-kubernetes/src/main/java/org/citrusframework/yaks/kubernetes/KubernetesSupport.java +++ b/java/steps/yaks-kubernetes/src/main/java/org/citrusframework/yaks/kubernetes/KubernetesSupport.java @@ -37,6 +37,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientBuilder; import io.fabric8.kubernetes.client.KubernetesClientException; +import io.fabric8.kubernetes.client.dsl.Updatable; import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext; import org.citrusframework.Citrus; import org.citrusframework.context.TestContext; @@ -70,6 +71,11 @@ private KubernetesSupport() { // prevent instantiation of utility class } + // Optional property value mapper used to customize YAML dumper. + public interface PropertyValueMapper { + Object map(Property property, Object propertyValue); + } + /** * Retrieve current Kubernetes client if set in Citrus context as bean reference. * Otherwise, create new default instance. @@ -133,6 +139,25 @@ protected NodeTuple representJavaBeanProperty(Object javaBean, Property property return new Yaml(representer); } + public static Yaml yaml(PropertyValueMapper mapper) { + Representer representer = new Representer(new DumperOptions()) { + @Override + protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) { + Object propertyValueMapped = mapper.map(property, propertyValue); + + // if value of property is null, ignore it. + if (propertyValueMapped == null || (propertyValueMapped instanceof Collection && ((Collection) propertyValueMapped).isEmpty()) || + (propertyValueMapped instanceof Map && ((Map) propertyValueMapped).isEmpty())) { + return null; + } else { + return super.representJavaBeanProperty(javaBean, property, propertyValueMapped, customTag); + } + } + }; + representer.getPropertyUtils().setSkipMissingProperties(true); + return new Yaml(representer); + } + public static ObjectMapper json() { return OBJECT_MAPPER; } @@ -167,7 +192,7 @@ public static void createResource(KubernetesClient k8sClient, String namespa public static void createResource(KubernetesClient k8sClient, String namespace, ResourceDefinitionContext context, String yaml) { k8sClient.genericKubernetesResources(context).inNamespace(namespace) - .load(new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8))).createOrReplace(); + .load(new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8))).createOr(Updatable::update); } public static void deleteResource(KubernetesClient k8sClient, String namespace, @@ -223,5 +248,4 @@ public static Optional getServiceClusterIp(Citrus citrus, String service return Optional.empty(); } - } diff --git a/java/tools/maven/yaks-maven-extension/src/main/java/org/citrusframework/yaks/maven/extension/ExtensionSettings.java b/java/tools/maven/yaks-maven-extension/src/main/java/org/citrusframework/yaks/maven/extension/ExtensionSettings.java index 59701f21..44316bf9 100644 --- a/java/tools/maven/yaks-maven-extension/src/main/java/org/citrusframework/yaks/maven/extension/ExtensionSettings.java +++ b/java/tools/maven/yaks-maven-extension/src/main/java/org/citrusframework/yaks/maven/extension/ExtensionSettings.java @@ -89,7 +89,7 @@ public static String getLogPatternLayout() { * @return */ public static boolean hasMountedTests() { - return getMountedTestsPath().length() > 0; + return !getMountedTestsPath().isEmpty(); } /** @@ -97,7 +97,7 @@ public static boolean hasMountedTests() { * @return */ public static boolean hasMountedSecrets() { - return getMountedSecretsPath().length() > 0; + return !getMountedSecretsPath().isEmpty(); } /** diff --git a/pkg/apis/yaks/v1alpha1/test_types.go b/pkg/apis/yaks/v1alpha1/test_types.go index c80d4642..f48e3956 100644 --- a/pkg/apis/yaks/v1alpha1/test_types.go +++ b/pkg/apis/yaks/v1alpha1/test_types.go @@ -51,7 +51,7 @@ type TestSpec struct { Selenium SeleniumSpec `json:"selenium,omitempty"` KubeDock KubeDockSpec `json:"kubedock,omitempty"` Env []string `json:"env,omitempty"` - Secret string `json:"secret,omitempty"` + Secrets []string `json:"secrets,omitempty"` } // RuntimeSpec --. diff --git a/pkg/apis/yaks/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/yaks/v1alpha1/zz_generated.deepcopy.go index d4eea08b..11640677 100644 --- a/pkg/apis/yaks/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/yaks/v1alpha1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Code generated by controller-gen. DO NOT EDIT. @@ -329,6 +328,11 @@ func (in *TestSpec) DeepCopyInto(out *TestSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Secrets != nil { + in, out := &in.Secrets, &out.Secrets + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestSpec. diff --git a/pkg/client/yaks/clientset/versioned/clientset.go b/pkg/client/yaks/clientset/versioned/clientset.go index 3a292610..fab726e2 100644 --- a/pkg/client/yaks/clientset/versioned/clientset.go +++ b/pkg/client/yaks/clientset/versioned/clientset.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. @@ -34,8 +33,7 @@ type Interface interface { YaksV1alpha1() yaksv1alpha1.YaksV1alpha1Interface } -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. +// Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient yaksV1alpha1 *yaksv1alpha1.YaksV1alpha1Client diff --git a/pkg/client/yaks/clientset/versioned/doc.go b/pkg/client/yaks/clientset/versioned/doc.go deleted file mode 100644 index c82aadf0..00000000 --- a/pkg/client/yaks/clientset/versioned/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -/* -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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated clientset. -package versioned diff --git a/pkg/client/yaks/clientset/versioned/fake/clientset_generated.go b/pkg/client/yaks/clientset/versioned/fake/clientset_generated.go index 9a6a1294..08fefc48 100644 --- a/pkg/client/yaks/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/yaks/clientset/versioned/fake/clientset_generated.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/fake/doc.go b/pkg/client/yaks/clientset/versioned/fake/doc.go index 9c6a5fa0..91d44826 100644 --- a/pkg/client/yaks/clientset/versioned/fake/doc.go +++ b/pkg/client/yaks/clientset/versioned/fake/doc.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/fake/register.go b/pkg/client/yaks/clientset/versioned/fake/register.go index 7fdd7b80..63d29912 100644 --- a/pkg/client/yaks/clientset/versioned/fake/register.go +++ b/pkg/client/yaks/clientset/versioned/fake/register.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/scheme/doc.go b/pkg/client/yaks/clientset/versioned/scheme/doc.go index dd7d3b58..bef75742 100644 --- a/pkg/client/yaks/clientset/versioned/scheme/doc.go +++ b/pkg/client/yaks/clientset/versioned/scheme/doc.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/scheme/register.go b/pkg/client/yaks/clientset/versioned/scheme/register.go index 3b0c2dd1..9a3ca58a 100644 --- a/pkg/client/yaks/clientset/versioned/scheme/register.go +++ b/pkg/client/yaks/clientset/versioned/scheme/register.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/doc.go b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/doc.go index 9f77d247..b0eef192 100644 --- a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/doc.go +++ b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/doc.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/doc.go b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/doc.go index 5d1c76cc..c746d225 100644 --- a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/doc.go +++ b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/doc.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_instance.go b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_instance.go index 5f38fcbb..6faf72ba 100644 --- a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_instance.go +++ b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_instance.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. @@ -25,7 +24,6 @@ import ( v1alpha1 "github.com/citrusframework/yaks/pkg/apis/yaks/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" @@ -37,9 +35,9 @@ type FakeInstances struct { ns string } -var instancesResource = schema.GroupVersionResource{Group: "yaks.citrusframework.org", Version: "v1alpha1", Resource: "instances"} +var instancesResource = v1alpha1.SchemeGroupVersion.WithResource("instances") -var instancesKind = schema.GroupVersionKind{Group: "yaks.citrusframework.org", Version: "v1alpha1", Kind: "Instance"} +var instancesKind = v1alpha1.SchemeGroupVersion.WithKind("Instance") // Get takes name of the instance, and returns the corresponding instance object, and an error if there is any. func (c *FakeInstances) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Instance, err error) { diff --git a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_tests.go b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_tests.go index 713b2680..fab7be1a 100644 --- a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_tests.go +++ b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_tests.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. @@ -25,7 +24,6 @@ import ( v1alpha1 "github.com/citrusframework/yaks/pkg/apis/yaks/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" @@ -37,9 +35,9 @@ type FakeTests struct { ns string } -var testsResource = schema.GroupVersionResource{Group: "yaks.citrusframework.org", Version: "v1alpha1", Resource: "tests"} +var testsResource = v1alpha1.SchemeGroupVersion.WithResource("tests") -var testsKind = schema.GroupVersionKind{Group: "yaks.citrusframework.org", Version: "v1alpha1", Kind: "Test"} +var testsKind = v1alpha1.SchemeGroupVersion.WithKind("Test") // Get takes name of the test, and returns the corresponding test object, and an error if there is any. func (c *FakeTests) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Test, err error) { diff --git a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_yaks_client.go b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_yaks_client.go index 5582c1fe..aaffaa9c 100644 --- a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_yaks_client.go +++ b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_yaks_client.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/generated_expansion.go b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/generated_expansion.go index 63c995c6..2d573047 100644 --- a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/generated_expansion.go +++ b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/generated_expansion.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/instance.go b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/instance.go index e00f6236..2754f921 100644 --- a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/instance.go +++ b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/instance.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/test.go b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/test.go index 6e03c42e..5df5207c 100644 --- a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/test.go +++ b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/test.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/yaks_client.go b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/yaks_client.go index 2ded791e..6f02675f 100644 --- a/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/yaks_client.go +++ b/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/yaks_client.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by client-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/informers/externalversions/factory.go b/pkg/client/yaks/informers/externalversions/factory.go index 5b58712a..00ca733d 100644 --- a/pkg/client/yaks/informers/externalversions/factory.go +++ b/pkg/client/yaks/informers/externalversions/factory.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by informer-gen. DO NOT EDIT. @@ -43,11 +42,17 @@ type sharedInformerFactory struct { lock sync.Mutex defaultResync time.Duration customResync map[reflect.Type]time.Duration + transform cache.TransformFunc informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. // This allows Start() to be called multiple times safely. startedInformers map[reflect.Type]bool + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool } // WithCustomResyncConfig sets a custom resync period for the specified informer types. @@ -76,6 +81,14 @@ func WithNamespace(namespace string) SharedInformerOption { } } +// WithTransform sets a transform on all informers. +func WithTransform(transform cache.TransformFunc) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.transform = transform + return factory + } +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -108,20 +121,39 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy return factory } -// Start initializes all requested informers. func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { f.lock.Lock() defer f.lock.Unlock() + if f.shuttingDown { + return + } + for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - go informer.Run(stopCh) + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() f.startedInformers[informerType] = true } } } -// WaitForCacheSync waits for all started informers' cache were synced. +func (f *sharedInformerFactory) Shutdown() { + f.lock.Lock() + f.shuttingDown = true + f.lock.Unlock() + + // Will return immediately if there is nothing to wait for. + f.wg.Wait() +} + func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() @@ -143,7 +175,7 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return res } -// InternalInformerFor returns the SharedIndexInformer for obj using an internal +// InformerFor returns the SharedIndexInformer for obj using an internal // client. func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { f.lock.Lock() @@ -161,6 +193,7 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) + informer.SetTransform(f.transform) f.informers[informerType] = informer return informer @@ -168,11 +201,58 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // SharedInformerFactory provides shared informers for resources in all known // API group versions. +// +// It is typically used like this: +// +// ctx, cancel := context.Background() +// defer cancel() +// factory := NewSharedInformerFactory(client, resyncPeriod) +// defer factory.WaitForStop() // Returns immediately if nothing was started. +// genericInformer := factory.ForResource(resource) +// typedInformer := factory.SomeAPIGroup().V1().SomeType() +// factory.Start(ctx.Done()) // Start processing these informers. +// synced := factory.WaitForCacheSync(ctx.Done()) +// for v, ok := range synced { +// if !ok { +// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) +// return +// } +// } +// +// // Creating informers can also be created after Start, but then +// // Start must be called again: +// anotherGenericInformer := factory.ForResource(resource) +// factory.Start(ctx.Done()) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory - ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + Start(stopCh <-chan struct{}) + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // ForResource gives generic access to a shared informer of the matching type. + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // InformerFor returns the SharedIndexInformer for obj using an internal + // client. + InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer + Yaks() yaks.Interface } diff --git a/pkg/client/yaks/informers/externalversions/generic.go b/pkg/client/yaks/informers/externalversions/generic.go index 83af3c50..9fe66c5f 100644 --- a/pkg/client/yaks/informers/externalversions/generic.go +++ b/pkg/client/yaks/informers/externalversions/generic.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by informer-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/client/yaks/informers/externalversions/internalinterfaces/factory_interfaces.go index 9d03bc13..fb0403a2 100644 --- a/pkg/client/yaks/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/pkg/client/yaks/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by informer-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/informers/externalversions/yaks/interface.go b/pkg/client/yaks/informers/externalversions/yaks/interface.go index 8348204a..d2f6300f 100644 --- a/pkg/client/yaks/informers/externalversions/yaks/interface.go +++ b/pkg/client/yaks/informers/externalversions/yaks/interface.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by informer-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/instance.go b/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/instance.go index ee8c27a3..f0e0caaf 100644 --- a/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/instance.go +++ b/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/instance.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by informer-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/interface.go b/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/interface.go index f4e0d1ee..cd820c87 100644 --- a/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/interface.go +++ b/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/interface.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by informer-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/test.go b/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/test.go index c840bbf6..8e84cfd6 100644 --- a/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/test.go +++ b/pkg/client/yaks/informers/externalversions/yaks/v1alpha1/test.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by informer-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/listers/yaks/v1alpha1/expansion_generated.go b/pkg/client/yaks/listers/yaks/v1alpha1/expansion_generated.go index 56b82fbd..cd181619 100644 --- a/pkg/client/yaks/listers/yaks/v1alpha1/expansion_generated.go +++ b/pkg/client/yaks/listers/yaks/v1alpha1/expansion_generated.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by lister-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/listers/yaks/v1alpha1/instance.go b/pkg/client/yaks/listers/yaks/v1alpha1/instance.go index b38e37a6..01aef81b 100644 --- a/pkg/client/yaks/listers/yaks/v1alpha1/instance.go +++ b/pkg/client/yaks/listers/yaks/v1alpha1/instance.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by lister-gen. DO NOT EDIT. diff --git a/pkg/client/yaks/listers/yaks/v1alpha1/test.go b/pkg/client/yaks/listers/yaks/v1alpha1/test.go index c72fe849..447876a8 100644 --- a/pkg/client/yaks/listers/yaks/v1alpha1/test.go +++ b/pkg/client/yaks/listers/yaks/v1alpha1/test.go @@ -1,19 +1,18 @@ /* -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. -*/ + * Copyright the original author or authors. + * + * Licensed 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. + */ // Code generated by lister-gen. DO NOT EDIT. diff --git a/pkg/cmd/config/config.go b/pkg/cmd/config/config.go index 7b95398f..a981e7af 100644 --- a/pkg/cmd/config/config.go +++ b/pkg/cmd/config/config.go @@ -65,7 +65,7 @@ type RuntimeConfig struct { Resources []string `yaml:"resources"` Settings SettingsConfig `yaml:"settings"` Env []EnvConfig `yaml:"env"` - Secret string `yaml:"secret"` + Secrets []string `yaml:"secret"` ClusterType string `yaml:"clusterType"` } diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go index c6fd8cca..e7d84636 100644 --- a/pkg/cmd/operator/operator.go +++ b/pkg/cmd/operator/operator.go @@ -162,23 +162,39 @@ func Run(leaderElection bool, leaderElectionID string) { hasTestLabel, err := labels.NewRequirement(v1alpha1.TestLabel, selection.Exists, []string{}) exitOnError(err, "cannot create test label selector") - selector := labels.NewSelector().Add(*hasTestLabel) + labelsSelector := labels.NewSelector().Add(*hasTestLabel) + + selector := cache.ByObject{ + Label: labelsSelector, + } + + if !envvar.IsCurrentOperatorGlobal() { + selector = cache.ByObject{ + Label: labelsSelector, + Namespaces: getNamespacesSelector(operatorNamespace, watchNamespace), + } + } + + cacheOptions := cache.Options{ + ByObject: map[k8sclient.Object]cache.ByObject{ + &corev1.Pod{}: selector, + &batchv1.Job{}: selector, + }, + } + + if !envvar.IsCurrentOperatorGlobal() { + cacheOptions.DefaultNamespaces = getNamespacesSelector(operatorNamespace, watchNamespace) + } // Create a new Cmd to provide shared dependencies and start components mgr, err := manager.New(c.GetConfig(), manager.Options{ - Namespace: watchNamespace, EventBroadcaster: broadcaster, LeaderElection: leaderElection, LeaderElectionNamespace: operatorNamespace, LeaderElectionID: leaderElectionID, LeaderElectionResourceLock: resourcelock.LeasesResourceLock, LeaderElectionReleaseOnCancel: true, - Cache: cache.Options{ - ByObject: map[k8sclient.Object]cache.ByObject{ - &corev1.Pod{}: {Label: selector}, - &batchv1.Job{}: {Label: selector}, - }, - }, + Cache: cacheOptions, }) exitOnError(err, "") @@ -216,6 +232,16 @@ func Run(leaderElection bool, leaderElectionID string) { exitOnError(err, "manager exited non-zero") } +func getNamespacesSelector(operatorNamespace string, watchNamespace string) map[string]cache.Config { + namespacesSelector := map[string]cache.Config{ + operatorNamespace: {}, + } + if operatorNamespace != watchNamespace { + namespacesSelector[watchNamespace] = cache.Config{} + } + return namespacesSelector +} + func installInstance(ctx context.Context, c client.Client, global bool, version string) error { operatorNamespace := envvar.GetOperatorNamespace() if operatorNamespace == "" { diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index ba0fe0a1..7d920b1f 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -90,6 +90,7 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions) cmd.Flags().StringP("settings", "s", "", "Path to runtime settings file. File content is added to the test runtime and can hold runtime dependency information for instance.") cmd.Flags().StringArrayP("env", "e", nil, "Set an environment variable in the integration container. E.g \"-e MY_VAR=my-value\"") cmd.Flags().StringArray("resource", nil, "Add a resource") + cmd.Flags().StringArray("secret", nil, "Bind a secret to the test") cmd.Flags().StringArray("property-file", nil, "Bind a property file to the test. E.g. \"--property-file test.properties\"") cmd.Flags().String("timeout", "", "Time to wait for individual test to complete") @@ -124,6 +125,7 @@ type runCmdOptions struct { Tags []string `mapstructure:"tag"` Features []string `mapstructure:"feature"` Resources []string `mapstructure:"resources"` + Secrets []string `mapstructure:"secrets"` PropertyFiles []string `mapstructure:"property-files"` Glue []string `mapstructure:"glue"` Options string `mapstructure:"options"` @@ -554,8 +556,12 @@ func (o *runCmdOptions) configureTest(ctx context.Context, namespace string, fil o.setupEnvSettings(&test, runConfig) - if runConfig.Config.Runtime.Secret != "" { - test.Spec.Secret = runConfig.Config.Runtime.Secret + if len(o.Secrets) > 0 { + test.Spec.Secrets = append(test.Spec.Secrets, o.Secrets...) + } + + if len(runConfig.Config.Runtime.Secrets) > 0 { + test.Spec.Secrets = append(test.Spec.Secrets, runConfig.Config.Runtime.Secrets...) } if runConfig.Config.Runtime.Selenium.Enabled { diff --git a/pkg/controller/test/start.go b/pkg/controller/test/start.go index 0c6d506c..86673d31 100644 --- a/pkg/controller/test/start.go +++ b/pkg/controller/test/start.go @@ -154,10 +154,6 @@ func (action *startAction) newTestResources(ctx context.Context, test *v1alpha1. Name: "tests", MountPath: "/etc/yaks/tests", }, - { - Name: "secrets", - MountPath: "/etc/yaks/secrets", - }, }, Env: []v1.EnvVar{ { @@ -777,34 +773,44 @@ func (action *startAction) bindSecrets(ctx context.Context, test *v1alpha1.Test, var options = metav1.ListOptions{ LabelSelector: fmt.Sprintf("%s=%s", v1alpha1.TestLabel, test.Name), } - if test.Spec.Secret != "" { - options.LabelSelector = fmt.Sprintf("%s=%s", - v1alpha1.TestConfigurationLabel, test.Spec.Secret) - } secrets, err := action.client.CoreV1().Secrets(test.Namespace).List(ctx, options) if err != nil { return err } - var found bool for _, item := range secrets.Items { - if item.Labels != nil && item.Labels[v1alpha1.TestConfigurationLabel] != test.Spec.Secret { - continue - } - job.Spec.Template.Spec.Volumes = append(job.Spec.Template.Spec.Volumes, v1.Volume{ - Name: "secrets", + Name: "secret-" + item.Name, VolumeSource: v1.VolumeSource{ Secret: &v1.SecretVolumeSource{ SecretName: item.Name, }, }, }) - found = true - break + + job.Spec.Template.Spec.Containers[0].VolumeMounts = append(job.Spec.Template.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ + Name: "secret-" + item.Name, + MountPath: "/etc/yaks/secrets", + }) + } + + for _, secretName := range test.Spec.Secrets { + job.Spec.Template.Spec.Volumes = append(job.Spec.Template.Spec.Volumes, v1.Volume{ + Name: "secret-" + secretName, + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: secretName, + }, + }, + }) + + job.Spec.Template.Spec.Containers[0].VolumeMounts = append(job.Spec.Template.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ + Name: "secret-" + secretName, + MountPath: "/etc/yaks/secrets", + }) } - if !found { + if len(test.Spec.Secrets) == 0 && len(secrets.Items) == 0 { job.Spec.Template.Spec.Volumes = append(job.Spec.Template.Spec.Volumes, v1.Volume{ Name: "secrets", VolumeSource: v1.VolumeSource{ diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go index 1ceb0934..2f9f946f 100644 --- a/pkg/resources/resources.go +++ b/pkg/resources/resources.go @@ -49,16 +49,16 @@ var assets = func() http.FileSystem { "/crd/bases/yaks.citrusframework.org_instances.yaml": &vfsgen۰CompressedFileInfo{ name: "yaks.citrusframework.org_instances.yaml", modTime: time.Time{}, - uncompressedSize: 3332, + uncompressedSize: 3379, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x56\x5d\x8f\xdb\xb6\x12\x7d\xd7\xaf\x18\xac\x1f\x72\x2f\xb0\x96\xb3\xb9\xc0\x45\xe1\x3e\xb9\xce\xb6\x35\x92\x7a\x17\x6b\x27\x41\x1e\x29\x71\x2c\x4d\x96\x22\x59\x7e\xd8\x71\x8b\xfe\xf7\x62\x28\xc9\x6b\xd9\xde\x34\x68\x53\x3d\x49\xc3\xe1\x9c\xc3\x33\x9c\x19\x8d\x60\xfc\xed\x9e\x6c\x04\x73\x63\xf7\x8e\xaa\x3a\x40\xa8\x11\x8c\xa3\x8a\xb4\x50\x20\x62\xa8\x8d\x03\xe3\xba\x37\x9f\x67\xa3\x6c\x04\x6f\xa9\x44\xed\x51\x42\xd4\x12\x5d\xda\x32\xb3\xa2\xac\xb1\x5f\xb9\x86\xf7\xe8\x3c\x19\x0d\xaf\xf2\x97\xf0\x1f\x76\xb8\xea\x96\xae\xfe\xfb\x7d\x36\x82\xbd\x89\xd0\x88\x3d\x68\x13\x20\x7a\x84\x50\x93\x87\x0d\x29\x04\xfc\x5c\xa2\x0d\x40\x1a\x4a\xd3\x58\x45\x42\x97\x08\x3b\x0a\x75\x82\xe9\x82\xe4\xd9\x08\x3e\x76\x21\x4c\x11\x04\x69\x10\x50\x1a\xbb\x07\xb3\x39\xf6\x03\x11\x12\x61\x00\xa8\x43\xb0\xd3\xc9\x64\xb7\xdb\xe5\x22\x71\xcd\x8d\xab\x26\xaa\xf5\xf3\x93\xb7\x8b\xf9\xed\x72\x75\x3b\x7e\x95\xbf\x4c\x3b\xde\x69\x85\xde\x83\xc3\x5f\x23\x39\x94\x50\xec\x41\x58\xab\xa8\x14\x85\x42\x50\x62\x97\x44\xa9\x1c\xa2\x84\x60\x98\xee\xce\x51\x20\x5d\x5d\x83\x37\x9b\xb0\x13\x0e\xb3\x11\x48\xf2\xc1\x51\x11\xc3\x40\xab\x9e\x1c\xf9\x81\x83\xd1\x20\x34\x5c\xcd\x56\xb0\x58\x5d\xc1\x0f\xb3\xd5\x62\x75\x9d\x8d\xe0\xc3\x62\xfd\xf3\xdd\xbb\x35\x7c\x98\x3d\x3c\xcc\x96\xeb\xc5\xed\x0a\xee\x1e\x60\x7e\xb7\x7c\xbd\x58\x2f\xee\x96\x2b\xb8\xfb\x11\x66\xcb\x8f\xf0\x66\xb1\x7c\x7d\x0d\x48\xa1\x46\x07\xf8\xd9\x3a\xe6\x6f\x1c\x10\xab\x88\x92\x25\x5b\x21\x0e\x08\x6c\x4c\x4b\xc8\x5b\x2c\x69\x43\x25\x28\xa1\xab\x28\x2a\x84\xca\x6c\xd1\x69\xd2\x15\x58\x74\x0d\x79\xce\xa5\x07\xa1\x65\x36\x02\x45\x0d\x05\x11\x92\xe5\xec\x50\x0c\xf3\x2d\xaf\x66\x26\x2c\x75\x77\x69\x0a\xc2\x12\x7e\x0e\xa8\x13\x9b\xfc\xf1\x3b\x9f\x93\x99\x6c\x6f\xb2\x47\xd2\x72\x0a\xf3\xe8\x83\x69\x1e\xd0\x9b\xe8\x4a\x7c\x8d\x1b\xd2\xc4\x2c\xb3\x06\x83\x90\x22\x88\x69\x06\xa0\x44\x81\xca\xf3\x1b\x70\x42\xa7\xb0\x17\x8f\x3e\x03\x10\x5a\x9b\xee\x50\xed\x62\x69\x74\x70\x46\x29\x74\xe3\x0a\x75\xfe\x18\x0b\x2c\x22\x29\x89\x2e\x81\xf6\x94\xb6\x2f\xf3\xff\xe7\x37\x19\x40\xe9\x30\x6d\x5f\x53\x83\x3e\x88\xc6\x4e\x41\x47\xa5\x32\x00\x2d\x1a\x9c\x02\x69\x1f\xf8\x2e\xfb\x9c\x11\xf3\x92\x82\x8b\x7e\xe3\x44\x83\x3b\xe3\x1e\xf9\x32\x66\x9c\x06\x06\xaf\x9c\x89\x1d\xb3\x8b\x7e\x6d\xc8\x9e\xa7\x08\x58\x19\x47\xfd\xf7\xb8\x3f\x11\xbf\x06\xf4\x7c\x27\xd3\x57\x2b\xd2\xa2\xa3\x91\x4c\x8a\x7c\x78\x33\x30\xbf\x25\x1f\xd2\x92\x55\xd1\x09\x75\x44\x3b\x59\x3d\xe9\x2a\x2a\xe1\x9e\xec\x19\x80\x2f\x8d\xc5\x29\x2c\x99\x93\x15\x25\xca\x0c\xa0\xd3\x27\x71\x1a\x83\x90\x32\x65\x42\xa8\x7b\x47\x3a\xa0\x9b\x1b\x15\x1b\x7d\x60\x2c\xd1\x97\x8e\x6c\x48\x8a\xae\x5d\x44\xa0\x0d\x7c\x9c\xbd\x59\x1d\x60\xb8\x56\x2a\x65\x0a\xa1\xd2\x16\x80\x4f\xde\xe8\x7b\x11\xea\x29\xe4\x2c\x5b\x6e\x2c\x3a\x11\x8c\xcb\x07\x5e\xad\xf4\x3f\x1d\x9b\xc2\x9e\xc9\x16\xc6\x28\x14\xfa\x22\x7e\x8d\x2d\x76\x1f\x12\xac\x91\x29\xd2\x5f\x41\x5b\x23\x07\xb8\xf7\x87\xef\x16\x94\x4b\xbd\x4b\xc6\x73\x98\x9d\x6e\x17\x90\x82\x08\xd1\xe7\xc3\xf5\x16\xe6\xfd\xc0\x76\x06\xd5\x3a\x6d\x6f\x84\xb2\xb5\xb8\x69\xd3\x58\xd6\xd8\x88\x69\xb7\xc3\x58\xd4\xb3\xfb\xc5\xfb\xff\xad\x06\x66\x18\x52\x5c\x1c\x65\x82\xeb\xbd\x75\x3e\xb4\x10\xbe\x74\x87\x6c\xe5\x87\x10\xd6\xb1\x3a\xe1\x70\x3b\xdb\xe7\xa8\xa6\x8f\xac\x27\x80\x2f\x98\x53\x37\x45\x24\x17\x33\xb6\xc0\x9d\x04\x28\xbb\x63\xb4\x2d\x9f\xb8\x57\x73\xcf\x43\xdd\x96\xf1\x20\x30\xb0\x93\xd0\x60\x8a\x4f\x58\x86\x1c\x56\xe8\x38\x0c\xf8\xda\x44\x25\xb9\xd6\xb7\xe8\x02\x38\x2c\x4d\xa5\xe9\xb7\x43\x6c\xcf\xbd\x9d\x41\x95\xe0\x52\x3a\x89\x99\xae\x32\x8f\xc9\xad\x50\x11\xaf\xb9\x3d\xa6\x89\xe4\x90\x51\x20\xea\xa3\x78\xc9\xc5\xe7\xf0\x8b\x71\x08\xa4\x37\x66\x9a\x26\x92\x9f\x4e\x26\x15\x85\xbe\x97\x95\xa6\x69\xa2\xa6\xb0\x9f\xa4\xf6\xc3\x83\xc1\x38\x3f\x91\xb8\x45\x35\xf1\x54\x8d\x85\x2b\x6b\x0a\x58\x86\xe8\x70\x22\x2c\x8d\x13\x75\x9d\xfa\x56\xde\xc8\x91\xeb\xba\x9f\x7f\x31\xe0\x7a\x76\x29\xda\x27\xb5\x84\x2f\x64\x80\x7b\x03\xe7\x5b\x74\x5b\xdb\x53\x3c\x09\xcd\x26\x56\xe7\xe1\x76\xb5\x86\x1e\x3a\x25\xe3\x54\xfd\xa4\xfb\xd3\x46\xff\x94\x02\x16\x8c\xf4\x26\x4d\x11\xfe\x07\x70\xa6\x49\x31\x51\x4b\x6b\x48\xb7\x3f\x24\xa5\x22\xd4\xa7\xf2\xfb\x58\x34\x14\xda\x19\x8d\x3e\x70\xae\x72\x98\xa7\x46\x0e\x05\x42\xb4\x52\x04\x94\x39\x2c\x34\xcc\x45\x83\x6a\x2e\x3c\xfe\xeb\x09\x60\xa5\xfd\x98\x85\xfd\xba\x14\x1c\xcf\xa6\x53\xe7\x56\xb5\xa3\x85\x7e\x40\x3c\x93\xaf\xbe\x44\x57\x16\x4b\xae\xbc\x2d\xc9\xae\x66\xb8\x7b\x60\xaa\x81\x61\xa1\x0e\x62\x5d\xae\x55\x68\x3b\x44\xea\x70\xa7\xf6\x13\xfc\xbb\xce\x8d\xf1\xc7\xe3\xfc\xcc\xf9\x79\x00\x7e\xda\xc6\x7d\x69\xe5\x52\xd3\x1e\x3e\xba\x9f\x3d\x5f\xda\x7e\xa6\xfd\x81\x97\x91\x7f\x63\x5f\xff\x6b\x78\xbe\x75\x3c\x1c\x55\xa7\xf1\xce\xd2\xfa\x7c\xbe\x53\xd3\xff\x9a\x8c\x27\xc7\x41\x9b\x34\x85\xe7\x0a\x93\xff\x34\xf7\xdb\x4b\x8d\xfa\x8b\xe2\x5c\x3c\xcc\x99\xb1\x65\x37\x85\xe0\x62\x4b\xc5\x07\xe3\x44\x85\xc7\x96\x58\x1c\xfa\x59\x8f\xdf\x49\x02\xbf\xff\x91\xfd\x19\x00\x00\xff\xff\x78\x77\x5f\x81\x04\x0d\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x56\x4d\x8f\xdb\x36\x10\xbd\xeb\x57\x0c\xd6\x97\x16\x58\xcb\xbb\x29\x0a\x14\xee\xc9\x75\xb6\xad\x91\x74\x77\xb1\xda\x24\xc8\x91\x92\xc6\xd2\x64\x29\x92\xe5\x87\x1d\xf7\xe3\xbf\x17\x43\x4a\x8e\x65\x3b\x69\xda\x06\xd5\x49\x1a\x0e\xe7\x3d\xbe\xe1\xcc\x68\x02\xd3\x2f\xf7\x64\x13\x58\x6a\xb3\xb3\xd4\xb4\x1e\x7c\x8b\xa0\x2d\x35\xa4\x84\x04\x11\x7c\xab\x2d\x68\xdb\xbf\xb9\x3c\x9b\x64\x13\x78\x49\x15\x2a\x87\x35\x04\x55\xa3\x8d\x5b\x16\x46\x54\x2d\x0e\x2b\x97\xf0\x1a\xad\x23\xad\xe0\x59\x7e\x05\x5f\xb1\xc3\x45\xbf\x74\xf1\xf5\xf7\xd9\x04\x76\x3a\x40\x27\x76\xa0\xb4\x87\xe0\x10\x7c\x4b\x0e\xd6\x24\x11\xf0\x7d\x85\xc6\x03\x29\xa8\x74\x67\x24\x09\x55\x21\x6c\xc9\xb7\x11\xa6\x0f\x92\x67\x13\x78\xdb\x87\xd0\xa5\x17\xa4\x40\x40\xa5\xcd\x0e\xf4\xfa\xd0\x0f\x84\x8f\x84\x01\xa0\xf5\xde\xcc\x67\xb3\xed\x76\x9b\x8b\xc8\x35\xd7\xb6\x99\xc9\xe4\xe7\x66\x2f\x57\xcb\x9b\xdb\xe2\x66\xfa\x2c\xbf\x8a\x3b\x5e\x29\x89\xce\x81\xc5\x5f\x03\x59\xac\xa1\xdc\x81\x30\x46\x52\x25\x4a\x89\x20\xc5\x36\x8a\xd2\x58\xc4\x1a\xbc\x66\xba\x5b\x4b\x9e\x54\x73\x09\x4e\xaf\xfd\x56\x58\xcc\x26\x50\x93\xf3\x96\xca\xe0\x47\x5a\x0d\xe4\xc8\x8d\x1c\xb4\x02\xa1\xe0\x62\x51\xc0\xaa\xb8\x80\x1f\x16\xc5\xaa\xb8\xcc\x26\xf0\x66\xf5\xf8\xf3\xdd\xab\x47\x78\xb3\x78\x78\x58\xdc\x3e\xae\x6e\x0a\xb8\x7b\x80\xe5\xdd\xed\xf3\xd5\xe3\xea\xee\xb6\x80\xbb\x1f\x61\x71\xfb\x16\x5e\xac\x6e\x9f\x5f\x02\x92\x6f\xd1\x02\xbe\x37\x96\xf9\x6b\x0b\xc4\x2a\x62\xcd\x92\x15\x88\x23\x02\x6b\x9d\x08\x39\x83\x15\xad\xa9\x02\x29\x54\x13\x44\x83\xd0\xe8\x0d\x5a\x45\xaa\x01\x83\xb6\x23\xc7\xb9\x74\x20\x54\x9d\x4d\x40\x52\x47\x5e\xf8\x68\x39\x39\x14\xc3\x7c\xc9\xab\x99\x09\x43\xfd\x5d\x9a\x83\x30\x84\xef\x3d\xaa\xc8\x26\x7f\xfa\xce\xe5\xa4\x67\x9b\xeb\xec\x89\x54\x3d\x87\x65\x70\x5e\x77\x0f\xe8\x74\xb0\x15\x3e\xc7\x35\x29\x62\x96\x59\x87\x5e\xd4\xc2\x8b\x79\x06\x20\x45\x89\xd2\xf1\x1b\x70\x42\xe7\xb0\x13\x4f\x2e\x03\x10\x4a\xe9\xfe\x50\x69\xb1\xd2\xca\x5b\x2d\x25\xda\x69\x83\x2a\x7f\x0a\x25\x96\x81\x64\x8d\x36\x82\x0e\x94\x36\x57\xf9\xf5\xb7\xf9\x55\x06\xa0\x44\x87\x73\x20\xe5\x3c\x5f\x59\x97\x73\xe0\xbc\x22\x6f\x83\x5b\x5b\xd1\xe1\x56\xdb\x27\xbe\x73\x19\xab\xcd\x18\x8d\xd5\xa1\x27\x70\xd6\x2f\x85\x1c\xe8\x08\x8f\x8d\xb6\x34\x7c\x4f\x07\xe2\xfc\xea\xd1\xf1\xd5\x8b\x5f\x49\x8b\x55\x4f\x23\x9a\x24\x39\xff\x62\x64\x7e\x49\xce\xc7\x25\x23\x83\x15\xf2\x80\x76\xb4\x3a\x52\x4d\x90\xc2\x7e\xb0\x67\x00\xae\xd2\x06\xe7\x70\xcb\x9c\x8c\xa8\xb0\xce\x00\x7a\x19\x22\xa7\x29\x88\xba\x8e\x82\x0b\x79\x6f\x49\x79\xb4\x4b\x2d\x43\xa7\xf6\x8c\x6b\x74\x95\x25\xe3\xa3\x70\x8f\x36\x20\xd0\x1a\xde\x2e\x5e\x14\x7b\x18\x2e\x89\x46\xea\x52\xc8\xb8\x05\xe0\x9d\xd3\xea\x5e\xf8\x76\x0e\x39\xcb\x96\x6b\x83\x56\x78\x6d\xf3\x91\x57\x92\xfe\xa7\x43\x93\xdf\x31\xd9\x52\x6b\x89\x42\x9d\xc5\x6f\x31\x61\x0f\x21\xc1\xe8\x3a\x46\xfa\x3b\x68\xa3\xeb\x11\xee\xfd\xfe\x3b\x81\x72\x45\xf7\xc9\xf8\x18\x66\xaf\xdb\x19\x24\x2f\x7c\x70\xf9\x78\x3d\xc1\xbc\x1e\xd9\x4e\xa0\x92\xd3\xe6\x5a\x48\xd3\x8a\xeb\x94\xc6\xaa\xc5\x4e\xcc\xfb\x1d\xda\xa0\x5a\xdc\xaf\x5e\x7f\x53\x8c\xcc\x30\xa6\xb8\x3a\xc8\x04\x97\x75\x72\xde\x77\x0a\xbe\x74\xfb\x6c\xe5\xfb\x10\xc6\xb2\x3a\x7e\x7f\x3b\xd3\x73\x50\xba\x07\xd6\x23\xc0\x3f\xa6\xa3\x35\x00\xe6\xd8\x0f\x8f\x9a\x6b\x18\x13\x91\x5e\x12\xac\xfb\x63\xa5\x4e\x4f\xdc\xa2\xb9\xd5\xa1\x4a\xd5\xcb\x66\xa1\x40\x97\xef\xb0\xf2\xf9\x51\xe8\x02\x2d\x87\x01\xd7\xea\x20\x6b\x2e\xf1\x0d\x5a\x0f\x16\x2b\xdd\x28\xfa\x6d\x1f\xdb\x71\x4b\x67\x50\x29\xb8\xb4\x20\x5e\x66\x9e\x87\x1b\x21\x03\x5e\xc6\x3e\x38\x8e\xcc\x83\xc8\x22\x63\x42\x50\x07\xf1\xe2\x06\x77\xcc\xe3\x17\x6d\x11\x48\xad\xf5\x3c\x8e\x25\x37\x9f\xcd\x1a\xf2\x43\x43\xab\x74\xd7\x05\x45\x7e\x37\x8b\x3d\x88\xa7\x83\xb6\x6e\x56\xe3\x06\xe5\xcc\x51\x33\x15\xb6\x6a\xc9\x63\xe5\x83\xc5\x99\x30\x34\x8d\x07\x51\xb1\x79\xe5\x5d\x3d\xb1\x7d\x0b\x74\x23\xd8\x93\x1b\x93\x9e\xd8\x2f\xfe\x41\x7a\xb8\x91\xf0\xe5\x10\x7d\xa8\x74\xc4\x0f\x59\x60\x13\x4b\xf7\x70\x53\x3c\xc2\xc0\x24\x65\x2a\x25\xe5\x83\xeb\x89\x2e\x43\x7e\x58\x4d\x52\xeb\x38\x59\xf8\xbf\xc0\xea\x2e\xc6\x44\x55\x1b\x4d\x2a\xfd\xa4\x54\x92\x50\x79\x70\xa1\xec\xc8\xa7\x49\x8d\xce\x73\xea\x8e\xc3\x2e\x63\x73\x87\x12\x21\x98\x5a\x78\x9e\x85\x63\x87\x95\x82\xa5\xe8\x50\x2e\x85\xc3\xff\x39\x57\x9c\x15\x37\xe5\x24\x7c\x56\xb6\x0e\x47\xd9\xb1\x73\x92\xf7\x60\x61\x18\x34\x1f\x49\xed\x50\xea\x85\xc1\x8a\x2b\x78\x43\x75\x5f\x6b\xdc\x85\x30\x56\xd2\xb8\xe0\x47\xb1\xce\xd7\x3c\xa4\x4e\x13\x3b\xe5\xb1\xfd\x08\xff\xae\x77\x63\xfc\xe9\xf4\x58\xf7\x4f\x01\xf0\x93\x06\xc0\xb9\x95\x73\xcd\x7f\xfc\xa8\x61\x86\x7d\x6a\xfb\x89\xf6\x7b\x5e\xba\xfe\x17\xfb\x86\x3f\xc9\xd3\xad\xd3\xf1\xc8\x3b\x8e\x77\x92\xd6\x8f\xe7\x3b\x0e\x8f\xcf\xc9\x78\x74\x1c\xb5\x57\x5d\x3a\x2e\xbe\xfa\xbf\xe6\x7e\x73\xae\xe1\x7f\x52\x9c\xb3\x87\x39\x31\x26\x76\x73\xf0\x36\x24\x2a\xce\x6b\x2b\x1a\x3c\xb4\x84\x72\xdf\xf9\x06\xfc\x5e\x12\xf8\xfd\xcf\xec\xaf\x00\x00\x00\xff\xff\x5a\x5f\x5f\x7f\x33\x0d\x00\x00"), }, "/crd/bases/yaks.citrusframework.org_tests.yaml": &vfsgen۰CompressedFileInfo{ name: "yaks.citrusframework.org_tests.yaml", modTime: time.Time{}, - uncompressedSize: 6775, + uncompressedSize: 6876, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x4f\x8f\xe3\xba\x0d\xbf\xfb\x53\x10\x9b\xc3\x6b\x81\x89\xb3\xfb\x0a\x14\x45\x7a\x4a\x33\xb3\x68\xb0\xfb\x32\x83\x49\x76\x1f\xde\x51\xb1\x19\x87\x3b\xb2\xe4\x8a\x52\x66\xd3\xa2\xdf\xbd\x90\xe4\x64\xe3\xfc\xb1\x27\x99\x1d\xa0\x3e\x25\x34\xc9\x1f\xf5\x23\x45\x4a\xee\x41\xff\xe7\x3d\x49\x0f\xc6\xba\xda\x18\x2a\x56\x16\xec\x0a\x41\x1b\x2a\x48\x09\x09\xc2\xd9\x95\x36\xa0\x4d\xfd\x8b\xd3\xa4\x97\xf4\xe0\x33\x65\xa8\x18\x73\x70\x2a\x47\x13\x4c\x46\x95\xc8\x56\xb8\x7d\x73\x03\x5f\xd1\x30\x69\x05\xbf\xa6\xef\xe1\x4f\x5e\xe1\x5d\xfd\xea\xdd\x9f\xff\x9e\xf4\x60\xa3\x1d\x94\x62\x03\x4a\x5b\x70\x8c\x60\x57\xc4\xb0\x24\x89\x80\xdf\x33\xac\x2c\x90\x82\x4c\x97\x95\x24\xa1\x32\x84\x67\xb2\xab\x00\x53\x3b\x49\x93\x1e\xfc\x51\xbb\xd0\x0b\x2b\x48\x81\x80\x4c\x57\x1b\xd0\xcb\x7d\x3d\x10\x36\x04\x0c\x00\x2b\x6b\xab\xe1\x60\xf0\xfc\xfc\x9c\x8a\x10\x6b\xaa\x4d\x31\x90\x51\x8f\x07\x9f\x27\xe3\xbb\xe9\xec\xae\xff\x6b\xfa\x3e\x58\x7c\x51\x12\x99\xc1\xe0\xbf\x1c\x19\xcc\x61\xb1\x01\x51\x55\x92\x32\xb1\x90\x08\x52\x3c\x07\x52\x0a\x83\x98\x83\xd5\x3e\xdc\x67\x43\x96\x54\x71\x03\xac\x97\xf6\x59\x18\x4c\x7a\x90\x13\x5b\x43\x0b\x67\x1b\x5c\x6d\x83\x23\x6e\x28\x68\x05\x42\xc1\xbb\xd1\x0c\x26\xb3\x77\xf0\x8f\xd1\x6c\x32\xbb\x49\x7a\xf0\xfb\x64\xfe\xcf\xfb\x2f\x73\xf8\x7d\xf4\xf8\x38\x9a\xce\x27\x77\x33\xb8\x7f\x84\xf1\xfd\xf4\x76\x32\x9f\xdc\x4f\x67\x70\xff\x11\x46\xd3\x3f\xe0\xd3\x64\x7a\x7b\x03\x48\x76\x85\x06\xf0\x7b\x65\x7c\xfc\xda\x00\x79\x16\x31\xf7\x94\xcd\x10\x1b\x01\x2c\x75\x0c\x88\x2b\xcc\x68\x49\x19\x48\xa1\x0a\x27\x0a\x84\x42\xaf\xd1\x28\x52\x05\x54\x68\x4a\x62\x9f\x4b\x06\xa1\xf2\xa4\x07\x92\x4a\xb2\xc2\x06\xc9\xd1\xa2\x3c\xcc\xcf\x2c\xcd\x44\x54\x54\xd7\xd2\x10\x44\x45\xf8\xdd\xa2\x0a\xd1\xa4\x4f\x7f\xe3\x94\xf4\x60\xfd\x21\x79\x22\x95\x0f\x61\xec\xd8\xea\xf2\x11\x59\x3b\x93\xe1\x2d\x2e\x49\x91\x8f\x32\x29\xd1\x8a\x5c\x58\x31\x4c\x00\xa4\x58\xa0\x64\xff\x0b\x7c\x42\x87\xb0\x11\x4f\x9c\x00\x08\xa5\x74\xbd\xa8\xf8\x32\xd3\xca\x1a\x2d\x25\x9a\x7e\x81\x2a\x7d\x72\x0b\x5c\x38\x92\x39\x9a\x00\xba\x0d\x69\xfd\x3e\xfd\x6b\xfa\x21\x01\xc8\x0c\x06\xf3\x39\x95\xc8\x56\x94\xd5\x10\x94\x93\x32\x01\x50\xa2\xc4\x21\x58\x64\xcb\xa9\x47\x4b\x33\xb2\xc6\xf1\xd2\x88\x12\x9f\xb5\x79\xf2\x85\x98\xf8\x14\x78\xe0\xc2\x68\x57\x47\x75\x52\x2f\xba\xdb\xc6\x28\x2c\x16\xda\xd0\xf6\x7f\x7f\xbb\x1a\xff\xd3\x03\x92\x2a\xc2\xbf\x48\xd0\x1c\xd9\x86\xbf\x92\xd8\x7e\xda\x89\x3e\x53\x2d\xae\xa4\x33\x42\xd6\xa1\x06\x09\x93\x2a\x9c\x14\x26\xca\x12\x00\xce\x74\x85\x43\x98\xfa\x18\x2a\x91\x61\x9e\x00\xd4\x5c\x84\x18\xfa\x20\xf2\x3c\xb0\x2e\xe4\x83\x21\x65\xd1\x8c\xb5\x74\xa5\xda\x45\x98\x23\x67\x86\x2a\x1b\xd8\x9b\xaf\x30\x78\x86\x6a\x25\x18\x83\x06\xc0\x37\xd6\xea\x41\xd8\xd5\x10\x52\xb6\xc2\x3a\x4e\xf7\xdf\x46\x36\x1f\xf6\x24\x76\xe3\x43\xf2\xfb\xa8\x5e\xed\x29\x10\x6d\x7d\x3b\x2b\xb5\x53\x36\xf4\x88\xdd\x12\x4f\xe1\x19\x64\x27\x2d\xa7\xec\xca\x52\x98\x4d\x1a\xac\x1b\xf8\xf3\x3d\x49\x17\xfe\x83\x60\xdf\x2b\x2f\x83\xac\x82\x51\x73\xcd\xfb\xa2\x2e\xd0\x8f\x82\xe4\xc5\xa0\xcb\x60\xd4\x00\xfd\xb8\x2f\xea\x02\x9d\x3d\x51\x55\x5d\x8c\xca\xd1\xaa\x01\x3b\x6b\xc8\x3a\x33\xec\x4b\x08\x8d\xd1\x06\x72\xb4\x82\xe4\x79\xf0\xa0\xc5\x0d\xac\xbb\x7d\xd1\x11\x54\xd4\x59\x7f\x10\xb2\x5a\x89\x0f\x71\x57\x64\x2b\x2c\xc5\xb0\xb6\xd0\x15\xaa\xd1\xc3\xe4\xeb\x5f\x66\x0d\x31\x9c\x08\x91\x38\xb4\xca\xa8\xb8\xeb\xbe\x81\x2d\x18\x3d\x4c\xd2\x9d\x69\x65\x74\x85\xc6\xee\x36\x76\x7c\xf6\x5a\xe1\x9e\xf4\x00\xe8\x17\x1f\x4b\x3d\x7c\x73\xdf\x03\x31\x82\xd6\xbb\x14\xf3\x3a\xfc\x38\x29\xc9\x8f\x38\x3f\x2a\x50\xc5\xee\xd7\x70\x0c\x5e\x49\x28\xd0\x8b\x6f\x98\xd9\x14\x66\x68\xbc\x1b\xe0\x95\x76\x32\xf7\x2d\x72\x8d\xc6\x82\xc1\x4c\x17\x8a\xfe\xbd\xf3\xcd\x7e\x24\x7a\x50\x29\xec\xb6\xe7\xfc\x78\x42\x57\xf0\xa7\x8b\xb5\x90\x0e\x6f\xfc\x54\x09\x83\xdc\xa0\x47\x01\xa7\xf6\xfc\x05\x15\x4e\xe1\x37\x6d\x10\x48\x2d\xf5\x30\x0c\x72\x1e\x0e\x06\x05\xd9\xed\x08\xc8\x74\x59\x3a\x45\x76\x33\x08\x5d\xdb\xcf\x53\x6d\x78\x90\xe3\x1a\xe5\x80\xa9\xe8\x0b\x93\xad\xc8\x62\x66\x9d\xc1\x81\xa8\xa8\x1f\x42\x57\xa1\xdd\xa7\x65\xde\x33\xf5\xd0\xe0\x5f\x1a\xb1\x1e\x15\x43\x7c\x42\x37\x6d\xc9\x80\x6f\xad\x3e\xd7\xa2\x36\x8d\xab\xf8\x41\xb4\x17\x79\x76\x1e\xef\x66\x73\xd8\x42\x87\x64\x1c\xb2\x1f\x78\xff\x61\xc8\x3f\x52\xe0\x09\x23\xb5\x0c\xc3\xd7\x1f\x9d\x8c\x2e\x83\x4f\x54\x79\xa5\x49\xc5\x73\x5c\x26\x09\xd5\x21\xfd\xec\x16\x25\xd9\x78\xb4\x09\x95\x67\x75\x0a\xe3\x30\xff\x60\x81\xe0\xaa\x5c\x58\xcc\x53\x98\x28\x18\x8b\x12\xe5\x58\x30\xbe\x79\x02\x3c\xd3\xdc\xf7\xc4\xbe\x2c\x05\xfb\x23\xfd\x50\x39\xb2\xb6\xf7\x62\x3b\x5b\xcf\xe4\xcb\x6f\xcd\x59\x85\x59\x63\xbb\xe4\xc8\xe1\xdc\xe7\xdb\x06\xfa\x6d\x30\x3f\x2c\xe4\xd3\x7b\x14\xe2\xd1\x61\x49\xc5\xa1\xf4\x00\x75\x86\xd6\x17\x02\x07\xe4\x7e\x3f\x3d\xd2\x3e\xef\xbf\xc6\xb0\xa8\xec\xa9\x57\x67\x49\xdb\x3e\xa1\xa5\x5d\x6e\x78\x86\x5d\xff\xa0\x5a\x1f\x3b\x24\x8b\xe5\xc9\xd8\x5f\x80\x22\x8c\x11\x9b\x83\x77\xfe\x08\x96\xeb\xec\xa9\x83\xd8\x4f\x6e\x81\xb7\x3a\x7b\xba\x92\x58\x2a\x45\x71\x0d\x3b\x00\xc6\xa9\x11\x7f\x61\x34\x6d\xd6\xbe\xf9\x15\x68\x2e\x21\x77\xd7\x9c\x2e\xa0\xb8\xc1\xc8\xf6\x48\x7c\x96\x91\x2e\x4e\x3a\xca\xad\x93\x99\xb6\x92\xeb\x34\x6e\x61\xa6\xad\x5a\x8c\x53\x96\x4e\x81\x36\xa9\x89\x5a\x57\xd6\x8a\xd4\x45\x71\x2e\xdd\x67\x53\xf3\x82\x25\xb7\xad\xcb\x3f\x6b\x34\x0b\xcd\xad\x55\xba\xd0\x5a\xa2\x38\x1c\xe7\xad\x6c\x32\x66\x06\x4f\xa4\xb8\x25\x58\x46\x89\x8a\x5c\xd9\xd9\xeb\xa2\xda\x95\x34\x9f\xec\x2e\xf0\xc6\x1c\x5f\xdf\x07\x94\xfe\x3a\x1d\x5f\x93\x9b\xb7\x6b\x21\x71\xff\x77\x65\xa9\xbd\x49\xbc\xdd\x3c\xda\x7e\x75\xf8\xbf\x18\x66\xe7\xce\x10\xe1\xfa\xd0\x75\x8a\x08\x4a\x8d\x73\x84\x5e\xb0\x3f\xb1\x5d\x77\x90\xc8\xa9\x40\xbe\x6c\x47\xc6\xfb\xcd\x45\x26\xe1\x76\xdd\x51\x1b\x3e\xe8\x70\xe7\x3e\x59\x1a\x2d\xce\xeb\xcb\xde\xb1\xfb\x8e\x2d\x7f\x66\x19\xf0\xc6\xbb\x9e\x1d\x59\x9c\x5e\x57\x52\xde\x3a\xdc\x68\x4f\xdb\x76\x8d\xd8\xf6\x45\x43\xe7\xf6\x8f\x4f\xbc\xc2\xbf\xce\x47\xfc\xf6\xf0\x4a\x1f\xa8\x72\x52\x27\x0e\xc1\x97\x38\xa9\xbf\x0c\xbc\xce\x49\xf8\x78\xf3\x3a\x17\x4e\xc5\x2d\xfd\xaa\x48\x5a\xcf\x31\x10\xbf\x02\x5c\x51\xf0\xdd\x65\x05\x90\x49\xc1\xdc\x76\x04\x83\x97\xec\x1c\xd8\x96\xe8\x6f\xc8\x7c\xb6\x5d\x5f\xea\x6c\xee\x35\x5f\xeb\xe9\x27\xac\xad\x23\x3d\xed\x8d\xa3\xc5\xd8\xe7\x75\x72\x7b\x51\x43\x5e\x9f\xfa\xc8\xd3\x6a\x73\x12\xff\x48\x18\x27\xd1\x10\xac\x71\xf1\xdb\x29\x5b\x6d\x7c\x22\xf7\x24\x6e\x71\x74\xdd\xa8\x47\x1f\xfc\xe7\xbf\xc9\xff\x02\x00\x00\xff\xff\x08\x02\x0a\x82\x77\x1a\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x18\xdb\x8e\xda\x46\xf4\xdd\x5f\x71\xb4\xbc\xb4\xd2\x62\x76\x53\x55\xaa\xe8\x13\x65\x37\x2a\x4a\xc2\xae\x16\x92\x28\x8f\x83\x7d\x30\x27\x8c\x67\xdc\xb9\x40\xe8\xe5\xdf\xab\x99\xb1\x09\xe6\x62\x2f\x6c\x52\x75\x9e\xe0\xcc\xb9\xdf\x3d\x1d\xe8\x7e\xbb\x13\x75\x60\x28\x8b\x8d\xa2\x6c\x61\xc0\x2c\x10\xa4\xa2\x8c\x04\xe3\xc0\xac\x59\x48\x05\x52\x95\xbf\x74\x1c\x75\xa2\x0e\xbc\xa5\x04\x85\xc6\x14\xac\x48\x51\x79\x92\x41\xc1\x92\x05\x56\x37\xd7\xf0\x01\x95\x26\x29\xe0\x55\x7c\x03\x3f\x38\x84\xab\xf2\xea\xea\xc7\x5f\xa3\x0e\x6c\xa4\x85\x9c\x6d\x40\x48\x03\x56\x23\x98\x05\x69\x98\x13\x47\xc0\x2f\x09\x16\x06\x48\x40\x22\xf3\x82\x13\x13\x09\xc2\x9a\xcc\xc2\x8b\x29\x99\xc4\x51\x07\x3e\x95\x2c\xe4\xcc\x30\x12\xc0\x20\x91\xc5\x06\xe4\x7c\x17\x0f\x98\xf1\x0a\x03\xc0\xc2\x98\xa2\xdf\xeb\xad\xd7\xeb\x98\x79\x5d\x63\xa9\xb2\x1e\x0f\x78\xba\xf7\x76\x34\xbc\x1f\x4f\xee\xbb\xaf\xe2\x1b\x4f\xf1\x5e\x70\xd4\x1a\x14\xfe\x61\x49\x61\x0a\xb3\x0d\xb0\xa2\xe0\x94\xb0\x19\x47\xe0\x6c\xed\x9d\x92\x29\xc4\x14\x8c\x74\xea\xae\x15\x19\x12\xd9\x35\x68\x39\x37\x6b\xa6\x30\xea\x40\x4a\xda\x28\x9a\x59\x53\xf3\x55\xa5\x1c\xe9\x1a\x82\x14\xc0\x04\x5c\x0d\x26\x30\x9a\x5c\xc1\x6f\x83\xc9\x68\x72\x1d\x75\xe0\xe3\x68\xfa\xfb\xc3\xfb\x29\x7c\x1c\x3c\x3d\x0d\xc6\xd3\xd1\xfd\x04\x1e\x9e\x60\xf8\x30\xbe\x1b\x4d\x47\x0f\xe3\x09\x3c\xbc\x86\xc1\xf8\x13\xbc\x19\x8d\xef\xae\x01\xc9\x2c\x50\x01\x7e\x29\x94\xd3\x5f\x2a\x20\xe7\x45\x4c\x9d\xcb\x26\x88\x35\x05\xe6\x32\x28\xa4\x0b\x4c\x68\x4e\x09\x70\x26\x32\xcb\x32\x84\x4c\xae\x50\x09\x12\x19\x14\xa8\x72\xd2\x2e\x96\x1a\x98\x48\xa3\x0e\x70\xca\xc9\x30\xe3\x21\x07\x46\x39\x31\xdf\x32\x35\x23\x56\x50\x99\x4b\x7d\x60\x05\xe1\x17\x83\xc2\x6b\x13\x2f\x7f\xd1\x31\xc9\xde\xea\x36\x5a\x92\x48\xfb\x30\xb4\xda\xc8\xfc\x09\xb5\xb4\x2a\xc1\x3b\x9c\x93\x20\xa7\x65\x94\xa3\x61\x29\x33\xac\x1f\x01\x70\x36\x43\xae\xdd\x2f\x70\x01\xed\xc3\x86\x2d\x75\x04\xc0\x84\x90\xa5\x51\xe1\x32\x91\xc2\x28\xc9\x39\xaa\x6e\x86\x22\x5e\xda\x19\xce\x2c\xf1\x14\x95\x17\x5a\xa9\xb4\xba\x89\x6f\x7f\x8e\x6f\x22\x00\xc1\x72\xec\x83\x41\x6d\x74\xec\x98\xc6\x09\x19\x65\xf5\x5c\xb1\x1c\xd7\x52\x2d\x5d\xbe\x45\xce\xd3\x8e\x7f\xa6\xa4\x2d\x85\x1f\xc5\x0b\xec\x2a\x55\x98\xc1\x4c\x2a\xaa\xfe\x77\x2b\xa5\xdd\x4f\x27\x90\x44\xe6\xff\x05\x3f\x4c\x51\x1b\xff\x97\x93\x36\x6f\xb6\xa0\xb7\x54\x82\x0b\x6e\x15\xe3\xa5\xaa\x1e\xa2\x49\x64\x96\x33\x15\x60\x11\x80\x4e\x64\x81\x7d\x18\x3b\x1d\x0a\x96\x60\x1a\x01\x94\x26\x7b\x1d\xba\xc0\xd2\xd4\x3b\x97\xf1\x47\x45\xc2\xa0\x1a\x4a\x6e\x73\xb1\xd5\x30\x45\x9d\x28\x2a\x8c\x77\xd2\x74\x81\x9e\x33\x14\x0b\xa6\xd1\x63\x00\x7c\xd6\x52\x3c\x32\xb3\xe8\x43\xac\x0d\x33\x56\xc7\xbb\xb7\xc1\x9b\x8f\x3b\x10\xb3\x71\x2a\xb9\x72\x29\xad\x3d\x26\x44\x1a\xd7\xb5\x72\x69\x85\xf1\xad\x60\x6b\xe2\x31\x79\x0a\xb5\xe5\x46\xc7\xda\xe6\x39\x53\x9b\xd8\x53\xd7\xe4\x4f\x77\x20\x6d\xf2\x1f\x99\x76\x2d\xf1\x3c\x91\x85\x27\xaa\xdb\xbc\x0b\x6a\x13\xfa\x9a\x11\x3f\x5b\xe8\xdc\x13\xd5\x84\xbe\xde\x05\xb5\x09\x9d\x2c\xa9\x28\xce\x96\xaa\x03\x55\x4d\xec\xa4\x06\x6b\x8d\xb0\x4b\x21\x54\x4a\x2a\x48\xd1\x30\xe2\xa7\x85\x7b\x2c\x5d\x93\x75\xbf\x0b\x3a\x10\x15\x70\x56\xb7\x8c\x17\x0b\x76\x1b\xaa\x22\x59\x60\xce\xfa\x25\x85\x2c\x50\x0c\x1e\x47\x1f\x7e\x9a\xd4\xc0\x70\x44\x45\xd2\xbe\x23\x06\xc4\x6d\x93\xf5\xde\x82\xc1\xe3\x28\xde\x92\x16\x4a\x16\xa8\xcc\xb6\xb0\xc3\xd9\xe9\x78\x3b\xd0\x3d\x41\x7f\x77\x6b\x77\xe0\x18\x57\x33\x37\x75\xad\x0f\x83\x12\x65\xd5\x62\x5a\x9a\x13\x06\x24\xb9\xc9\xe6\x26\x04\x8a\xd0\xf4\x1c\x98\x09\x90\xb3\xcf\x98\x98\x78\x8f\xf5\x04\x95\x63\x03\x7a\x21\x2d\x4f\x5d\x67\x5c\xa1\x32\xa0\x30\x91\x99\xa0\x3f\xb7\xbc\xb5\x9b\x84\x4e\x28\x67\xbe\xda\x7d\x5f\x70\x6b\xc4\x8a\x71\x8b\xd7\x7e\x7c\xd4\x39\xbb\xf9\xad\xd0\xc9\x04\x2b\x76\xf8\x79\x02\xbd\xaf\xc7\x3b\xa9\x10\x48\xcc\x65\xdf\x4f\x73\xdd\xef\xf5\x32\x32\xd5\x1c\x48\x64\x9e\x5b\x41\x66\xd3\xf3\xad\xdb\x0d\x55\xa9\x74\x2f\xc5\x15\xf2\x9e\xa6\xac\xcb\x54\xb2\x20\x83\x89\xb1\x0a\x7b\xac\xa0\xae\x37\x44\xf8\x9e\x1f\xe7\x69\x47\x95\x93\x43\xd7\xc4\x1e\x64\x4a\x38\xbe\xd5\x9e\x11\x1e\xd7\x87\x5d\x62\xb0\x92\x55\x30\xf1\x6b\x14\x1c\xc8\xb9\xee\xe9\x7e\x32\x85\x4a\x93\x10\xa9\x10\x94\xaf\xa8\x07\x7e\xa9\xe2\xe3\xbc\x49\x62\xee\x07\xb2\x5b\xa7\x94\xcc\x3d\x4f\x14\x69\x21\x49\x84\xdd\x2e\xe1\x84\xc2\x80\xb6\xb3\x9c\x4c\x58\x70\x7c\x62\x1a\xb9\xcf\x76\xe8\x67\x22\xcc\x10\x6c\x91\x32\xe3\x56\x88\x3a\xc2\x48\xc0\x90\xe5\xc8\x87\xcc\xcd\xfd\xff\x34\x56\x2e\x2a\xba\xeb\x82\xf0\xac\x68\xed\x6e\x00\xfb\xc8\xc1\xbd\x3b\x17\xd5\x8c\x3e\x11\x5a\x57\xe2\x93\x02\x93\x5a\x99\xa5\xa8\xfd\x9a\xe8\xda\x0f\xba\x62\xda\x0e\xe1\xea\x1c\xaf\x75\x08\x9b\xc6\x9c\xb2\x7d\xe8\x9e\xd4\x09\x1a\x97\x23\xda\x4b\xee\x76\xf7\xdd\xdd\xc4\xbf\x94\x61\x50\x98\x63\x57\x27\x9d\x56\x1d\xdf\x1a\xcf\x27\x3c\xe1\x5d\x77\x50\xac\x0e\x19\x92\xc1\xfc\xa8\xee\xcf\x90\xc2\x94\x62\x9b\xbd\x3b\xb7\xb1\xa5\x32\x59\xb6\x38\xf6\x8d\x9d\xe1\x9d\x4c\x96\x17\x3a\x96\x72\x96\x5d\xe2\x1d\x00\x65\xc5\x40\xbf\xd7\xa8\x9a\xa8\x5d\x0b\xcd\x50\x9d\xe3\xdc\x6d\x1b\x3b\xc3\xc5\x35\x8f\x54\x1b\xf4\x49\x8f\xb4\xf9\xa4\x25\xdd\x5a\x3d\xd3\x94\x72\xad\xc4\x0d\x9e\x69\xca\x16\x65\x85\xa1\x63\x42\xeb\xae\x09\x58\x17\xe6\x0a\x97\x59\x76\x2a\xdc\x27\x43\xf3\x0c\x93\x9b\xec\x72\x67\x85\x6a\x26\x75\x63\x96\xce\xa4\xe4\xc8\xc4\x39\x79\xa6\x31\x51\x68\xce\xc9\xb2\x0b\x0b\x59\x23\x47\x41\x36\x6f\xed\x90\x01\xed\xc2\xe0\x1c\xed\x49\x8d\xe6\xb4\x9a\xd4\x6c\x16\xbc\xa8\x7b\x08\xf9\x61\x3c\xbc\x24\xa2\xdf\xaf\xf1\x84\xae\xd1\x16\xa5\xe6\xd6\xf2\xfd\xa6\x58\xf5\xb4\xf1\xbf\x18\x81\xa7\x36\x0f\xff\xf1\xd2\xb6\x7b\x78\xa4\xda\xf6\x21\x67\xda\xad\x80\x97\xad\x1f\x29\x65\xa8\x8f\xf8\xb4\xc1\xb2\xf0\x75\x75\x16\x89\xff\xb6\x6f\xc9\x0d\xa7\xb4\xff\xe2\x3f\x9a\x1a\x0d\xcc\xcb\x4f\xcd\x43\xf6\x2d\x25\x7f\xc2\x0c\xf8\xce\x55\xaf\x2d\x19\x1c\x5f\x96\x52\x8e\xda\x7f\x4f\x1f\xa7\x6d\x1b\xcc\xcd\x46\x43\x6b\xf9\x87\x13\x1e\x10\x5e\xc6\x23\xbc\x7c\xbc\x90\x07\x8a\x94\xc4\x91\xd5\xf9\x1c\x26\xe5\xbb\xc4\xcb\x98\xf8\xa7\xa3\x97\xb1\xb0\x22\x94\xf4\x8b\x34\x69\xdc\x7e\x20\xbc\x41\x5c\x90\xf0\xed\x69\x05\x90\x70\xa6\x75\xd3\xe2\x06\xcf\xa9\x1c\xa8\x52\xf4\x1d\x6a\x7d\xb2\x5d\x9f\xcb\x6c\xea\x30\x5f\xca\xe9\x1b\xd8\xd6\x12\x9e\xe6\xc6\xd1\x40\xec\xe2\x3a\xba\x3b\xab\x21\xaf\x8e\x3d\x31\x35\xd2\x1c\x95\x7f\x00\x0c\x93\xa8\x0f\x46\xd9\xf0\x72\xab\x8d\x54\x2e\x90\x3b\x10\x3b\x3b\xf8\x48\x29\x47\x1f\xfc\xf5\x4f\xf4\x6f\x00\x00\x00\xff\xff\x20\x74\xbb\xc4\xdc\x1a\x00\x00"), }, "/infrastructure": &vfsgen۰DirInfo{ name: "infrastructure", diff --git a/pkg/util/envvar/envvar.go b/pkg/util/envvar/envvar.go index 68acf8cc..9c238bbf 100644 --- a/pkg/util/envvar/envvar.go +++ b/pkg/util/envvar/envvar.go @@ -18,6 +18,7 @@ package envvar import ( "os" + "strings" corev1 "k8s.io/api/core/v1" ) @@ -94,3 +95,12 @@ func GetOperatorNamespace() string { return "" } + +// IsCurrentOperatorGlobal returns true if the operator is configured to watch all namespaces. +func IsCurrentOperatorGlobal() bool { + if watchNamespace, envSet := os.LookupEnv(WatchNamespaceEnv); !envSet || strings.TrimSpace(watchNamespace) == "" { + return true + } + + return false +} diff --git a/script/gen_client.sh b/script/gen_client.sh index 87fd6da4..7e56fd32 100755 --- a/script/gen_client.sh +++ b/script/gen_client.sh @@ -24,6 +24,10 @@ GO111MODULE=on # Entering the client module cd $rootdir/pkg/client/yaks +rm -rf ./clientset +rm -rf ./informers +rm -rf ./listers + echo "Generating Go client code..." $(go env GOPATH)/bin/client-gen \ @@ -31,29 +35,22 @@ $(go env GOPATH)/bin/client-gen \ --go-header-file=$rootdir/script/headers/default.txt \ --clientset-name "versioned" \ --input-base=github.com/citrusframework/yaks/pkg/apis \ - --output-base=. \ - --output-package=github.com/citrusframework/yaks/pkg/client/yaks/clientset + --output-dir=clientset \ + --output-pkg=github.com/citrusframework/yaks/pkg/client/yaks/clientset $(go env GOPATH)/bin/lister-gen \ - --input-dirs=github.com/citrusframework/yaks/pkg/apis/yaks/v1alpha1 \ + $rootdir/pkg/apis/yaks/v1alpha1 \ --go-header-file=$rootdir/script/headers/default.txt \ - --output-base=. \ - --output-package=github.com/citrusframework/yaks/pkg/client/yaks/listers + --output-dir=listers \ + --output-pkg=github.com/citrusframework/yaks/pkg/client/yaks/listers $(go env GOPATH)/bin/informer-gen \ + $rootdir/pkg/apis/yaks/v1alpha1 \ --versioned-clientset-package=github.com/citrusframework/yaks/pkg/client/yaks/clientset/versioned \ --listers-package=github.com/citrusframework/yaks/pkg/client/yaks/listers \ - --input-dirs=github.com/citrusframework/yaks/pkg/apis/yaks/v1alpha1 \ --go-header-file=$rootdir/script/headers/default.txt \ - --output-base=. \ - --output-package=github.com/citrusframework/yaks/pkg/client/yaks/informers - -# hack to fix non go-module compliance -rm -rf ./clientset -rm -rf ./informers -rm -rf ./listers -cp -R ./github.com/citrusframework/yaks/pkg/client/yaks/* . -rm -rf ./github.com + --output-dir=informers \ + --output-pkg=github.com/citrusframework/yaks/pkg/client/yaks/informers # hack to fix test custom resource generated fake. otherwise generated fake file is handled as test scoped file mv $rootdir/pkg/client/yaks/clientset/versioned/typed/yaks/v1alpha1/fake/fake_test.go \ diff --git a/script/gen_crd.sh b/script/gen_crd.sh index 3b01a713..f5fa44cf 100755 --- a/script/gen_crd.sh +++ b/script/gen_crd.sh @@ -24,11 +24,7 @@ apidir=$location/../pkg/apis/yaks echo "Generating CRDs..." cd "$apidir" -$(go env GOPATH)/bin/controller-gen crd \ - paths=./... \ - output:crd:artifacts:config=../../../config/crd/bases \ - output:crd:dir=../../../config/crd/bases \ - crd:crdVersions=v1 +$(go env GOPATH)/bin/controller-gen paths=./... output:crd:artifacts:config=../../../config/crd/bases output:crd:dir=../../../config/crd/bases crd:crdVersions=v1 # cleanup working directory in $apidir rm -rf ./config