diff --git a/.github/workflows/agent-integration-test.yml b/.github/workflows/agent-integration-test.yml new file mode 100644 index 000000000..bdefdbf7e --- /dev/null +++ b/.github/workflows/agent-integration-test.yml @@ -0,0 +1,129 @@ +name: start and run agent cucumber integration tests +on: + workflow_dispatch: + pull_request_target: + types: [labeled] +concurrency: + group: integration-test-${{ github.event.number || github.run_id }} + cancel-in-progress: true +env: + GH_TOKEN: ${{ secrets.APK_BOT_TOKEN }} +jobs: + runs_agent_cucumber_integration_tests_on_pull_request: + if: github.event_name == 'pull_request_target' && contains(github.event.label.name, 'trigger-action') + runs-on: ubuntu-latest + steps: + - uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Create AKS Cluster and set context + uses: azure/CLI@v1 + with: + azcliversion: 2.44.1 + inlineScript: | + az aks create --resource-group "${{ secrets.AZURE_RESOURCE_GROUP }}" --name "agent-integ-${{ secrets.AKS_CLUSTER_NAME }}-${{ github.event.number || github.run_id }}" --enable-cluster-autoscaler --min-count 1 --max-count 3 --location "southeastasia" --generate-ssh-keys + - uses: azure/aks-set-context@v3 + with: + resource-group: '${{ secrets.AZURE_RESOURCE_GROUP }}' + cluster-name: 'go-integ-${{ secrets.AKS_CLUSTER_NAME }}-${{ github.event.number || github.run_id }}' + - name: Create Namespace apk + shell: sh + run: | + kubectl create namespace apk + kubectl get ns + - name: Checkout apk-repo. + uses: actions/checkout@v3 + with: + fetch-depth: "0" + path: apk-repo + token: ${{ secrets.APK_BOT_TOKEN }} + - name: Set release username and email + shell: sh + run: | + git config --global user.name ${{ secrets.APK_BOT_USER }} + git config --global user.email ${{ secrets.APK_BOT_EMAIL }} + + - name: checkout pull request and merge. + shell: sh + if: github.event_name == 'pull_request_target' && contains(github.event.label.name, 'trigger-action') + run: | + cd apk-repo + gh pr checkout ${{ github.event.number }} -b pr-${{ github.event.number }} + git checkout pr-${{ github.event.number }} + git merge origin/main + + - name: Helm release deploy APIM CP + if: github.event_name == 'pull_request_target' && contains(github.event.label.name, 'trigger-action') + shell: sh + run: | + cd apk-repo/test/apim-apk-agent-test/apim-cp-helm-chart + helm repo add bitnami https://charts.bitnami.com/bitnami + helm repo add jetstack https://charts.jetstack.io + helm dependency build + helm install apim -n apk . --debug --wait --timeout 5m0s \ + --set deployment.image.respository=sampathrajapakse/wso2am \ + --set deployment.image.tag=4.3.0 \ + kubectl get pods -n apk + kubectl get svc -n apk + + - name: Helm release deploy APK DP + if: github.event_name == 'pull_request_target' && contains(github.event.label.name, 'trigger-action') + shell: sh + run: | + cd /helm-charts + helm dependency build + helm install apk-test-setup -n apk . --debug --wait --timeout 15m0s \ + kubectl get pods -n apk + kubectl get svc -n apk + + - name: Helm release deploy APIM APK Agent + if: github.event_name == 'pull_request_target' && contains(github.event.label.name, 'trigger-action') + shell: sh + run: | + cd apk-repo/test/apim-apk-agent-test/agent-helm-chart + helm dependency build + helm install apim-apk-agent -n apk . --debug --wait --timeout 2m0s \ + --set controlPlane.serviceURL=https://apim-wso2am-cp-1-service:9443/ \ + --set controlPlane.eventListeningEndpoints=amqp://admin:admin@apim-wso2am-cp-1-service:5673?retries='10'&connectdelay='30' \ + --set dataPlane.k8ResourceEndpoint=https://apk-wso2-apk-config-ds-service.apk.svc.cluster.local:9443/api/configurator/apis/generate-k8s-resources \ + kubectl get pods -n apk + kubectl get svc -n apk + - name: Run test cases + shell: sh + run: | + cd apk-repo/test/apim-apk-agent-test/cucumber-tests + sh ./scripts/setup-hosts.sh + ./gradlew runTests + - name: Helm release undeploy + if: always() + shell: sh + run: | + cd apk-repo/helm-charts + kubectl describe pods -n apk + kubectl get pods -n apk + kubectl get svc -n apk + helm uninstall apim-apk-agent -n apk + cd apk-repo/test/apim-apk-agent-test/apim-cp-helm-chart + helm uninstall apim -n apk + cd apk-repo/test/apim-apk-agent-test/agent-helm-chart + helm uninstall apim-apk-agent -n apk + - name: Delete AKS cluster + if: always() + uses: azure/CLI@v1 + with: + azcliversion: 2.44.1 + inlineScript: | + az aks delete --resource-group ${{ secrets.AZURE_RESOURCE_GROUP }} --name go-integ-${{ secrets.AKS_CLUSTER_NAME }}-${{ github.event.number || github.run_id }} --yes + - name: Logout from azure + if: always() + uses: azure/CLI@v1 + with: + azcliversion: 2.44.1 + inlineScript: | + az logout + - name: Publish Test Report + if: always() + uses: malinthaprasan/action-surefire-report@v1 + with: + report_paths: 'apk-agent-repo/test/postman-tests/build/*.xml' + fail_on_test_failures: true \ No newline at end of file diff --git a/test/apim-apk-agent-test/agent-helm-chart/Chart.lock b/test/apim-apk-agent-test/agent-helm-chart/Chart.lock new file mode 100644 index 000000000..028ab93b7 --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: cert-manager + repository: https://charts.jetstack.io + version: v1.10.1 +digest: sha256:ec4c4f13caccd7a20912773027a411630546bcb6139744732d49806ce2514fc8 +generated: "2024-01-22T12:10:42.822012+05:30" diff --git a/test/apim-apk-agent-test/agent-helm-chart/Chart.yaml b/test/apim-apk-agent-test/agent-helm-chart/Chart.yaml new file mode 100644 index 000000000..23dbf0f64 --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/Chart.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. + +apiVersion: v2 +name: apim-apk-agent +description: A Helm chart for deploying apim-apk-agent +version: 0.1.0 +dependencies: + - name: cert-manager + version: "v1.10.1" + repository: "https://charts.jetstack.io" \ No newline at end of file diff --git a/test/apim-apk-agent-test/agent-helm-chart/charts/cert-manager-v1.10.1.tgz b/test/apim-apk-agent-test/agent-helm-chart/charts/cert-manager-v1.10.1.tgz new file mode 100644 index 000000000..ef78ba848 Binary files /dev/null and b/test/apim-apk-agent-test/agent-helm-chart/charts/cert-manager-v1.10.1.tgz differ diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/cert-manager/certificates/apk-agent-server-certificate.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/cert-manager/certificates/apk-agent-server-certificate.yaml new file mode 100644 index 000000000..6015bf0be --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/cert-manager/certificates/apk-agent-server-certificate.yaml @@ -0,0 +1,40 @@ +# Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. + +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io + +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: apim-apk-agent-server-cert + namespace: {{ .Release.Namespace }} +spec: + commonName: apim-apk-agent-service + privateKey: + algorithm: RSA + encoding: PKCS8 + size: 2048 + + dnsNames: + - apim-apk-agent-service.{{ .Release.Namespace }}.svc + - apim-apk-agent-service.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + kind: "ClusterIssuer" + name: "apk-agent-selfsigned-issuer" + secretName: apk-agent-server-cert + + diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/cert-manager/issuers/apk-agent-root-certificate.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/cert-manager/issuers/apk-agent-root-certificate.yaml new file mode 100644 index 000000000..1cb515a8a --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/cert-manager/issuers/apk-agent-root-certificate.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: apk-agent-root-certificate + namespace: {{ .Release.Namespace }} +type: kubernetes.io/tls +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvVENDQWVXZ0F3SUJBZ0lVZDRuanY4eVNQZ283dDBGMWUyYUpFbzlUcFE0d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0RqRU1NQW9HQTFVRUF3d0RZWEJyTUI0WERUSXpNRE13T1RBNE1UWXpORm9YRFRNek1ETXdOakE0TVRZegpORm93RGpFTU1Bb0dBMVVFQXd3RFlYQnJNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCkFRRUExRzlCQWNWYTNhTWVteEVSWStKOFVtSC9XOEpwY0VPdGRlTlg1WU5paG5OT1h0bHZoU3pGek9QYUs5N1AKcjRJcUdBU2JWTmlSKzFKNldFb2kvYjZaSlR4MHEzWVVuMFlsUUpyejdnMjBUZG9HSmp4R1ZXem4wRVc0YmVIWApHcTYwdlhMZjR0M21sTENMR0lLM2tKVFdBb1J6ZDc0ZGpWNys1djBCbS82S0JCQVdjdTVVYk9EOUtScE9zeEdNCm4zWjAxMDNvQUdWaXlxODRRdEZ2aFhWTld0dERMZTJqVS83bzQyZGRhSm96Ukw5eisxQWVwZG9XUHlKWklacVUKYlhjR0FrN2lkazdjLzhkS014d0FtM0NWL1d2Z1dyVks1UitZVGlHcVJmNXBkOVdXQ3lkRVZRa05xQ1pnVFBOeQpCVFJ2SG81Mm9uUG5UNkFMdE1JMG1uV0x0UUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVenhjQThjZUNGNXQrCnZQZU9wWWJpMTFDV2p3Y3dId1lEVlIwakJCZ3dGb0FVenhjQThjZUNGNXQrdlBlT3BZYmkxMUNXandjd0R3WUQKVlIwVEFRSC9CQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFGQ0tkNXg4ejY0cDFqOUJub1NBbApKSnVOejR1V2p2L1lLOTRCM3MzS1VrWE9Yakh1THVhemtTc3MyVUhGYitLZUxkNnZoaW1NNVFxa0ZzVUVNc25DCjhSeUJaUDU4a2doY0x6SmxkNVVpd2xuci9SdU9BTnZjdjRlS1Nhdnd1NS9BQlh1TVVRYi9Hdkt0V1BycjJWYkoKVUxnM3A3TkdpZ1hISGc4NGVWTUE3b05YMVo1UjJjUzRJU2tsV1htNVNwTVBoK1NOQ2dxd3FoeFJOWUoySjBFWgpxbHA0b2ZRRzNHSjcySitEUkhsTnVqV0Vza1A1SUpqdzZ3OFEwempYeDI2eWVsR2UyK1RNNkJCN1BwQ042a05VCnpIbzJrLzU3NWJ1MmlaenRuWVZtRTc0SDFXM2NYSjdjMHE4MnVVRnZkVytGbFJ0bStPUElpSUdLNzRsRmlaTkIKT1E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRRFViMEVCeFZyZG94NmIKRVJGajRueFNZZjlid21sd1E2MTE0MWZsZzJLR2MwNWUyVytGTE1YTTQ5b3Izcyt2Z2lvWUJKdFUySkg3VW5wWQpTaUw5dnBrbFBIU3JkaFNmUmlWQW12UHVEYlJOMmdZbVBFWlZiT2ZRUmJodDRkY2FyclM5Y3QvaTNlYVVzSXNZCmdyZVFsTllDaEhOM3ZoMk5YdjdtL1FHYi9vb0VFQlp5N2xSczRQMHBHazZ6RVl5ZmRuVFhUZWdBWldMS3J6aEMKMFcrRmRVMWEyME10N2FOVC91ampaMTFvbWpORXYzUDdVQjZsMmhZL0lsa2htcFJ0ZHdZQ1R1SjJUdHoveDBvegpIQUNiY0pYOWErQmF0VXJsSDVoT0lhcEYvbWwzMVpZTEowUlZDUTJvSm1CTTgzSUZORzhlam5haWMrZFBvQXUwCndqU2FkWXUxQWdNQkFBRUNnZ0VBQ1VMRVdiaHB5cW0yeHRuS29Va1pWRm9UVU1PNzV2bjhVTnhWVTVzVHEzclIKV3M4dHptZHlSQWxXMUh6Rkh3aVVuekZzT0JtczI0RHY5bk5jN1NUbTlqbVplSFFRV0JVdHdKQkF2QXI2NWozdgo4TERGL0NsZ1BiTWNaQ1hwUTYrRUQ1STNjbU5zRHVWWFd2MHYxV3kzbTZwOGdpYldrUGdvTXBlcS8wcnNaMXJiCjB6TDhuNkpENUtxc3JjWE5WODNObTZqUmxUMzJZWGZreHpwczhpME1PZGYyLzllQmVrMC93N2xBTU0wNFQ3dXMKNWRHeVRFNHo3eThYVndscmF6WFlMM2VUL3RDOHY4M3BrWXNlOWdBZ2I4Z3MrRmlhTUc3WG1sMmpmY05YV1I0ZwpHRmRSMmRJVlNQbnJwdldLajNrS0IwVXFsVVplakp2WkhhQlk2cStDd1FLQmdRRGRKbFB3MUFONjhncVVMdjB2CmltMWNyVTJneS9kbzZpWjl0Y05MdjgxblMzS1JtRVllKzBTYzZZR3dNQWtPWjd0S1BTMnNsRU9IUDUzQjVseU8KakttSlhkQXBvZVUzSW5lOW5kRGs3TEoxNVpsTkFzNXlWb1pjdzdINHp2YTIwM0c2UDFnZWpja2RpOWVicDFnVAorUVpNSmZjdHJtaExDaDhQR1ZzZDRPaFFNUUtCZ1FEMTZWYVRDQ243MElESFNnLzJia1M3NjJzK2dmcHJpK3hCCjE4UmhMOVowL1RQQVl2dUpqNWNUaHh6S2hGWG53ZDRHVGZ4eFdnaURsV3lIb1BjRDhLT2JLM1htT1ZUUEg2WDcKNjdNdTc4bWxLZlVZY3VrM244ekFmc1FkQzBBNmNRRVlhcVFIMW4wSjZVM255RnNwL0hJWis1NjhQQmQwT0dMUQprWmdrc3oyMnhRS0JnR01uZEN0ZVk5RVVCTG83OXprQmo5Y2x2TkNEb3dKZk9iTFRkQ1RhY25ZRjFmQ0JuYTcyCmFlVVFyUjBaN0hXUS9PQmtYYjRyRzd2Z1FoTlYvZG5NSjVkM2dJV3FHT09IaUxoenNkMXlZdkdKYUJxblQzamsKWW9ubEZEN0NUTXZjTWZtWHZTSzEzNTVudk53RlEvQndqdXBGZTNYMzVMc0FacnlXV2N3anN3V0JBb0dBYTNidApQcFB5eFBqNVRoNHZtNkhVcDhyWnN4ZGFPR1dOZWJpeE9VZU9rTkdXTEIwVmo2Z1FmWmd1SE5KNE9DK2d0MkNkClVXdm5ESm5nTStWRURaUzc2ck96Y2tqYnB5aE5nU29meEFOR084ZDZOSlVERml2ZmJyLzNORG9XZDNPcTV1Q3oKampsTnEyY3BoSUVxVmM3Y2pqNUh3RHNDaE9lZlIwWlpGckM5NTRFQ2dZRUFwZHloY1FiL1o0WXJ5bHJmelJycAovR0RjdVg5TlQxWDdtT2tCamExVXUvSTV6ZFVMYzkrNjZUc3IyTEhiVUdtUkhnTGx4NHo1U1dIeVJiTnhOUENwCkN1Q0svdkh6TlN6YlZVeDRUSzBYZHJHOWI5SHRXcU4yU0pERk9tSXBVYUJPd25SYThxa3hwSTF3YWRsT2ZYejUKUFdIQ3RJcWRkdlRkeG50TnpxekRnVzg9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K \ No newline at end of file diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/cert-manager/issuers/self-signed-issuer.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/cert-manager/issuers/self-signed-issuer.yaml new file mode 100644 index 000000000..6681820de --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/cert-manager/issuers/self-signed-issuer.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: apk-agent-selfsigned-issuer +spec: + ca: + secretName: apk-agent-root-certificate \ No newline at end of file diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/deployment.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/deployment.yaml new file mode 100644 index 000000000..04e761d28 --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/deployment.yaml @@ -0,0 +1,87 @@ +# Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Chart.Name }} + labels: + app.kubernetes.io/app: "apim-apk-agent" + helm.sh/chart: {{ .Chart.Name }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/app: "apim-apk-agent" + app.kubernetes.io/name: {{ .Chart.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/app: "apim-apk-agent" + app.kubernetes.io/name: {{ .Chart.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + serviceAccountName: wso2agent-platform + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: grpc-port + containerPort: 18000 + - name: rest-port + containerPort: 18001 + env: + - name: APIM_APK_AGENT_PRIVATE_KEY_PATH + value: /home/wso2/security/keystore/apk-agent.key + - name: APIM_APK_AGENT_PUBLIC_CERT_PATH + value: /home/wso2/security/keystore/apk-agent.crt + - name: APIM_APK_AGENT_SERVER_NAME + value: apim-apk-agent-service.{{ .Release.Namespace }}.svc + - name: APIM_APK_AGENT_GRPC_PORT + value: "18000" + volumeMounts: + - name: log-conf-volume + mountPath: /home/wso2/conf/ + - name: apk-agent-certificates + mountPath: /home/wso2/security/keystore/apk-agent.key + subPath: tls.key + - name: apk-agent-certificates + mountPath: /home/wso2/security/keystore/apk-agent.crt + subPath: tls.crt + - name: apk-agent-certificates + mountPath: /home/wso2/security/truststore/apk-agent-ca.crt + subPath: ca.crt + readinessProbe: + exec: + command: [ "sh", "check_health.sh" ] + initialDelaySeconds: 20 + periodSeconds: 20 + failureThreshold: 5 + livenessProbe: + exec: + command: [ "sh", "check_health.sh" ] + initialDelaySeconds: 20 + periodSeconds: 20 + failureThreshold: 5 + volumes: + - name: log-conf-volume + configMap: + name: {{ .Release.Name }}-log-conf + - name: apk-agent-certificates + secret: + secretName: apk-agent-server-cert diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/log-conf.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/log-conf.yaml new file mode 100644 index 000000000..613871038 --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/log-conf.yaml @@ -0,0 +1,59 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-log-conf + namespace: {{ .Release.Namespace }} +data: + config.toml: | + [controlPlane] + enabled = {{ .Values.controlPlane.enabled }} + serviceURL = "{{ .Values.controlPlane.serviceURL }}" + username = "{{ .Values.controlPlane.username }}" + password = "{{ .Values.controlPlane.password }}" + environmentLabels = ["{{ .Values.controlPlane.environmentLabels }}"] + skipSSLVerification = {{ .Values.controlPlane.skipSSLVerification }} + [controlPlane.brokerConnectionParameters] + eventListeningEndpoints = ["{{ .Values.controlPlane.eventListeningEndpoints }}"] + + [dataPlane] + enabled = {{ .Values.dataPlane.enabled }} + k8ResourceEndpoint = "{{ .Values.dataPlane.k8ResourceEndpoint }}" + namespace = "{{ .Values.dataPlane.namespace }}" + log_config.toml: | + # The logging configuration for Adapter + + ## Adapter root Level configurations + + logLevel = "INFO" # LogLevels can be "DEBG", "FATL", "ERRO", "WARN", "INFO", "PANC" + LogFormat = "TEXT" # Values can be "JSON", "TEXT" + + [rotation] + MaxSize = 10 # In MegaBytes (MB) + MaxBackups = 3 + MaxAge = 2 # In days + Compress = true + + ## Adapter package Level configurations + + [[pkg]] + name = "github.com/wso2/apk/adapter/internal/adapter" + logLevel = "INFO" # LogLevels can be "DEBG", "FATL", "ERRO", "WARN", "INFO", "PANC" + + [[pkg]] + name = "github.com/wso2/apk/adapter/internal/oasparser" + logLevel = "INFO" + + + # The logging configuration for Router + + [accessLogs] + enable = false + format = "[%START_TIME%] '%REQ(:METHOD)% %DYNAMIC_METADATA(envoy.filters.http.ext_authz:originalPath)% %REQ(:PATH)% %PROTOCOL%' %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% '%REQ(X-FORWARDED-FOR)%' '%REQ(USER-AGENT)%' '%REQ(X-REQUEST-ID)%' '%REQ(:AUTHORITY)%' '%UPSTREAM_HOST%'\n" + + [wireLogs] + enable = false + include = ["Headers", "Body", "Trailers"] + + # [[pkg]] + # name = "github.com/wso2/apk/Adapter/pkg/xds" + # logLevel = "INFO" diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/service.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/service.yaml new file mode 100644 index 000000000..db2bf382f --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/service.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. + +apiVersion: v1 +kind: Service +metadata: + name: "apim-apk-agent-service" +spec: + ports: + - name: grpc-server + protocol: TCP + port: 18000 + - name: rest-server + protocol: TCP + port: 18001 + selector: + app.kubernetes.io/app: "apim-apk-agent" + diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-account-secret.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-account-secret.yaml new file mode 100644 index 000000000..d610cefe1 --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-account-secret.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. + +apiVersion: v1 +kind: Secret +metadata: + name: agent-account-secret-token + namespace: {{ .Release.Namespace }} + annotations: + kubernetes.io/service-account.name: wso2agent-platform +type: kubernetes.io/service-account-token \ No newline at end of file diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-cluster-role-binding.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-cluster-role-binding.yaml new file mode 100644 index 000000000..1fcc2918c --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-cluster-role-binding.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. + +apiVersion: rbac.authorization.k8s.io/v1 +# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace. +kind: ClusterRoleBinding +metadata: + name: agent-cluster-role-binding + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: wso2agent-role + apiGroup: rbac.authorization.k8s.io +subjects: + # You can specify more than one "subject" + - kind: ServiceAccount + name: wso2agent-platform + namespace: {{ .Release.Namespace }} \ No newline at end of file diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-cluster-role.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-cluster-role.yaml new file mode 100644 index 000000000..6d18eb5c9 --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-cluster-role.yaml @@ -0,0 +1,123 @@ +# Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: wso2agent-role +rules: + - apiGroups: [""] + resources: ["services","configmaps","secrets"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["httproutes","gateways"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: [ "gateway.networking.k8s.io" ] + resources: [ "gateways/status" ] + verbs: [ "get","patch","update" ] + - apiGroups: ["dp.wso2.com"] + resources: ["apis"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["dp.wso2.com"] + resources: ["apis/finalizers"] + verbs: ["update"] + - apiGroups: ["dp.wso2.com"] + resources: ["apis/status"] + verbs: ["get","patch","update"] + - apiGroups: ["dp.wso2.com"] + resources: ["authentications"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["dp.wso2.com"] + resources: ["authentications/finalizers"] + verbs: ["update"] + - apiGroups: ["dp.wso2.com"] + resources: ["authentications/status"] + verbs: ["get","patch","update"] + - apiGroups: ["dp.wso2.com"] + resources: ["backends"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["dp.wso2.com"] + resources: ["backends/finalizers"] + verbs: ["update"] + - apiGroups: ["dp.wso2.com"] + resources: ["backends/status"] + verbs: ["get","patch","update"] + - apiGroups: ["dp.wso2.com"] + resources: ["apipolicies"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["dp.wso2.com"] + resources: ["apipolicies/finalizers"] + verbs: ["update"] + - apiGroups: ["dp.wso2.com"] + resources: ["apipolicies/status"] + verbs: ["get","patch","update"] + - apiGroups: ["dp.wso2.com"] + resources: ["interceptorservices"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["dp.wso2.com"] + resources: ["interceptorservices/finalizers"] + verbs: ["update"] + - apiGroups: ["dp.wso2.com"] + resources: ["interceptorservices/status"] + verbs: ["get","patch","update"] + - apiGroups: [ "dp.wso2.com" ] + resources: [ "scopes" ] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["dp.wso2.com"] + resources: ["scopes/finalizers"] + verbs: ["update"] + - apiGroups: ["dp.wso2.com"] + resources: ["scopes/status"] + verbs: ["get","patch","update"] + - apiGroups: [ "dp.wso2.com" ] + resources: [ "ratelimitpolicies" ] + verbs: [ "get","list","watch","update","delete","create" ] + - apiGroups: [ "dp.wso2.com" ] + resources: [ "ratelimitpolicies/finalizers" ] + verbs: [ "update" ] + - apiGroups: [ "dp.wso2.com" ] + resources: [ "ratelimitpolicies/status" ] + verbs: [ "get","patch","update" ] + - apiGroups: [ "coordination.k8s.io" ] + resources: [ "leases" ] + verbs: [ "get","list","watch","update","patch","create","delete" ] + - apiGroups: ["dp.wso2.com"] + resources: ["tokenissuers"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["dp.wso2.com"] + resources: ["tokenissuers/finalizers"] + verbs: ["update"] + - apiGroups: ["dp.wso2.com"] + resources: ["tokenissuers/status"] + verbs: ["get","patch","update"] + - apiGroups: ["dp.wso2.com"] + resources: ["backendjwts"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["dp.wso2.com"] + resources: ["backendjwts/finalizers"] + verbs: ["update"] + - apiGroups: ["dp.wso2.com"] + resources: ["backendjwts/status"] + verbs: ["get","patch","update"] + - apiGroups: ["dp.wso2.com"] + resources: ["gqlroutes"] + verbs: ["get","list","watch","update","delete","create"] + - apiGroups: ["dp.wso2.com"] + resources: ["gqlroutes/finalizers"] + verbs: ["update"] + - apiGroups: ["dp.wso2.com"] + resources: ["gqlroutes/status"] + verbs: ["get","patch","update"] \ No newline at end of file diff --git a/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-service-account.yaml b/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-service-account.yaml new file mode 100644 index 000000000..969c24ff7 --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/templates/serviceAccount/agent-service-account.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: wso2agent-platform + namespace: {{ .Release.Namespace }} \ No newline at end of file diff --git a/test/apim-apk-agent-test/agent-helm-chart/values.yaml b/test/apim-apk-agent-test/agent-helm-chart/values.yaml new file mode 100644 index 000000000..0fbb6327e --- /dev/null +++ b/test/apim-apk-agent-test/agent-helm-chart/values.yaml @@ -0,0 +1,36 @@ +# Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +# +# WSO2 LLC. 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. + +replicaCount: 1 +image: + repository: wso2/apim-apk-agent + tag: latest + pullPolicy: Always +service: + name: apim-apk-agent-service +resources: {} +controlPlane: + enabled: true + serviceURL: https://apim-wso2am-cp-1-service:9443/ + username: admin + password: admin + environmentLabels: Default + skipSSLVerification: true + eventListeningEndpoints: amqp://admin:admin@apim-wso2am-cp-1-service:5672?retries='10'&connectdelay='30' +dataPlane: + enabled: true + k8ResourceEndpoint: https://apk-wso2-apk-config-ds-service.apk.svc.cluster.local:9443/api/configurator/apis/generate-k8s-resources + namespace: apk diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/Chart.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/Chart.yaml new file mode 100644 index 000000000..ab09f3425 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/Chart.yaml @@ -0,0 +1,17 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +appVersion: "4.2.0" +description: A Helm chart for the deployment of WSO2 API Management Control Plane profile +name: wso2am-cp +version: 4.2.0-0 +icon: https://wso2.cachefly.net/wso2/sites/all/images/wso2logo.svg diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/README.md b/test/apim-apk-agent-test/apim-cp-helm-chart/README.md new file mode 100644 index 000000000..9e20e7dcd --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/README.md @@ -0,0 +1,175 @@ +# wso2am-cp + +![Version: 4.2.0-0](https://img.shields.io/badge/Version-4.2.0--0-informational?style=flat-square) ![AppVersion: 4.2.0](https://img.shields.io/badge/AppVersion-4.2.0-informational?style=flat-square) + +A Helm chart for the deployment of WSO2 API Management Control Plane profile + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| aws.efs.accessPoints | object | `{"carbonDb1":"","carbonDb2":"","solr1":"","solr2":""}` | EFS Access Points for static provisioning | +| aws.efs.capacity | string | `""` | EFS capacity | +| aws.efs.directoryPerms | string | `"0777"` | EFS directory permissions | +| aws.efs.fileSystemId | string | `""` | EFS file system ID for mounting the persistent volume | +| aws.enabled | bool | `true` | If AWS is used as the cloud provider | +| aws.region | string | `""` | AWS region | +| aws.secretsManager.secretIdentifiers.internalKeystorePassword | object | `{"secretKey":"","secretName":""}` | Internal keystore password identifier in secrets manager | +| aws.secretsManager.secretIdentifiers.internalKeystorePassword.secretKey | string | `""` | AWS Secrets Manager secret key | +| aws.secretsManager.secretIdentifiers.internalKeystorePassword.secretName | string | `""` | AWS Secrets Manager secret name | +| aws.secretsManager.secretProviderClass | string | `"wso2am-cp-secret-provider-class"` | AWS Secrets Manager secret provider class name | +| aws.serviceAccountName | string | `""` | | +| azure.enabled | bool | `false` | If Azure is used as the cloud provider | +| azure.keyVault.activeDirectory.servicePrincipal | object | `{"appId":"","clientSecretName":"","credentialsSecretName":""}` | Service Principal created for transacting with the target Azure Key Vault For advanced details refer to official documentation (https://github.com/Azure/secrets-store-csi-driver-provider-azure/blob/master/docs/service-principal-mode.md) | +| azure.keyVault.activeDirectory.servicePrincipal.appId | string | `""` | Application ID of the service principal used in secret-store-csi | +| azure.keyVault.activeDirectory.servicePrincipal.clientSecretName | string | `""` | Client secret name of the service principal used in secret-store-csi | +| azure.keyVault.activeDirectory.servicePrincipal.credentialsSecretName | string | `""` | Credentials secret name of the service principal used as nodePublisherRef | +| azure.keyVault.activeDirectory.tenantId | string | `""` | Azure Active Directory tenant ID of the target Key Vault | +| azure.keyVault.name | string | `""` | Azure Key vault used for credential management | +| azure.keyVault.resourceManager.resourceGroup | string | `""` | Name of the Azure Resource Group to which the target Azure Key Vault belongs | +| azure.keyVault.resourceManager.subscriptionId | string | `""` | Subscription ID of the target Azure Key Vault | +| azure.keyVault.secretIdentifiers.internalKeystoreKeyPassword | string | `""` | Internal keystore key password identifier in keyvault | +| azure.keyVault.secretIdentifiers.internalKeystorePassword | string | `""` | Internal keystore password identifier in keyvault | +| azure.keyVault.secretProviderClass | string | `"wso2am-cp-secret-provider-class"` | Azure Key vault secret provider class name | +| azure.persistence.capacity | string | `""` | Persistent volume capacity | +| azure.persistence.fileShare | string | `""` | Azure fileshare name | +| azure.persistence.secretName | string | `""` | Azure file secret name | +| azure.persistence.storageClass | string | `""` | Persistent volume storage class | +| gcp.enabled | bool | `false` | If GCP is used as the cloud provider | +| gcp.fs | object | `{"capacity":"","fileshares":{"carbonDB1":{"fileShareName":"","fileStoreName":"","ip":""},"carbonDB2":{"fileShareName":"","fileStoreName":"","ip":""},"solr1":{"fileShareName":"","fileStoreName":"","ip":""},"solr2":{"fileShareName":"","fileStoreName":"","ip":""}},"location":"","network":"","tier":""}` | File Store configuration parameters | +| gcp.fs.capacity | string | `""` | Storage capacity of the file system (in GB or other appropriate units) | +| gcp.fs.fileshares | object | `{"carbonDB1":{"fileShareName":"","fileStoreName":"","ip":""},"carbonDB2":{"fileShareName":"","fileStoreName":"","ip":""},"solr1":{"fileShareName":"","fileStoreName":"","ip":""},"solr2":{"fileShareName":"","fileStoreName":"","ip":""}}` | FileStore configuration for specific services | +| gcp.fs.fileshares.carbonDB1 | object | `{"fileShareName":"","fileStoreName":"","ip":""}` | FileShare configs for CarbonDB persistent storage for instance 1 | +| gcp.fs.fileshares.carbonDB1.fileShareName | string | `""` | FileShare of the CarbonDB persistent storage for instance 1 | +| gcp.fs.fileshares.carbonDB1.fileStoreName | string | `""` | FileStore of the CarbonDB persistent storage for instance 1 | +| gcp.fs.fileshares.carbonDB1.ip | string | `""` | IP of the CarbonDB persistent storage for instance 1 | +| gcp.fs.fileshares.carbonDB2 | object | `{"fileShareName":"","fileStoreName":"","ip":""}` | FileShare configs for CarbonDB2 persistent storage for instance 2 | +| gcp.fs.fileshares.carbonDB2.fileShareName | string | `""` | FileShare of the CarbonDB persistent storage for instance 2 | +| gcp.fs.fileshares.carbonDB2.fileStoreName | string | `""` | FileStore of the CarbonDB persistent storage for instance 2 | +| gcp.fs.fileshares.carbonDB2.ip | string | `""` | IP of the CarbonDB persistent storage for instance 2 | +| gcp.fs.fileshares.solr1 | object | `{"fileShareName":"","fileStoreName":"","ip":""}` | FileShare configs for Solr persistent storage for instance 1 | +| gcp.fs.fileshares.solr1.fileShareName | string | `""` | FileShare of the Solr persistent storage for instance 1 | +| gcp.fs.fileshares.solr1.fileStoreName | string | `""` | FileStore of the Solr persistent storage for instance 1 | +| gcp.fs.fileshares.solr1.ip | string | `""` | IP of the Solr persistent storage for instance 1 | +| gcp.fs.fileshares.solr2 | object | `{"fileShareName":"","fileStoreName":"","ip":""}` | FileShare configs for Solr persistent storage for instance 2 | +| gcp.fs.fileshares.solr2.fileShareName | string | `""` | FileShare of the Solr persistent storage for instance 2 | +| gcp.fs.fileshares.solr2.fileStoreName | string | `""` | FileStore of the Solr persistent storage for instance 2 | +| gcp.fs.fileshares.solr2.ip | string | `""` | IP of the Solr persistent storage for instance 2 | +| gcp.fs.location | string | `""` | Region of the FileStore | +| gcp.fs.network | string | `""` | Network of the FileStore | +| gcp.fs.tier | string | `""` | Tier of the FileStore | +| gcp.secretsManager | object | `{"projectId":"","secret":{"secretName":"","secretVersion":""},"secretProviderClass":""}` | Secrets Manager configuration parameters | +| gcp.secretsManager.projectId | string | `""` | Project ID | +| gcp.secretsManager.secret.secretName | string | `""` | Name of the secret | +| gcp.secretsManager.secret.secretVersion | string | `""` | Version of the secret | +| gcp.secretsManager.secretProviderClass | string | `""` | Secret provider class | +| gcp.serviceAccountName | string | `""` | Service Account with access to read secrets | +| kubernetes.enableAppArmor | bool | `false` | Enable AppArmor profiles for the deployment | +| kubernetes.ingress.controlPlane.annotations | object | `{"nginx.ingress.kubernetes.io/affinity":"cookie","nginx.ingress.kubernetes.io/backend-protocol":"HTTPS","nginx.ingress.kubernetes.io/session-cookie-hash":"sha1","nginx.ingress.kubernetes.io/session-cookie-name":"route"}` | Ingress annotations | +| kubernetes.ingress.controlPlane.hostname | string | `"am.wso2.com"` | Ingress hostname | +| kubernetes.ingress.ratelimit.burstLimit | string | `""` | Ingress ratelimit burst limit | +| kubernetes.ingress.ratelimit.enabled | bool | `false` | Ingress rate limit | +| kubernetes.ingress.ratelimit.zoneName | string | `""` | Ingress ratelimit zone name | +| kubernetes.ingress.tlsSecret | string | `""` | Kubernetes secret created for Ingress TLS | +| kubernetes.ingressClass | string | `"nginx"` | Ingress class to be used for the ingress resource | +| kubernetes.securityContext.runAsUser | int | `802` | User ID of the container | +| wso2.apim.configurations.adminPassword | string | `""` | Super admin password | +| wso2.apim.configurations.adminUsername | string | `""` | Super admin username | +| wso2.apim.configurations.databases.apim_db | object | `{"password":"","poolParameters":{"defaultAutoCommit":false,"maxActive":100,"maxWait":60000,"minIdle":5,"testOnBorrow":true,"testWhileIdle":true,"validationInterval":30000},"url":"","username":""}` | APIM AM_DB configurations. | +| wso2.apim.configurations.databases.apim_db.password | string | `""` | APIM AM_DB password | +| wso2.apim.configurations.databases.apim_db.poolParameters | object | `{"defaultAutoCommit":false,"maxActive":100,"maxWait":60000,"minIdle":5,"testOnBorrow":true,"testWhileIdle":true,"validationInterval":30000}` | APIM database JDBC pool parameters | +| wso2.apim.configurations.databases.apim_db.url | string | `""` | APIM AM_DB URL | +| wso2.apim.configurations.databases.apim_db.username | string | `""` | APIM AM_DB username | +| wso2.apim.configurations.databases.jdbc.driver | string | `""` | JDBC driver class name | +| wso2.apim.configurations.databases.shared_db | object | `{"password":"","poolParameters":{"defaultAutoCommit":false,"maxActive":100,"maxWait":60000,"minIdle":5,"testOnBorrow":true,"testWhileIdle":true,"validationInterval":30000},"url":"","username":""}` | APIM SharedDB configurations. | +| wso2.apim.configurations.databases.shared_db.password | string | `""` | APIM SharedDB password | +| wso2.apim.configurations.databases.shared_db.poolParameters | object | `{"defaultAutoCommit":false,"maxActive":100,"maxWait":60000,"minIdle":5,"testOnBorrow":true,"testWhileIdle":true,"validationInterval":30000}` | APIM shared database JDBC pool parameters | +| wso2.apim.configurations.databases.shared_db.url | string | `""` | APIM SharedDB URL | +| wso2.apim.configurations.databases.shared_db.username | string | `""` | APIM SharedDB username | +| wso2.apim.configurations.databases.type | string | `""` | Database type. eg: mysql, oracle, mssql, postgres | +| wso2.apim.configurations.devportal.applicationSharingImpl | string | `nil` | | +| wso2.apim.configurations.devportal.applicationSharingType | string | `nil` | | +| wso2.apim.configurations.devportal.defaultReservedUsername | string | `nil` | | +| wso2.apim.configurations.devportal.displayDeprecatedAPIs | string | `nil` | | +| wso2.apim.configurations.devportal.displayMutipleVersions | string | `nil` | | +| wso2.apim.configurations.devportal.enableAnonymousMode | string | `nil` | | +| wso2.apim.configurations.devportal.enableApplicationSharing | string | `nil` | | +| wso2.apim.configurations.devportal.enableComments | string | `nil` | | +| wso2.apim.configurations.devportal.enableCrossTenantSubscriptions | string | `nil` | | +| wso2.apim.configurations.devportal.enableForum | string | `nil` | | +| wso2.apim.configurations.devportal.enableKeyProvisioning | string | `nil` | | +| wso2.apim.configurations.devportal.enableRatings | string | `nil` | | +| wso2.apim.configurations.devportal.loginUsernameCaseInsensitive | string | `nil` | | +| wso2.apim.configurations.gateway.environments | list | `[{"description":"This is a hybrid gateway that handles both production and sandbox token traffic.","displayInApiConsole":true,"httpHostname":"gw.wso2.com","name":"Default","provider":"wso2","serviceName":"wso2am-gateway-service","servicePort":9443,"showAsTokenEndpointUrl":true,"type":"hybrid","websubHostname":"websub.wso2.com","wsHostname":"websocket.wso2.com"}]` | APIM Gateway environments | +| wso2.apim.configurations.iskm.enabled | bool | `false` | If Identity Server is used as the Resident KM | +| wso2.apim.configurations.iskm.serviceName | string | `""` | Kubernetes service name exposing Identity Server | +| wso2.apim.configurations.iskm.servicePort | int | `9443` | Kubernetes service port exposing Identity Serve | +| wso2.apim.configurations.oauth_config.allowedScopes | list | `["^device_.*,openid"]` | List of allow-listed scopes | +| wso2.apim.configurations.oauth_config.enableTokenEncryption | bool | `false` | Enable token encryption | +| wso2.apim.configurations.oauth_config.enableTokenHashing | bool | `false` | Enable token hashing | +| wso2.apim.configurations.openTelemetry.enabled | bool | `false` | Open Telemetry enabled | +| wso2.apim.configurations.openTelemetry.hostname | string | `""` | Remote tracer hostname | +| wso2.apim.configurations.openTelemetry.name | string | `""` | Remote tracer name. e.g. jaeger, zipkin, OTLP | +| wso2.apim.configurations.openTelemetry.port | string | `""` | Remote tracer port | +| wso2.apim.configurations.openTracer.enabled | bool | `false` | Open Tracing enabled | +| wso2.apim.configurations.openTracer.name | string | `""` | Remote tracer name. e.g. jaeger, zipkin | +| wso2.apim.configurations.openTracer.properties.hostname | string | `""` | Remote tracer hostname | +| wso2.apim.configurations.openTracer.properties.port | string | `""` | Remote tracer port | +| wso2.apim.configurations.publisher.supportedDocumentTypes | string | `""` | Supported document types in Publisher. This should be used only if there are additional document types to be supported. | +| wso2.apim.configurations.security.jksSecretName | string | `"apim-keystore-secret"` | Kubernetes secret containing the keystores and truststore | +| wso2.apim.configurations.security.keystores.internal.alias | string | `"wso2carbon"` | Internal keystore alias | +| wso2.apim.configurations.security.keystores.internal.enabled | bool | `false` | Internal keystore enabled | +| wso2.apim.configurations.security.keystores.internal.keyPassword | string | `""` | Internal keystore key password | +| wso2.apim.configurations.security.keystores.internal.name | string | `"wso2carbon.jks"` | Internal keystore name | +| wso2.apim.configurations.security.keystores.internal.password | string | `""` | Internal keystore password | +| wso2.apim.configurations.security.keystores.primary.alias | string | `"wso2carbon"` | Primary keystore alias | +| wso2.apim.configurations.security.keystores.primary.enabled | bool | `false` | Primary keystore enabled | +| wso2.apim.configurations.security.keystores.primary.keyPassword | string | `""` | Primary keystore key password | +| wso2.apim.configurations.security.keystores.primary.name | string | `"wso2carbon.jks"` | Primary keystore name | +| wso2.apim.configurations.security.keystores.primary.password | string | `""` | Primary keystore password | +| wso2.apim.configurations.security.keystores.tls.alias | string | `"wso2carbon"` | TLS keystore alias | +| wso2.apim.configurations.security.keystores.tls.enabled | bool | `true` | TLS keystore enabled | +| wso2.apim.configurations.security.keystores.tls.keyPassword | string | `""` | TLS keystore key password | +| wso2.apim.configurations.security.keystores.tls.name | string | `"wso2carbon.jks"` | TLS keystore name | +| wso2.apim.configurations.security.keystores.tls.password | string | `""` | TLS keystore password | +| wso2.apim.configurations.security.truststore.name | string | `"client-truststore.jks"` | Truststore name | +| wso2.apim.configurations.security.truststore.password | string | `""` | Truststore password | +| wso2.apim.configurations.userStore.properties | object | `{"key":"value"}` | User store properties | +| wso2.apim.configurations.userStore.type | string | `"database_unique_id"` | User store type. https://apim.docs.wso2.com/en/latest/administer/managing-users-and-roles/managing-user-stores/configure-primary-user-store/configuring-the-primary-user-store/ | +| wso2.apim.log4j2.appenders | string | `""` | Appenders | +| wso2.apim.log4j2.loggers | string | `""` | Console loggers that can be enabled. Allowed values are AUDIT_LOG_CONSOLE, HTTP_ACCESS_CONSOLE, TRANSACTION_CONSOLE, CORRELATION_CONSOLE | +| wso2.apim.portOffset | int | `0` | Port Offset for APIM deployment | +| wso2.apim.secureVaultEnabled | bool | `false` | Secure vauld enabled | +| wso2.apim.startupArgs | string | `""` | Startup arguments for APIM | +| wso2.apim.version | string | `"4.2.0"` | APIM version | +| wso2.deployment.highAvailability | bool | `true` | Enable high availability for traffic manager. If this is enabled, two traffic manager instances will be deployed. This is not relavant to HA in Kubernetes. Multiple replicas of the same instance will not count as HA for TM. | +| wso2.deployment.image.digest | string | `""` | Docker image digest | +| wso2.deployment.image.imagePullPolicy | string | `"Always"` | Refer to the Kubernetes documentation on updating images (https://kubernetes.io/docs/concepts/containers/images/#updating-images) | +| wso2.deployment.image.registry | string | `""` | Container registry hostname | +| wso2.deployment.image.repository | string | `""` | Azure ACR repository name consisting the image | +| wso2.deployment.lifecycle.preStopHook.sleepSeconds | int | `10` | Number of seconds to sleep before sending SIGTERM to the pod | +| wso2.deployment.livenessProbe.failureThreshold | int | `3` | Minimum consecutive successes for the probe to be considered successful after having failed | +| wso2.deployment.livenessProbe.initialDelaySeconds | int | `60` | Number of seconds after the container has started before liveness probes are initiated | +| wso2.deployment.livenessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the probe | +| wso2.deployment.minAvailable | string | `"50%"` | Minimum available pod counts for PDB | +| wso2.deployment.nodeSelector | string | `nil` | Node selector to deploy pod in selected node. Add label to the node and specify the label here. | +| wso2.deployment.persistence.solrIndexing | object | `{"capacity":{"carbonDatabase":"50M","solrIndexedData":"50M"},"enabled":false}` | Persistent runtime artifacts for Apache Solr-based indexing | +| wso2.deployment.persistence.solrIndexing.capacity.carbonDatabase | string | `"50M"` | For persisting the H2 based local Carbon database file | +| wso2.deployment.persistence.solrIndexing.capacity.solrIndexedData | string | `"50M"` | For persisting the indexed solr data | +| wso2.deployment.persistence.solrIndexing.enabled | bool | `false` | Indicates if persistence of the runtime artifacts for Apache Solr-based indexing is enabled By default, this is disabled | +| wso2.deployment.readinessProbe.failureThreshold | int | `3` | Minimum consecutive successes for the probe to be considered successful after having failed | +| wso2.deployment.readinessProbe.initialDelaySeconds | int | `60` | Number of seconds after the container has started before readiness probes are initiated | +| wso2.deployment.readinessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the probe | +| wso2.deployment.replicas | int | `1` | | +| wso2.deployment.resources.jvm.memory.xms | string | `"2048m"` | JVM heap memory Xms | +| wso2.deployment.resources.jvm.memory.xmx | string | `"2048m"` | JVM heap memory Xmx | +| wso2.deployment.resources.limits.cpu | string | `"3000m"` | CPU limit for API Manager | +| wso2.deployment.resources.limits.memory | string | `"3Gi"` | Memory limit for API Manager | +| wso2.deployment.resources.requests.cpu | string | `"2000m"` | CPU request for API Manager | +| wso2.deployment.resources.requests.memory | string | `"2Gi"` | Memory request for API Manager | +| wso2.deployment.startupProbe.failureThreshold | int | `3` | Minimum consecutive successes for the probe to be considered successful after having failed | +| wso2.deployment.startupProbe.initialDelaySeconds | int | `60` | Number of seconds after the container has started before startup probes are initiated | +| wso2.deployment.startupProbe.periodSeconds | int | `10` | How often (in seconds) to perform the probe | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.11.2](https://github.com/norwoodj/helm-docs/releases/v1.11.2) diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/confs/api-manager.sh b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/api-manager.sh new file mode 100755 index 000000000..b1328c3eb --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/api-manager.sh @@ -0,0 +1,362 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Copyright 2005-2012 WSO2, Inc. http://www.wso2.org +# +# 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. + +# ---------------------------------------------------------------------------- +# Main Script for the WSO2 Carbon Server +# +# Environment Variable Prequisites +# +# CARBON_HOME Home of WSO2 Carbon installation. If not set I will try +# to figure it out. +# +# JAVA_HOME Must point at your Java Development Kit installation. +# +# JAVA_OPTS (Optional) Java runtime options used when the commands +# is executed. +# +# NOTE: Borrowed generously from Apache Tomcat startup scripts. +# ----------------------------------------------------------------------------- + +# OS specific support. $var _must_ be set to either true or false. +#ulimit -n 100000 + +cygwin=false; +darwin=false; +os400=false; +mingw=false; +case "`uname`" in +CYGWIN*) cygwin=true;; +MINGW*) mingw=true;; +OS400*) os400=true;; +Darwin*) darwin=true + if [ -z "$JAVA_VERSION" ] ; then + JAVA_VERSION="CurrentJDK" + else + echo "Using Java version: $JAVA_VERSION" + fi + if [ -z "$JAVA_HOME" ] ; then + JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home + fi + ;; +esac + +# resolve links - $0 may be a softlink +PRG="$0" + +while [ -h "$PRG" ]; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '.*/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`/"$link" + fi +done + +# Get standard environment variables +PRGDIR=`dirname "$PRG"` + +# Only set CARBON_HOME if not already set +[ -z "$CARBON_HOME" ] && CARBON_HOME=`cd "$PRGDIR/.." ; pwd` + +# Set AXIS2_HOME. Needed for One Click JAR Download +AXIS2_HOME="$CARBON_HOME" + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CARBON_HOME" ] && CARBON_HOME=`cygpath --unix "$CARBON_HOME"` + [ -n "$AXIS2_HOME" ] && CARBON_HOME=`cygpath --unix "$CARBON_HOME"` +fi + +# For OS400 +if $os400; then + # Set job priority to standard for interactive (interactive - 6) by using + # the interactive priority - 6, the helper threads that respond to requests + # will be running at the same priority as interactive jobs. + COMMAND='chgjob job('$JOBNAME') runpty(6)' + system $COMMAND + + # Enable multi threading + QIBM_MULTI_THREADED=Y + export QIBM_MULTI_THREADED +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$CARBON_HOME" ] && + CARBON_HOME="`(cd "$CARBON_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + [ -n "$AXIS2_HOME" ] && + CARBON_HOME="`(cd "$CARBON_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD=java + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." + echo " CARBON cannot execute $JAVACMD" + exit 1 +fi + +# if JAVA_HOME is not set we're not happy +if [ -z "$JAVA_HOME" ]; then + echo "You must set the JAVA_HOME variable before running CARBON." + exit 1 +fi + +if [ -e "$CARBON_HOME/wso2carbon.pid" ]; then + PID=`cat "$CARBON_HOME"/wso2carbon.pid` +fi + +# ----- Process the input command ---------------------------------------------- +args="" +for c in $* +do + if [ "$c" = "--debug" ] || [ "$c" = "-debug" ] || [ "$c" = "debug" ]; then + CMD="--debug" + continue + elif [ "$CMD" = "--debug" ]; then + if [ -z "$PORT" ]; then + PORT=$c + fi + elif [ "$c" = "--stop" ] || [ "$c" = "-stop" ] || [ "$c" = "stop" ]; then + CMD="stop" + elif [ "$c" = "--start" ] || [ "$c" = "-start" ] || [ "$c" = "start" ]; then + CMD="start" + elif [ "$c" = "--version" ] || [ "$c" = "-version" ] || [ "$c" = "version" ]; then + CMD="version" + elif [ "$c" = "--restart" ] || [ "$c" = "-restart" ] || [ "$c" = "restart" ]; then + CMD="restart" + elif [ "$c" = "--test" ] || [ "$c" = "-test" ] || [ "$c" = "test" ]; then + CMD="test" + elif [ "$c" = "--optimize" ] || [ "$c" = "-optimize" ] || [ "$c" = "optimize" ]; then + for option in $*; do + if [ "$option" = "--skipConfigOptimization" ] || [ "$option" = "-skipConfigOptimization" ] || + [ "$option" = "skipConfigOptimization" ]; then + passedSkipConfigOptimizationOption=true + echo "Passed skipConfigOptimization Option: $passedSkipConfigOptimizationOption" + fi + done + + for profile in $*; do + case "$profile" in + *Dprofile=*) + cd $(dirname "$0") + if [ "$passedSkipConfigOptimizationOption" = true ]; then + sh profileSetup.sh $profile --skipConfigOptimization + else + sh profileSetup.sh $profile + fi + echo "Starting the server..." + ;; + esac + done + else + args="$args $c" + fi +done + +if [ "$CMD" = "--debug" ]; then + if [ "$PORT" = "" ]; then + echo " Please specify the debug port after the --debug option" + exit 1 + fi + if [ -n "$JAVA_OPTS" ]; then + echo "Warning !!!. User specified JAVA_OPTS will be ignored, once you give the --debug option." + fi + CMD="RUN" + JAVA_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=$PORT" + echo "Please start the remote debugging client to continue..." +elif [ "$CMD" = "start" ]; then + if [ -e "$CARBON_HOME/wso2carbon.pid" ]; then + if ps -p $PID > /dev/null ; then + echo "Process is already running" + exit 0 + fi + fi + export CARBON_HOME="$CARBON_HOME" +# using nohup sh to avoid erros in solaris OS.TODO + nohup sh "$CARBON_HOME"/bin/api-manager.sh $args > /dev/null 2>&1 & + exit 0 +elif [ "$CMD" = "stop" ]; then + export CARBON_HOME="$CARBON_HOME" + kill -term `cat "$CARBON_HOME"/wso2carbon.pid` + exit 0 +elif [ "$CMD" = "restart" ]; then + export CARBON_HOME="$CARBON_HOME" + kill -term `cat "$CARBON_HOME"/wso2carbon.pid` + process_status=0 + pid=`cat "$CARBON_HOME"/wso2carbon.pid` + while [ "$process_status" -eq "0" ] + do + sleep 1; + ps -p$pid 2>&1 > /dev/null + process_status=$? + done + +# using nohup sh to avoid erros in solaris OS.TODO + nohup sh "$CARBON_HOME"/bin/api-manager.sh $args > /dev/null 2>&1 & + exit 0 +elif [ "$CMD" = "test" ]; then + JAVACMD="exec "$JAVACMD"" +elif [ "$CMD" = "version" ]; then + cat "$CARBON_HOME"/bin/version.txt + cat "$CARBON_HOME"/bin/wso2carbon-version.txt + exit 0 +fi + +# ---------- Handle the SSL Issue with proper JDK version -------------------- +java_version=$("$JAVACMD" -version 2>&1 | awk -F '"' '/version/ {print $2}') +java_version_formatted=$(echo "$java_version" | awk -F. '{printf("%02d%02d",$1,$2);}') +if [ $java_version_formatted -lt 1100 ] || [ $java_version_formatted -gt 1700 ]; then + echo " Starting WSO2 Carbon (in unsupported JDK)" + echo " [ERROR] CARBON is supported only between JDK 11 and JDK 17" +fi + +CARBON_XBOOTCLASSPATH="" +for f in "$CARBON_HOME"/lib/xboot/*.jar +do + if [ "$f" != "$CARBON_HOME/lib/xboot/*.jar" ];then + CARBON_XBOOTCLASSPATH="$CARBON_XBOOTCLASSPATH":$f + fi +done + + +CARBON_CLASSPATH="" +if [ -e "$JAVA_HOME/lib/tools.jar" ]; then + CARBON_CLASSPATH="$JAVA_HOME/lib/tools.jar" +fi +for f in "$CARBON_HOME"/bin/*.jar +do + if [ "$f" != "$CARBON_HOME/bin/*.jar" ];then + CARBON_CLASSPATH="$CARBON_CLASSPATH":$f + fi +done +for t in "$CARBON_HOME"/lib/*.jar +do + CARBON_CLASSPATH="$CARBON_CLASSPATH":$t +done +for t in "$CARBON_HOME"/lib/endorsed/*.jar +do + CARBON_CLASSPATH="$CARBON_CLASSPATH":$t +done + + + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + JAVA_HOME=`cygpath --absolute --windows "$JAVA_HOME"` + CARBON_HOME=`cygpath --absolute --windows "$CARBON_HOME"` + AXIS2_HOME=`cygpath --absolute --windows "$CARBON_HOME"` + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + CARBON_CLASSPATH=`cygpath --path --windows "$CARBON_CLASSPATH"` + CARBON_XBOOTCLASSPATH=`cygpath --path --windows "$CARBON_XBOOTCLASSPATH"` +fi + +# ----- Execute The Requested Command ----------------------------------------- + +echo JAVA_HOME environment variable is set to $JAVA_HOME +echo CARBON_HOME environment variable is set to "$CARBON_HOME" + +cd "$CARBON_HOME" + +TMP_DIR="$CARBON_HOME"/tmp +if [ -d "$TMP_DIR" ]; then +rm -rf "$TMP_DIR"/* +fi + +START_EXIT_STATUS=121 +status=$START_EXIT_STATUS + +if [ -z "$JVM_MEM_OPTS" ]; then + java_version=$("$JAVACMD" -version 2>&1 | awk -F '"' '/version/ {print $2}') + JVM_MEM_OPTS="-Xms256m -Xmx1024m" + if [ "$java_version" \< "1.8" ]; then + JVM_MEM_OPTS="$JVM_MEM_OPTS -XX:MaxPermSize=256m" + fi +fi +echo "Using Java memory options: $JVM_MEM_OPTS" + +#To monitor a Carbon server in remote JMX mode on linux host machines, set the below system property. +# -Djava.rmi.server.hostname="your.IP.goes.here" + +JAVA_VER_BASED_OPTS="--add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED" + +if [ $java_version_formatted -ge 1700 ]; then + JAVA_VER_BASED_OPTS="$JAVA_VER_BASED_OPTS --add-opens=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/sun.security.x509=ALL-UNNAMED" +fi + +while [ "$status" = "$START_EXIT_STATUS" ] +do + $JAVACMD \ + -Xbootclasspath/a:"$CARBON_XBOOTCLASSPATH" \ + $JVM_MEM_OPTS \ + -XX:+HeapDumpOnOutOfMemoryError \ + -XX:HeapDumpPath="$CARBON_HOME/repository/logs/heap-dump.hprof" \ + $JAVA_OPTS \ + -Dcom.sun.management.jmxremote \ + -classpath "$CARBON_CLASSPATH" \ + $JAVA_VER_BASED_OPTS \ + -Djava.io.tmpdir="$CARBON_HOME/tmp" \ + -Dcatalina.base="$CARBON_HOME/lib/tomcat" \ + -Dwso2.server.standalone=true \ + -Dcarbon.registry.root=/ \ + -Djava.command="$JAVACMD" \ + -Dcarbon.home="$CARBON_HOME" \ + -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \ + -Dcarbon.config.dir.path="$CARBON_HOME/repository/conf" \ + -Djava.util.logging.config.file="$CARBON_HOME/repository/conf/etc/logging-bridge.properties" \ + -Dcomponents.repo="$CARBON_HOME/repository/components/plugins" \ + -Dconf.location="$CARBON_HOME/repository/conf"\ + -Dcom.atomikos.icatch.file="$CARBON_HOME/lib/transactions.properties" \ + -Dcom.atomikos.icatch.hide_init_file_path=true \ + -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false \ + -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true \ + -Dcom.sun.jndi.ldap.connect.pool.authentication=simple \ + -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 \ + -Dorg.terracotta.quartz.skipUpdateCheck=true \ + -Djava.security.egd=file:/dev/./urandom \ + -Dfile.encoding=UTF8 \ + -Djava.net.preferIPv4Stack=true \ + -Dcom.ibm.cacheLocalHost=true \ + -Dorg.opensaml.httpclient.https.disableHostnameVerification=true \ + -Dhttpclient.hostnameVerifier=AllowAll \ + -DworkerNode=false \ + -DenableCorrelationLogs=false \ + -Dcarbon.new.config.dir.path="$CARBON_HOME/repository/resources/conf" \ + -Djavax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom=net.sf.saxon.xpath.XPathFactoryImpl \ + -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \ + -Dorg.ops4j.pax.logging.logReaderEnabled=false \ + -Dorg.ops4j.pax.logging.eventAdminEnabled=false \ + -Djdk.nio.zipfs.allowDotZipEntry=true \ + -Djdk.util.zip.disableZip64ExtraFieldValidation=true \ + org.wso2.carbon.bootstrap.Bootstrap $* + status=$? +done diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/confs/instance-1/deployment.toml b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/instance-1/deployment.toml new file mode 100644 index 000000000..8c26d8543 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/instance-1/deployment.toml @@ -0,0 +1,283 @@ +[server] +hostname = "{{ .Values.kubernetes.ingress.controlPlane.hostname }}" +#node_ip = "$env{NODE_IP}" +offset = {{ .Values.wso2.apim.portOffset }} +base_path = "${carbon.protocol}://${carbon.host}:${carbon.management.port}" +#discard_empty_caches = false +server_role = "control-plane" + +[user_store] +type = {{ .Values.wso2.apim.configurations.userStore.type | quote }} +{{- range $key, $value := .Values.wso2.apim.configurations.userStore.properties }} +{{ $key }} = {{ $value | quote }} +{{- end }} + +[super_admin] +username = {{ .Values.wso2.apim.configurations.adminUsername | quote }} +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{admin_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.adminPassword | quote }} +{{- end }} +create_admin_account = true + +[database.apim_db] +type = "{{ .Values.wso2.apim.configurations.databases.type }}" +url = "{{ .Values.wso2.apim.configurations.databases.apim_db.url}}" +username = "{{ .Values.wso2.apim.configurations.databases.apim_db.username }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{apim_db_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.databases.apim_db.password | quote }} +{{- end }} + +[database.apim_db.pool_options] +{{- range $key, $value := .Values.wso2.apim.configurations.databases.apim_db.poolParameters }} +{{ $key }} = "{{ $value }}" +{{- end }} + +[database.shared_db] +type = "{{ .Values.wso2.apim.configurations.databases.type }}" +url = "{{ .Values.wso2.apim.configurations.databases.shared_db.url}}" +username = "{{ .Values.wso2.apim.configurations.databases.shared_db.username }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{shared_db_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.databases.shared_db.password | quote }} +{{- end }} + +[database.shared_db.pool_options] +{{- range $key, $value := .Values.wso2.apim.configurations.databases.shared_db.poolParameters }} +{{ $key }} = "{{ $value }}" +{{- end }} + +{{- if .Values.wso2.apim.configurations.security.keystores.primary.enabled }} +[keystore.primary] +type = "JKS" +file_name = "{{ .Values.wso2.apim.configurations.security.keystores.primary.name }}" +alias = "{{ .Values.wso2.apim.configurations.security.keystores.primary.alias }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{keystore_password}" +key_password = "$secret{keystore_key_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.security.keystores.primary.password | quote }} +key_password = {{ .Values.wso2.apim.configurations.security.keystores.primary.keyPassword | quote }} +{{- end }} +{{- end }} + +{{- if .Values.wso2.apim.configurations.security.keystores.tls.enabled }} +[keystore.tls] +type = "JKS" +file_name = "{{ .Values.wso2.apim.configurations.security.keystores.tls.name }}" +alias = "{{ .Values.wso2.apim.configurations.security.keystores.tls.alias }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{ssl_keystore_password}" +key_password = "$secret{ssl_key_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.security.keystores.tls.password | quote }} +key_password = {{ .Values.wso2.apim.configurations.security.keystores.tls.keyPassword | quote }} +{{- end }} +{{- end }} + +{{- if .Values.wso2.apim.configurations.security.keystores.internal.enabled }} +[keystore.internal] +type = "JKS" +file_name = "{{ .Values.wso2.apim.configurations.security.keystores.internal.name }}" +alias = "{{ .Values.wso2.apim.configurations.security.keystores.internal.alias }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{internal_keystore_password}" +key_password = "$secret{internal_keystore_key_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.security.keystores.internal.password | quote }} +key_password = {{ .Values.wso2.apim.configurations.security.keystores.internal.keyPassword | quote }} +{{- end }} +{{- end }} + +[truststore] +type = "JKS" +file_name = "{{ .Values.wso2.apim.configurations.security.truststore.name }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{truststore_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.security.truststore.password | quote }} +{{- end }} + +{{- range $i, $env := .Values.wso2.apim.configurations.gateway.environments }} +[[apim.gateway.environment]] +name = {{ $env.name | quote }} +type = {{ $env.type | quote }} +gateway_type = "APK" +provider = {{ $env.provider | quote }} +display_in_api_console = {{ $env.displayInApiConsole }} +description = {{ $env.description | quote }} +show_as_token_endpoint_url = {{ $env.showAsTokenEndpointUrl }} +service_url = "https://{{ $env.serviceName }}:{{ $env.servicePort }}/services/" +username= "${admin.username}" +password= "${admin.password}" +ws_endpoint = "ws://{{ $env.wsHostname }}" +wss_endpoint = "wss://{{ $env.wsHostname }}" +http_endpoint = "http://{{ $env.httpHostname }}" +https_endpoint = "https://{{ $env.httpHostname }}" +websub_event_receiver_http_endpoint = "http://{{ $env.websubHostname }}" +websub_event_receiver_https_endpoint = "https://{{ $env.websubHostname }}" + +{{- end }} + +[apim.key_manager] +{{- if .Values.wso2.apim.configurations.iskm.enabled }} +type = "WSO2-IS" +service_url = "https://{{ .Values.wso2.apim.configurations.iskm.serviceName }}:{{ .Values.wso2.apim.configurations.iskm.servicePort }}/services/" +{{- else }} +service_url = "https://{{ template "apim-helm-cp.fullname" . }}-service:{{ add 9443 .Values.wso2.apim.portOffset }}/services/" +{{- end }} +username= "$ref{super_admin.username}" +password= "$ref{super_admin.password}" + +{{ if .Values.wso2.apim.configurations.iskm.enabled }} +[oauth.grant_type.token_exchange] +enable = false +allow_refresh_tokens = true +iat_validity_period = "1h" +{{- end }} + +#[apim.publisher] +#{{- if .Values.wso2.apim.configurations.publisher.supportedDocumentTypes }} +#supported_document_types = {{ toJson .Values.wso2.apim.configurations.publisher.supportedDocumentTypes }} +#{{- end }} + +[apim.devportal] +url = "https://{{ .Values.kubernetes.ingress.controlPlane.hostname }}/devportal" +{{- if .Values.wso2.apim.configurations.devportal.enableApplicationSharing }} +enable_application_sharing = {{ .Values.wso2.apim.configurations.devportal.enableApplicationSharing }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.applicationSharingType }} +application_sharing_type = {{ .Values.wso2.apim.configurations.devportal.applicationSharingType | quote }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.applicationSharingImpl }} +application_sharing_impl = {{ .Values.wso2.apim.configurations.devportal.applicationSharingImpl | quote }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.displayMultipleVersions }} +display_multiple_versions = {{ .Values.wso2.apim.configurations.devportal.displayMultipleVersions }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.displayDeprecatedAPIs }} +display_deprecated_apis = {{ .Values.wso2.apim.configurations.devportal.displayDeprecatedAPIs }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableComments }} +enable_comments = {{ .Values.wso2.apim.configurations.devportal.enableComments }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableRatings }} +enable_ratings = {{ .Values.wso2.apim.configurations.devportal.enableRatings }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableForum }} +enable_forum = {{ .Values.wso2.apim.configurations.devportal.enableForum }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableAnonymousMode }} +enable_anonymous_mode = {{ .Values.wso2.apim.configurations.devportal.enableAnonymousMode }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableCrossTenantSubscriptions }} +enable_cross_tenant_subscriptions = {{ .Values.wso2.apim.configurations.devportal.enableCrossTenantSubscriptions }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.defaultReservedUsername }} +default_reserved_username = {{ .Values.wso2.apim.configurations.devportal.defaultReservedUsername | quote }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.loginUsernameCaseInsensitive }} +login_username_case_insensitive = {{ .Values.wso2.apim.configurations.devportal.loginUsernameCaseInsensitive }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableKeyProvisioning }} +enable_key_provisioning = {{ .Values.wso2.apim.configurations.devportal.enableKeyProvisioning }} +{{- end }} + +[apim.event_hub] +enable = true +username = "$ref{super_admin.username}" +password = "$ref{super_admin.password}" +service_url = "https://{{ template "apim-helm-cp.fullname" . }}-service:{{ add 9443 .Values.wso2.apim.portOffset }}/services/" +event_listening_endpoints = ["tcp://localhost:{{ add 5672 .Values.wso2.apim.portOffset }}"] +{{- if .Values.wso2.deployment.highAvailability }} +event_duplicate_url = ["tcp://{{ template "apim-helm-cp.fullname" . }}-2-service:{{ add 5672 .Values.wso2.apim.portOffset }}"] +{{- end }} + +[[apim.event_hub.publish.url_group]] +urls = ["tcp://{{ template "apim-helm-cp.fullname" . }}-1-service:{{ add 9611 .Values.wso2.apim.portOffset }}"] +auth_urls = ["ssl://{{ template "apim-helm-cp.fullname" . }}-1-service:{{ add 9711 .Values.wso2.apim.portOffset }}"] + +{{- if .Values.wso2.deployment.highAvailability }} +[[apim.event_hub.publish.url_group]] +urls = ["tcp://{{ template "apim-helm-cp.fullname" . }}-2-service:{{ add 9611 .Values.wso2.apim.portOffset }}"] +auth_urls = ["ssl://{{ template "apim-helm-cp.fullname" . }}-2-service:{{ add 9711 .Values.wso2.apim.portOffset }}"] +{{- end }} + +[apim.oauth_config] +{{- if .Values.wso2.apim.configurations.iskm.enabled }} +revoke_endpoint = "https://{{ .Values.wso2.apim.configurations.iskm.serviceName }}:{{ .Values.wso2.apim.configurations.iskm.servicePort }}/oauth2/revoke" +{{- else }} +revoke_endpoint = "https://{{ template "apim-helm-cp.fullname" . }}-service:{{ add 9443 .Values.wso2.apim.portOffset }}/oauth2/revoke" +{{- end }} +enable_token_encryption = {{ .Values.wso2.apim.configurations.oauth_config.enableTokenEncryption }} +enable_token_hashing = {{ .Values.wso2.apim.configurations.oauth_config.enableTokenHashing }} +allowed_scopes = {{ toJson .Values.wso2.apim.configurations.oauth_config.allowedScopes }} + +{{- if .Values.wso2.apim.configurations.openTracer.enabled }} +[apim.open_tracer] +remote_tracer.enable = {{ .Values.wso2.apim.configurations.openTracer.enabled }} +remote_tracer.name = {{ .Values.wso2.apim.configurations.openTracer.name | quote }} +remote_tracer.properties.hostname = {{ .Values.wso2.apim.configurations.openTracer.properties.hostname | quote }} +remote_tracer.properties.port = {{ .Values.wso2.apim.configurations.openTracer.properties.port | quote }} +{{- end }} + +{{- if .Values.wso2.apim.configurations.openTelemetry.enabled }} +[apim.open_telemetry] +remote_tracer.enable = {{ .Values.wso2.apim.configurations.openTelemetry.enabled }} +remote_tracer.name = {{ .Values.wso2.apim.configurations.openTelemetry.name | quote }} +remote_tracer.hostname = {{ .Values.wso2.apim.configurations.openTelemetry.hostname | quote }} +remote_tracer.port = {{ .Values.wso2.apim.configurations.openTelemetry.port | quote }} +{{- end }} + +[transport.https.properties] +proxyPort = 443 + +[[event_handler]] +name="userPostSelfRegistration" +subscriptions=["POST_ADD_USER"] + +[service_provider] +sp_name_regex = "^[\\sa-zA-Z0-9._-]*$" + +{{- if not .Values.wso2.apim.configurations.iskm.enabled }} +[[event_listener]] +id = "token_revocation" +type = "org.wso2.carbon.identity.core.handler.AbstractIdentityHandler" +name = "org.wso2.is.notification.ApimOauthEventInterceptor" +order = 1 + +[event_listener.properties] +notification_endpoint = "https://localhost:${mgt.transport.https.port}/internal/data/v1/notify" +username = "${admin.username}" +password = "${admin.password}" +'header.X-WSO2-KEY-MANAGER' = "default" +{{- end }} + +{{- if .Values.wso2.deployment.persistence.solrIndexing.enabled }} +[database.local] +url = "jdbc:h2:/home/wso2carbon/solr/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE" + +[indexing] +location = "/home/wso2carbon/solr/indexed-data" +{{- else }} +[database.local] +url = "jdbc:h2:./repository/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE" +{{- end }} + +{{- if .Values.wso2.apim.secureVaultEnabled }} +[secrets] +admin_password = {{ .Values.wso2.apim.configurations.adminPassword | quote }} +keystore_password = {{ .Values.wso2.apim.configurations.security.keystores.primary.password | quote }} +keystore_key_password = {{ .Values.wso2.apim.configurations.security.keystores.primary.keyPassword | quote }} +ssl_keystore_password = {{ .Values.wso2.apim.configurations.security.keystores.tls.password | quote }} +ssl_key_password = {{ .Values.wso2.apim.configurations.security.keystores.tls.keyPassword | quote }} +internal_keystore_password = {{ .Values.wso2.apim.configurations.security.keystores.internal.password | quote }} +internal_keystore_key_password = {{ .Values.wso2.apim.configurations.security.keystores.internal.keyPassword | quote }} +truststore_password = {{ .Values.wso2.apim.configurations.security.truststore.password | quote }} +apim_db_password = {{ .Values.wso2.apim.configurations.databases.apim_db.password | quote}} +shared_db_password = {{ .Values.wso2.apim.configurations.databases.shared_db.password | quote}} +{{- end}} \ No newline at end of file diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/confs/instance-2/deployment.toml b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/instance-2/deployment.toml new file mode 100644 index 000000000..91c7c77b4 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/instance-2/deployment.toml @@ -0,0 +1,270 @@ +[server] +hostname = "{{ .Values.kubernetes.ingress.controlPlane.hostname }}" +node_ip = "$env{NODE_IP}" +offset = {{ .Values.wso2.apim.portOffset }} +base_path = "${carbon.protocol}://${carbon.host}:${carbon.management.port}" +#discard_empty_caches = false +server_role = "control-plane" + +[user_store] +type = {{ .Values.wso2.apim.configurations.userStore.type | quote }} +{{- range $key, $value := .Values.wso2.apim.configurations.userStore.properties }} +{{ $key }} = {{ $value | quote }} +{{- end }} + +[super_admin] +username = {{ .Values.wso2.apim.configurations.adminUsername | quote }} +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{admin_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.adminPassword | quote }} +{{- end }} +create_admin_account = true + +[database.apim_db] +type = "{{ .Values.wso2.apim.configurations.databases.type }}" +url = "{{ .Values.wso2.apim.configurations.databases.apim_db.url}}" +username = "{{ .Values.wso2.apim.configurations.databases.apim_db.username }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{apim_db_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.databases.apim_db.password | quote }} +{{- end }} +driver = "{{ .Values.wso2.apim.configurations.databases.jdbc.driver }}" + +[database.apim_db.pool_options] +{{- range $key, $value := .Values.wso2.apim.configurations.databases.apim_db.poolParameters }} +{{ $key }} = "{{ $value }}" +{{- end }} + +[database.shared_db] +type = "{{ .Values.wso2.apim.configurations.databases.type }}" +url = "{{ .Values.wso2.apim.configurations.databases.shared_db.url}}" +username = "{{ .Values.wso2.apim.configurations.databases.shared_db.username }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{shared_db_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.databases.shared_db.password | quote }} +{{- end }} +driver = "{{ .Values.wso2.apim.configurations.databases.jdbc.driver }}" + +[database.shared_db.pool_options] +{{- range $key, $value := .Values.wso2.apim.configurations.databases.shared_db.poolParameters }} +{{ $key }} = "{{ $value }}" +{{- end }} + +{{- if .Values.wso2.apim.configurations.security.keystores.primary.enabled }} +[keystore.primary] +type = "JKS" +file_name = "{{ .Values.wso2.apim.configurations.security.keystores.primary.name }}" +alias = "{{ .Values.wso2.apim.configurations.security.keystores.primary.alias }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{keystore_password}" +key_password = "$secret{keystore_key_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.security.keystores.primary.password | quote }} +key_password = {{ .Values.wso2.apim.configurations.security.keystores.primary.keyPassword | quote }} +{{- end }} +{{- end }} + +{{- if .Values.wso2.apim.configurations.security.keystores.tls.enabled }} +[keystore.tls] +type = "JKS" +file_name = "{{ .Values.wso2.apim.configurations.security.keystores.tls.name }}" +alias = "{{ .Values.wso2.apim.configurations.security.keystores.tls.alias }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{ssl_keystore_password}" +key_password = "$secret{ssl_key_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.security.keystores.tls.password | quote }} +key_password = {{ .Values.wso2.apim.configurations.security.keystores.tls.keyPassword | quote }} +{{- end }} +{{- end }} + +{{- if .Values.wso2.apim.configurations.security.keystores.internal.enabled }} +[keystore.internal] +type = "JKS" +file_name = "{{ .Values.wso2.apim.configurations.security.keystores.internal.name }}" +alias = "{{ .Values.wso2.apim.configurations.security.keystores.internal.alias }}" +{{- if .Values.wso2.apim.secureVaultEnabled }} +password = "$secret{internal_keystore_password}" +key_password = "$secret{internal_keystore_key_password}" +{{- else }} +password = {{ .Values.wso2.apim.configurations.security.keystores.internal.password | quote }} +key_password = {{ .Values.wso2.apim.configurations.security.keystores.internal.keyPassword | quote }} +{{- end }} +{{- end }} + +{{- range $i, $env := .Values.wso2.apim.configurations.gateway.environments }} +[[apim.gateway.environment]] +name = {{ $env.name | quote }} +type = {{ $env.type | quote }} +provider = {{ $env.provider | quote }} +display_in_api_console = {{ $env.displayInApiConsole }} +description = {{ $env.description | quote }} +show_as_token_endpoint_url = {{ $env.showAsTokenEndpointUrl }} +service_url = "https://{{ $env.serviceName }}:{{ $env.servicePort }}/services/" +username= "${admin.username}" +password= "${admin.password}" +ws_endpoint = "ws://{{ $env.wsHostname }}" +wss_endpoint = "wss://{{ $env.wsHostname }}" +http_endpoint = "http://{{ $env.httpHostname }}" +https_endpoint = "https://{{ $env.httpHostname }}" +websub_event_receiver_http_endpoint = "http://{{ $env.websubHostname }}" +websub_event_receiver_https_endpoint = "https://{{ $env.websubHostname }}" + +{{- end }} + +[apim.key_manager] +{{- if .Values.wso2.apim.configurations.iskm.enabled }} +type = "WSO2-IS" +service_url = "https://{{ .Values.wso2.apim.configurations.iskm.serviceName }}:{{ .Values.wso2.apim.configurations.iskm.servicePort }}/services/" +{{- else }} +service_url = "https://{{ template "apim-helm-cp.fullname" . }}-service:{{ add 9443 .Values.wso2.apim.portOffset }}/services/" +{{- end }} +username= "$ref{super_admin.username}" +password= "$ref{super_admin.password}" + +{{ if .Values.wso2.apim.configurations.iskm.enabled }} +[oauth.grant_type.token_exchange] +enable = false +allow_refresh_tokens = true +iat_validity_period = "1h" +{{- end }} + +[apim.devportal] +url = "https://{{ .Values.kubernetes.ingress.controlPlane.hostname }}/devportal" +{{- if .Values.wso2.apim.configurations.devportal.enableApplicationSharing }} +enable_application_sharing = {{ .Values.wso2.apim.configurations.devportal.enableApplicationSharing }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.applicationSharingType }} +application_sharing_type = {{ .Values.wso2.apim.configurations.devportal.applicationSharingType | quote }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.applicationSharingImpl }} +application_sharing_impl = {{ .Values.wso2.apim.configurations.devportal.applicationSharingImpl | quote }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.displayMultipleVersions }} +display_multiple_versions = {{ .Values.wso2.apim.configurations.devportal.displayMultipleVersions }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.displayDeprecatedAPIs }} +display_deprecated_apis = {{ .Values.wso2.apim.configurations.devportal.displayDeprecatedAPIs }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableComments }} +enable_comments = {{ .Values.wso2.apim.configurations.devportal.enableComments }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableRatings }} +enable_ratings = {{ .Values.wso2.apim.configurations.devportal.enableRatings }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableForum }} +enable_forum = {{ .Values.wso2.apim.configurations.devportal.enableForum }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableAnonymousMode }} +enable_anonymous_mode = {{ .Values.wso2.apim.configurations.devportal.enableAnonymousMode }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableCrossTenantSubscriptions }} +enable_cross_tenant_subscriptions = {{ .Values.wso2.apim.configurations.devportal.enableCrossTenantSubscriptions }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.defaultReservedUsername }} +default_reserved_username = {{ .Values.wso2.apim.configurations.devportal.defaultReservedUsername | quote }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.loginUsernameCaseInsensitive }} +login_username_case_insensitive = {{ .Values.wso2.apim.configurations.devportal.loginUsernameCaseInsensitive }} +{{- end }} +{{- if .Values.wso2.apim.configurations.devportal.enableKeyProvisioning }} +enable_key_provisioning = {{ .Values.wso2.apim.configurations.devportal.enableKeyProvisioning }} +{{- end }} + +[apim.event_hub] +enable = true +username = "$ref{super_admin.username}" +password = "$ref{super_admin.password}" +service_url = "https://{{ template "apim-helm-cp.fullname" . }}-service:{{ add 9443 .Values.wso2.apim.portOffset }}/services/" +event_listening_endpoints = ["tcp://localhost:{{ add 5672 .Values.wso2.apim.portOffset }}"] +{{- if .Values.wso2.deployment.highAvailability }} +event_duplicate_url = ["tcp://{{ template "apim-helm-cp.fullname" . }}-1-service:{{ add 5672 .Values.wso2.apim.portOffset }}"] +{{- end }} + +[[apim.event_hub.publish.url_group]] +urls = ["tcp://{{ template "apim-helm-cp.fullname" . }}-1-service:{{ add 9611 .Values.wso2.apim.portOffset }}"] +auth_urls = ["ssl://{{ template "apim-helm-cp.fullname" . }}-1-service:{{ add 9711 .Values.wso2.apim.portOffset }}"] + +{{- if .Values.wso2.deployment.highAvailability }} +[[apim.event_hub.publish.url_group]] +urls = ["tcp://{{ template "apim-helm-cp.fullname" . }}-2-service:{{ add 9611 .Values.wso2.apim.portOffset }}"] +auth_urls = ["ssl://{{ template "apim-helm-cp.fullname" . }}-2-service:{{ add 9711 .Values.wso2.apim.portOffset }}"] +{{- end }} + +[apim.oauth_config] +{{- if .Values.wso2.apim.configurations.iskm.enabled }} +revoke_endpoint = "https://{{ .Values.wso2.apim.configurations.iskm.serviceName }}:{{ .Values.wso2.apim.configurations.iskm.servicePort }}/oauth2/revoke" +{{- else }} +revoke_endpoint = "https://{{ template "apim-helm-cp.fullname" . }}-service:{{ add 9443 .Values.wso2.apim.portOffset }}/oauth2/revoke" +{{- end }} +enable_token_encryption = {{ .Values.wso2.apim.configurations.oauth_config.enableTokenEncryption }} +enable_token_hashing = {{ .Values.wso2.apim.configurations.oauth_config.enableTokenHashing }} +allowed_scopes = {{ toJson .Values.wso2.apim.configurations.oauth_config.allowedScopes }} + +{{- if .Values.wso2.apim.configurations.openTracer.enabled }} +[apim.open_tracer] +remote_tracer.enable = {{ .Values.wso2.apim.configurations.openTracer.enabled }} +remote_tracer.name = {{ .Values.wso2.apim.configurations.openTracer.name | quote }} +remote_tracer.properties.hostname = {{ .Values.wso2.apim.configurations.openTracer.properties.hostname | quote }} +remote_tracer.properties.port = {{ .Values.wso2.apim.configurations.openTracer.properties.port | quote }} +{{- end }} + +{{- if .Values.wso2.apim.configurations.openTelemetry.enabled }} +[apim.open_telemetry] +remote_tracer.enable = {{ .Values.wso2.apim.configurations.openTelemetry.enabled }} +remote_tracer.name = {{ .Values.wso2.apim.configurations.openTelemetry.name | quote }} +remote_tracer.hostname = {{ .Values.wso2.apim.configurations.openTelemetry.hostname | quote }} +remote_tracer.port = {{ .Values.wso2.apim.configurations.openTelemetry.port | quote }} +{{- end }} + +[transport.https.properties] +proxyPort = 443 + +[[event_handler]] +name="userPostSelfRegistration" +subscriptions=["POST_ADD_USER"] + +[service_provider] +sp_name_regex = "^[\\sa-zA-Z0-9._-]*$" + +{{- if not .Values.wso2.apim.configurations.iskm.enabled }} +[[event_listener]] +id = "token_revocation" +type = "org.wso2.carbon.identity.core.handler.AbstractIdentityHandler" +name = "org.wso2.is.notification.ApimOauthEventInterceptor" +order = 1 + +[event_listener.properties] +notification_endpoint = "https://localhost:${mgt.transport.https.port}/internal/data/v1/notify" +username = "${admin.username}" +password = "${admin.password}" +'header.X-WSO2-KEY-MANAGER' = "default" +{{- end }} + +{{- if .Values.wso2.deployment.persistence.solrIndexing.enabled }} +[database.local] +url = "jdbc:h2:/home/wso2carbon/solr/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE" + +[indexing] +location = "/home/wso2carbon/solr/indexed-data" +{{- else }} +[database.local] +url = "jdbc:h2:./repository/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE" +{{- end }} + +{{- if .Values.wso2.apim.secureVaultEnabled }} +[secrets] +admin_password = {{ .Values.wso2.apim.configurations.adminPassword | quote }} +keystore_password = {{ .Values.wso2.apim.configurations.security.keystores.primary.password | quote }} +keystore_key_password = {{ .Values.wso2.apim.configurations.security.keystores.primary.keyPassword | quote }} +ssl_keystore_password = {{ .Values.wso2.apim.configurations.security.keystores.tls.password | quote }} +ssl_key_password = {{ .Values.wso2.apim.configurations.security.keystores.tls.keyPassword | quote }} +internal_keystore_password = {{ .Values.wso2.apim.configurations.security.keystores.internal.password | quote }} +internal_keystore_key_password = {{ .Values.wso2.apim.configurations.security.keystores.internal.keyPassword | quote }} +truststore_password = {{ .Values.wso2.apim.configurations.security.truststore.password | quote }} +apim_db_password = {{ .Values.wso2.apim.configurations.databases.apim_db.password | quote}} +shared_db_password = {{ .Values.wso2.apim.configurations.databases.shared_db.password | quote}} +{{- end}} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/confs/log4j2.properties b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/log4j2.properties new file mode 100644 index 000000000..f3f40b696 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/log4j2.properties @@ -0,0 +1,525 @@ +# list of all appenders +#add entry "syslog" to use the syslog appender +{{- if .Values.wso2.apim.log4j2.appenders }} +appenders = {{ .Values.wso2.apim.log4j2.appenders }}, CARBON_CONSOLE,HTTP_ACCESS_CONSOLE,AUDIT_CONSOLE,TRANSACTION_CONSOLE,CORRELATION_CONSOLE,CARBON_LOGFILE,AUDIT_LOGFILE,ATOMIKOS_LOGFILE,CARBON_TRACE_LOGFILE,ERROR_LOGFILE,OPEN_TRACING,SERVICE_APPENDER,TRACE_APPENDER,osgi,CORRELATION,BOTDATA_APPENDER,API_LOGFILE +{{- else }} +appenders = CARBON_CONSOLE,HTTP_ACCESS_CONSOLE,AUDIT_CONSOLE,TRANSACTION_CONSOLE,CORRELATION_CONSOLE,CARBON_LOGFILE,AUDIT_LOGFILE,ATOMIKOS_LOGFILE,CARBON_TRACE_LOGFILE,ERROR_LOGFILE,OPEN_TRACING,SERVICE_APPENDER,TRACE_APPENDER,osgi,CORRELATION,BOTDATA_APPENDER,API_LOGFILE +{{- end }} + +# CARBON_CONSOLE is set to be a ConsoleAppender using a PatternLayout. +appender.CARBON_CONSOLE.type = Console +appender.CARBON_CONSOLE.name = CARBON_CONSOLE +appender.CARBON_CONSOLE.layout.type = PatternLayout +appender.CARBON_CONSOLE.layout.pattern = TID: [%X{tenantId}] Tenant: [%X{tenantDomain}] [%d] [%X{Correlation-ID}] : apim-cp : %5p {%c} - %replace{%mm}{\n}{|}%xThrowable{separator(|)}%n +appender.CARBON_CONSOLE.filter.threshold.type = ThresholdFilter +appender.CARBON_CONSOLE.filter.threshold.level = DEBUG + +appender.HTTP_ACCESS_CONSOLE.type = Console +appender.HTTP_ACCESS_CONSOLE.name = HTTP_ACCESS_CONSOLE +appender.HTTP_ACCESS_CONSOLE.layout.type = PatternLayout +appender.HTTP_ACCESS_CONSOLE.layout.pattern = apim-access [%X{Correlation-ID}] %mm%n +appender.HTTP_ACCESS_CONSOLE.filter.threshold.type = ThresholdFilter +appender.HTTP_ACCESS_CONSOLE.filter.threshold.level = INFO + +# AUDIT_CONSOLE is set to be a ConsoleAppender using a PatternLayout. +appender.AUDIT_CONSOLE.type = Console +appender.AUDIT_CONSOLE.name = AUDIT_CONSOLE +appender.AUDIT_CONSOLE.layout.type = PatternLayout +appender.AUDIT_CONSOLE.layout.pattern = TID: [%X{tenantId}] Tenant: [%X{tenantDomain}] [%d] [%X{Correlation-ID}] : apim-cp-audit : %5p {%c} - %replace{%mm}{\n}{|}%xThrowable{separator(|)}%n +appender.AUDIT_CONSOLE.filter.threshold.type = ThresholdFilter +appender.AUDIT_CONSOLE.filter.threshold.level = DEBUG + +# TRANSACTION_CONSOLE is set to be a ConsoleAppender using a PatternLayout. +appender.TRANSACTION_CONSOLE.type = Console +appender.TRANSACTION_CONSOLE.name = TRANSACTION_CONSOLE +appender.TRANSACTION_CONSOLE.layout.type = PatternLayout +appender.TRANSACTION_CONSOLE.layout.pattern = TID: [%X{tenantId}] [%d] [%X{Correlation-ID}] : apim-cp-transaction : {%c} - %mm %n +appender.TRANSACTION_CONSOLE.filter.threshold.type = ThresholdFilter +appender.TRANSACTION_CONSOLE.filter.threshold.level = DEBUG + +# CORRELATION_CONSOLE is set to be a ConsoleAppender using a PatternLayout. +appender.CORRELATION_CONSOLE.type = Console +appender.CORRELATION_CONSOLE.name = CORRELATION_CONSOLE +appender.CORRELATION_CONSOLE.layout.type = PatternLayout +appender.CORRELATION_CONSOLE.layout.pattern = %d{yyyy-MM-dd HH:mm:ss,SSS}|%X{Correlation-ID} : apim-cp-correlation : |%t|%mm%n +appender.CORRELATION_CONSOLE.filter.threshold.type = ThresholdFilter +appender.CORRELATION_CONSOLE.filter.threshold.level = DEBUG + +# CARBON_LOGFILE is set to be a DailyRollingFileAppender using a PatternLayout. +appender.CARBON_LOGFILE.type = RollingFile +appender.CARBON_LOGFILE.name = CARBON_LOGFILE +appender.CARBON_LOGFILE.fileName = ${sys:carbon.home}/repository/logs/wso2carbon.log +appender.CARBON_LOGFILE.filePattern = ${sys:carbon.home}/repository/logs/wso2carbon-%d{MM-dd-yyyy}-%i.log.gz +appender.CARBON_LOGFILE.layout.type = PatternLayout +appender.CARBON_LOGFILE.layout.pattern = TID: [%tenantId] [%appName] [%d] %5p {%c} - %m%ex%n +appender.CARBON_LOGFILE.policies.type = Policies +appender.CARBON_LOGFILE.policies.time.type = TimeBasedTriggeringPolicy +appender.CARBON_LOGFILE.policies.time.interval = 1 +appender.CARBON_LOGFILE.policies.time.modulate = true +appender.CARBON_LOGFILE.policies.size.type = SizeBasedTriggeringPolicy +appender.CARBON_LOGFILE.policies.size.size=1GB +appender.CARBON_LOGFILE.strategy.type = DefaultRolloverStrategy +appender.CARBON_LOGFILE.strategy.max = 20 +appender.CARBON_LOGFILE.filter.threshold.type = ThresholdFilter +appender.CARBON_LOGFILE.filter.threshold.level = DEBUG + +appender.CARBON_LOGFILE.strategy.action.type = Delete +appender.CARBON_LOGFILE.strategy.action.basepath = ${sys:carbon.home}/repository/logs/ +appender.CARBON_LOGFILE.strategy.action.maxdepth = 1 +appender.CARBON_LOGFILE.strategy.action.condition.type = IfLastModified +appender.CARBON_LOGFILE.strategy.action.condition.age = 14D +appender.CARBON_LOGFILE.strategy.action.PathConditions.type = IfFileName +appender.CARBON_LOGFILE.strategy.action.PathConditions.glob = wso2carbon-* + +# Appender config to AUDIT_LOGFILE +appender.AUDIT_LOGFILE.type = RollingFile +appender.AUDIT_LOGFILE.name = AUDIT_LOGFILE +appender.AUDIT_LOGFILE.fileName = ${sys:carbon.home}/repository/logs/audit.log +appender.AUDIT_LOGFILE.filePattern = ${sys:carbon.home}/repository/logs/audit-%d{MM-dd-yyyy}-%i.log +appender.AUDIT_LOGFILE.layout.type = PatternLayout +appender.AUDIT_LOGFILE.layout.pattern = TID: [%tenantId] [%d] %5p {%c} - %m%ex%n +appender.AUDIT_LOGFILE.policies.type = Policies +appender.AUDIT_LOGFILE.policies.time.type = TimeBasedTriggeringPolicy +appender.AUDIT_LOGFILE.policies.time.interval = 1 +appender.AUDIT_LOGFILE.policies.time.modulate = true +appender.AUDIT_LOGFILE.policies.size.type = SizeBasedTriggeringPolicy +appender.AUDIT_LOGFILE.policies.size.size = 10MB +appender.AUDIT_LOGFILE.strategy.type = DefaultRolloverStrategy +appender.AUDIT_LOGFILE.strategy.max = 20 +appender.AUDIT_LOGFILE.filter.threshold.type = ThresholdFilter +appender.AUDIT_LOGFILE.filter.threshold.level = INFO + +# Appender config API logging +appender.API_LOGFILE.type = RollingFile +appender.API_LOGFILE.name = API_LOGFILE +appender.API_LOGFILE.fileName = ${sys:carbon.home}/repository/logs/api.log +appender.API_LOGFILE.filePattern = ${sys:carbon.home}/repository/logs/api-%d{MM-dd-yyyy}-%i.log +appender.API_LOGFILE.layout.type = PatternLayout +appender.API_LOGFILE.layout.pattern = [%d] %5p {%c} %X{apiName} - %m%ex%n +appender.API_LOGFILE.policies.type = Policies +appender.API_LOGFILE.policies.time.type = TimeBasedTriggeringPolicy +appender.API_LOGFILE.policies.time.interval = 1 +appender.API_LOGFILE.policies.time.modulate = true +appender.API_LOGFILE.policies.size.type = SizeBasedTriggeringPolicy +appender.API_LOGFILE.policies.size.size = 10MB +appender.API_LOGFILE.strategy.type = DefaultRolloverStrategy +appender.API_LOGFILE.strategy.max = 20 +appender.API_LOGFILE.filter.threshold.type = ThresholdFilter +appender.API_LOGFILE.filter.threshold.level = DEBUG + +# Appender config to send Atomikos transaction logs to new log file tm.out. +appender.ATOMIKOS_LOGFILE.type = RollingFile +appender.ATOMIKOS_LOGFILE.name = ATOMIKOS_LOGFILE +appender.ATOMIKOS_LOGFILE.fileName = ${sys:carbon.home}/repository/logs/tm.out +appender.ATOMIKOS_LOGFILE.filePattern = ${sys:carbon.home}/repository/logs/tm-%d{MM-dd-yyyy}.out +appender.ATOMIKOS_LOGFILE.layout.type = PatternLayout +appender.ATOMIKOS_LOGFILE.layout.pattern = [%d] [%tenantId] %5p {%c} - %m%ex%n +appender.ATOMIKOS_LOGFILE.policies.type = Policies +appender.ATOMIKOS_LOGFILE.policies.time.type = TimeBasedTriggeringPolicy +appender.ATOMIKOS_LOGFILE.policies.time.interval = 1 +appender.ATOMIKOS_LOGFILE.policies.time.modulate = true +appender.ATOMIKOS_LOGFILE.strategy.type = DefaultRolloverStrategy +appender.ATOMIKOS_LOGFILE.strategy.max = 20 + +# Appender config to CARBON_TRACE_LOGFILE +appender.CARBON_TRACE_LOGFILE.type = RollingFile +appender.CARBON_TRACE_LOGFILE.name = CARBON_TRACE_LOGFILE +appender.CARBON_TRACE_LOGFILE.fileName = ${sys:carbon.home}/repository/logs/wso2carbon-trace-messages.log +appender.CARBON_TRACE_LOGFILE.filePattern = ${sys:carbon.home}/repository/logs/wso2carbon-trace-messages-%d{MM-dd-yyyy}.log +appender.CARBON_TRACE_LOGFILE.layout.type = PatternLayout +appender.CARBON_TRACE_LOGFILE.layout.pattern = [%d] [%tenantId] %5p {%c} - %m%ex%n +appender.CARBON_TRACE_LOGFILE.policies.type = Policies +appender.CARBON_TRACE_LOGFILE.policies.time.type = TimeBasedTriggeringPolicy +appender.CARBON_TRACE_LOGFILE.policies.time.interval = 1 +appender.CARBON_TRACE_LOGFILE.policies.time.modulate = true +appender.CARBON_TRACE_LOGFILE.policies.size.type = SizeBasedTriggeringPolicy +appender.CARBON_TRACE_LOGFILE.policies.size.size = 10MB +appender.CARBON_TRACE_LOGFILE.strategy.type = DefaultRolloverStrategy +appender.CARBON_TRACE_LOGFILE.strategy.max = 20 + +# Appender config to put correlation Log. +appender.CORRELATION.type = RollingFile +appender.CORRELATION.name = CORRELATION +appender.CORRELATION.fileName = ${sys:carbon.home}/repository/logs/correlation.log +appender.CORRELATION.filePattern =${sys:carbon.home}/repository/logs/correlation-%d{MM-dd-yyyy}-%i.log.gz +appender.CORRELATION.layout.type = PatternLayout +appender.CORRELATION.layout.pattern = %d{yyyy-MM-dd HH:mm:ss,SSS}|%X{Correlation-ID}|%t|%m%n +appender.CORRELATION.policies.type = Policies +appender.CORRELATION.policies.time.type = TimeBasedTriggeringPolicy +appender.CORRELATION.policies.time.interval = 1 +appender.CORRELATION.policies.time.modulate = true +appender.CORRELATION.policies.size.type = SizeBasedTriggeringPolicy +appender.CORRELATION.policies.size.size = 10MB +appender.CORRELATION.strategy.type = DefaultRolloverStrategy +appender.CORRELATION.strategy.max = 20 +appender.CORRELATION.filter.threshold.type = ThresholdFilter +appender.CORRELATION.filter.threshold.level = INFO + +appender.ERROR_LOGFILE.type = RollingFile +appender.ERROR_LOGFILE.name = ERROR_LOGFILE +appender.ERROR_LOGFILE.fileName = ${sys:carbon.home}/repository/logs/wso2-apigw-errors.log +appender.ERROR_LOGFILE.filePattern = ${sys:carbon.home}/repository/logs/wso2-apigw-errors-%d{MM-dd-yyyy}-%i.log.gz +appender.ERROR_LOGFILE.layout.type = PatternLayout +appender.ERROR_LOGFILE.layout.pattern = %d{ISO8601} [%X{ip}-%X{host}] [%t] %5p %c{1} %m%n +appender.ERROR_LOGFILE.policies.type = Policies +appender.ERROR_LOGFILE.policies.time.type = TimeBasedTriggeringPolicy +appender.ERROR_LOGFILE.policies.time.interval = 1 +appender.ERROR_LOGFILE.policies.time.modulate = true +appender.ERROR_LOGFILE.policies.size.type = SizeBasedTriggeringPolicy +appender.ERROR_LOGFILE.policies.size.size = 10MB +appender.ERROR_LOGFILE.strategy.type = DefaultRolloverStrategy +appender.ERROR_LOGFILE.strategy.max = 20 +appender.ERROR_LOGFILE.filter.threshold.type = ThresholdFilter +appender.ERROR_LOGFILE.filter.threshold.level = WARN + +appender.CARBON_SYS_LOG.type = Syslog +appender.CARBON_SYS_LOG.name = CARBON_SYS_LOG +appender.CARBON_SYS_LOG.host = localhost +appender.CARBON_SYS_LOG.facility = USER +appender.CARBON_SYS_LOG.layout.type = PatternLayout +appender.CARBON_SYS_LOG.layout.pattern = [%d] %5p - %x %m {%c}%n +appender.CARBON_SYS_LOG.filter.threshold.type = ThresholdFilter +appender.CARBON_SYS_LOG.filter.threshold.level = DEBUG + +appender.OPEN_TRACING.type = RollingFile +appender.OPEN_TRACING.name = OPEN_TRACING +appender.OPEN_TRACING.fileName = ${sys:carbon.home}/repository/logs/wso2-apimgt-open-tracing.log +appender.OPEN_TRACING.filePattern = ${sys:carbon.home}/repository/logs/wso2-apimgt-open-tracing-%d{MM-dd-yyyy}-%i.log.gz +appender.OPEN_TRACING.layout.type = PatternLayout +appender.OPEN_TRACING.layout.pattern = %d{HH:mm:ss,SSS} [%X{ip}-%X{host}] [%t] %5p %m%nn +appender.OPEN_TRACING.policies.type = Policies +appender.OPEN_TRACING.policies.time.type = TimeBasedTriggeringPolicy +appender.OPEN_TRACING.policies.time.interval = 1 +appender.OPEN_TRACING.policies.time.modulate = true +appender.OPEN_TRACING.policies.size.type = SizeBasedTriggeringPolicy +appender.OPEN_TRACING.policies.size.size = 10MB +appender.OPEN_TRACING.strategy.type = DefaultRolloverStrategy +appender.OPEN_TRACING.strategy.max = 20 +appender.OPEN_TRACING.filter.threshold.type = ThresholdFilter +appender.OPEN_TRACING.filter.threshold.level = TRACE + +appender.TRACE_APPENDER.type = RollingFile +appender.TRACE_APPENDER.name = TRACE_APPENDER +appender.TRACE_APPENDER.fileName = ${sys:carbon.home}/repository/logs/wso2-apigw-trace.log +appender.TRACE_APPENDER.filePattern = ${sys:carbon.home}/repository/logs/wso2-apigw-trace-%d{MM-dd-yyyy}.log +appender.TRACE_APPENDER.layout.type = PatternLayout +appender.TRACE_APPENDER.layout.pattern = %d{HH:mm:ss,SSS} [%X{ip}-%X{host}] [%t] %5p %c{1} %m%n +appender.TRACE_APPENDER.policies.type = Policies +appender.TRACE_APPENDER.policies.time.type = TimeBasedTriggeringPolicy +appender.TRACE_APPENDER.policies.time.interval = 1 +appender.TRACE_APPENDER.policies.time.modulate = true +appender.TRACE_APPENDER.strategy.type = DefaultRolloverStrategy +appender.TRACE_APPENDER.strategy.max = 20 + +appender.SERVICE_APPENDER.type = RollingFile +appender.SERVICE_APPENDER.name = SERVICE_APPENDER +appender.SERVICE_APPENDER.fileName = ${sys:carbon.home}/repository/logs/wso2-apigw-service.log +appender.SERVICE_APPENDER.filePattern = ${sys:carbon.home}/repository/logs/wso2-apigw-service-%i.log +appender.SERVICE_APPENDER.layout.type = PatternLayout +appender.SERVICE_APPENDER.layout.pattern = %d{ISO8601} [%X{ip}-%X{host}] [%t] %5p %c{1} %m%n +appender.SERVICE_APPENDER.policies.type = Policies +appender.SERVICE_APPENDER.policies.size.type = SizeBasedTriggeringPolicy +appender.SERVICE_APPENDER.policies.size.size=1000KB +appender.SERVICE_APPENDER.strategy.type = DefaultRolloverStrategy +appender.SERVICE_APPENDER.strategy.max = 10 + +appender.osgi.type = PaxOsgi +appender.osgi.name = PaxOsgi +appender.osgi.filter = * + +{{- println }} +{{- if .Values.wso2.apim.log4j2.loggers }} +loggers = {{ .Values.wso2.apim.log4j2.loggers }}, AUDIT_LOG, trace-messages, org-apache-coyote, com-hazelcast, Owasp-CsrfGuard, org-apache-axis2-wsdl-codegen-writer-PrettyPrinter, org-apache-axis2-clustering, org-apache-catalina, org-apache-tomcat, org-wso2-carbon-apacheds, org-apache-directory-server-ldap, org-apache-directory-server-core-event, com-atomikos, org-quartz, org-apache-jackrabbit-webdav, org-apache-juddi, org-apache-commons-digester-Digester, org-apache-jasper-compiler-TldLocationsCache, org-apache-qpid, org-apache-qpid-server-Main, qpid-message, qpid-message-broker-listening, org-apache-tiles, org-apache-commons-httpclient, org-apache-solr, me-prettyprint-cassandra-hector-TimingLogger, org-apache-axis-enterprise, org-apache-directory-shared-ldap, org-apache-directory-server-ldap-handlers, org-apache-directory-shared-ldap-entry-DefaultServerAttribute, org-apache-directory-server-core-DefaultDirectoryService, org-apache-directory-shared-ldap-ldif-LdifReader, org-apache-directory-server-ldap-LdapProtocolHandler, org-apache-directory-server-core, org-apache-directory-server-ldap-LdapSession, DataNucleus, Datastore, Datastore-Schema, JPOX-Datastore, JPOX-Plugin, JPOX-MetaData, JPOX-Query, JPOX-General, JPOX-Enhancer, org-apache-hadoop-hive, hive, ExecMapper, ExecReducer, net-sf-ehcache-config-ConfigurationFactory, axis2Deployment, equinox, tomcat2, StAXDialectDetector, trace, synapse, synapse_transport, axis2, axis2_transport, org-wso2-carbon, hunsicker, thrift-publisher, service_logger, trace_logger, org-wso2-carbon-apimgt-gateway-mediators-BotDetectionMediator, wso2-callhome, correlation +{{- else }} +loggers = AUDIT_LOG, trace-messages, org-apache-coyote, com-hazelcast, Owasp-CsrfGuard, org-apache-axis2-wsdl-codegen-writer-PrettyPrinter, org-apache-axis2-clustering, org-apache-catalina, org-apache-tomcat, org-wso2-carbon-apacheds, org-apache-directory-server-ldap, org-apache-directory-server-core-event, com-atomikos, org-quartz, org-apache-jackrabbit-webdav, org-apache-juddi, org-apache-commons-digester-Digester, org-apache-jasper-compiler-TldLocationsCache, org-apache-qpid, org-apache-qpid-server-Main, qpid-message, qpid-message-broker-listening, org-apache-tiles, org-apache-commons-httpclient, org-apache-solr, me-prettyprint-cassandra-hector-TimingLogger, org-apache-axis-enterprise, org-apache-directory-shared-ldap, org-apache-directory-server-ldap-handlers, org-apache-directory-shared-ldap-entry-DefaultServerAttribute, org-apache-directory-server-core-DefaultDirectoryService, org-apache-directory-shared-ldap-ldif-LdifReader, org-apache-directory-server-ldap-LdapProtocolHandler, org-apache-directory-server-core, org-apache-directory-server-ldap-LdapSession, DataNucleus, Datastore, Datastore-Schema, JPOX-Datastore, JPOX-Plugin, JPOX-MetaData, JPOX-Query, JPOX-General, JPOX-Enhancer, org-apache-hadoop-hive, hive, ExecMapper, ExecReducer, net-sf-ehcache-config-ConfigurationFactory, axis2Deployment, equinox, tomcat2, StAXDialectDetector, trace, synapse, synapse_transport, axis2, axis2_transport, org-wso2-carbon, hunsicker, thrift-publisher, service_logger, trace_logger, org-wso2-carbon-apimgt-gateway-mediators-BotDetectionMediator, wso2-callhome, correlation +{{- end }} + +logger.API_LOG.name = API_LOG +logger.API_LOG.level = INFO +logger.API_LOG.appenderRef.API_LOGFILE.ref = API_LOGFILE +logger.API_LOG.additivity = false + +logger.AUDIT_LOG.name = AUDIT_LOG +logger.AUDIT_LOG.level = INFO +logger.AUDIT_LOG.appenderRef.AUDIT_LOGFILE.ref = AUDIT_LOGFILE +logger.AUDIT_LOG.additivity = false + +logger.AUDIT_LOG_CONSOLE.name = AUDIT_LOG_CONSOLE +logger.AUDIT_LOG_CONSOLE.level = INFO +logger.AUDIT_LOG_CONSOLE.appenderRef.AUDIT_CONSOLE.ref = AUDIT_CONSOLE +logger.AUDIT_LOG_CONSOLE.additivity = false + +logger.HTTP_ACCESS_CONSOLE.name = HTTP_ACCESS_CONSOLE +logger.HTTP_ACCESS_CONSOLE.level = INFO +logger.HTTP_ACCESS_CONSOLE.appenderRef.HTTP_ACCESS_CONSOLE.ref = HTTP_ACCESS_CONSOLE +logger.HTTP_ACCESS_CONSOLE.additivity = false + +logger.TRANSACTION_CONSOLE.name = TRANSACTION_CONSOLE +logger.TRANSACTION_CONSOLE.level = INFO +logger.TRANSACTION_CONSOLE.appenderRef.TRANSACTION_CONSOLE.ref = TRANSACTION_CONSOLE +logger.TRANSACTION_CONSOLE.additivity = false + +logger.CORRELATION_CONSOLE.name = CORRELATION_CONSOLE +logger.CORRELATION_CONSOLE.level = INFO +logger.CORRELATION_CONSOLE.appenderRef.CORRELATION_CONSOLE.ref = CORRELATION_CONSOLE +logger.CORRELATION_CONSOLE.additivity = false + +logger.trace-messages.name = trace.messages +logger.trace-messages.level = TRACE +logger.trace-messages.appenderRef.CARBON_TRACE_LOGFILE.ref = CARBON_TRACE_LOGFILE + +logger.org-apache-coyote.name = org.apache.coyote +logger.org-apache-coyote.level = WARN + +logger.com-hazelcast.name = com.hazelcast +logger.com-hazelcast.level = ERROR + +logger.Owasp-CsrfGuard.name = Owasp.CsrfGuard +logger.Owasp-CsrfGuard.level = WARN + +logger.org-apache-axis2-wsdl-codegen-writer-PrettyPrinter.name = org.apache.axis2.wsdl.codegen.writer.PrettyPrinter +logger.org-apache-axis2-wsdl-codegen-writer-PrettyPrinter.level = ERROR +logger.org-apache-axis2-wsdl-codegen-writer-PrettyPrinter.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.org-apache-axis2-clustering.name = org.apache.axis2.clustering +logger.org-apache-axis2-clustering.level = INFO +logger.org-apache-axis2-clustering.additivity = false + +logger.org-apache.name = org.apache +logger.org-apache.level = INFO +logger.org-apache.additivity = false +logger.org-apache.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.org-apache-catalina.name = org.apache.catalina +logger.org-apache-catalina.level = ERROR + +logger.org-apache-tomcat.name = org.apache.tomcat +logger.org-apache-tomcat.level = INFO + +logger.org-wso2-carbon-apacheds.name = org.wso2.carbon.apacheds +logger.org-wso2-carbon-apacheds.level = WARN + +logger.org-apache-directory-server-ldap.name = org.apache.directory.server.ldap +logger.org-apache-directory-server-ldap.level = ERROR + +logger.org-apache-directory-server-core-event.name = org.apache.directory.server.core.event +logger.org-apache-directory-server-core-event.level = WARN + +logger.com-atomikos.name = com.atomikos +logger.com-atomikos.level = INFO +logger.com-atomikos.additivity = false +logger.com-atomikos.appenderRef.ATOMIKOS_LOGFILE.ref = ATOMIKOS_LOGFILE + +logger.org-quartz.name = org.quartz +logger.org-quartz.level = WARN + +logger.org-apache-jackrabbit-webdav.name = org.apache.jackrabbit.webdav +logger.org-apache-jackrabbit-webdav.level = WARN + +logger.org-apache-juddi.name = org.apache.juddi +logger.org-apache-juddi.level = ERROR + +logger.org-apache-commons-digester-Digester.name = org.apache.commons.digester.Digester +logger.org-apache-commons-digester-Digester.level = WARN + +logger.org-apache-jasper-compiler-TldLocationsCache.name = org.apache.jasper.compiler.TldLocationsCache +logger.org-apache-jasper-compiler-TldLocationsCache.level = WARN + +logger.org-apache-qpid.name = org.apache.qpid +logger.org-apache-qpid.level = WARN + +logger.org-apache-qpid-server-Main.name = org.apache.qpid.server.Main +logger.org-apache-qpid-server-Main.level = INFO + +logger.qpid-message.name = qpid.message +logger.qpid-message.level = WARN + +logger.qpid-message-broker-listening.name = qpid.message.broker.listening +logger.qpid-message-broker-listening.level = INFO + +logger.org-apache-tiles.name = org.apache.tiles +logger.org-apache-tiles.level = WARN + +logger.org-apache-commons-httpclient.name = org.apache.commons.httpclient +logger.org-apache-commons-httpclient.level = ERROR + +logger.org-apache-solr.name = org.apache.solr +logger.org-apache-solr.level = ERROR + +logger.me-prettyprint-cassandra-hector-TimingLogger.name = me.prettyprint.cassandra.hector.TimingLogger +logger.me-prettyprint-cassandra-hector-TimingLogger.level = ERROR + +logger.org-wso2.name = org.wso2 +logger.org-wso2.level = INFO + +logger.org-wso2-carbon.name = org.wso2.carbon +logger.org-wso2-carbon.level = INFO + +logger.org-apache-axis-enterprise.name = org.apache.axis2.enterprise +logger.org-apache-axis-enterprise.level = FATAL +logger.org-apache-axis-enterprise.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.org-apache-directory-shared-ldap.name = org.apache.directory.shared.ldap +logger.org-apache-directory-shared-ldap.level = WARN +logger.org-apache-directory-shared-ldap.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.org-apache-directory-server-ldap-handlers.name = org.apache.directory.server.ldap.handlers +logger.org-apache-directory-server-ldap-handlers.level = WARN +logger.org-apache-directory-server-ldap-handlers.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +# Following are to remove false error messages from startup (IS) +logger.org-apache-directory-shared-ldap-entry-DefaultServerAttribute.name = org.apache.directory.shared.ldap.entry.DefaultServerAttribute +logger.org-apache-directory-shared-ldap-entry-DefaultServerAttribute.level = FATAL +logger.org-apache-directory-shared-ldap-entry-DefaultServerAttribute.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.org-apache-directory-server-core-DefaultDirectoryService.name = org.apache.directory.server.core.DefaultDirectoryService +logger.org-apache-directory-server-core-DefaultDirectoryService.level = ERROR +logger.org-apache-directory-server-core-DefaultDirectoryService.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.org-apache-directory-shared-ldap-ldif-LdifReader.name = org.apache.directory.shared.ldap.ldif.LdifReader +logger.org-apache-directory-shared-ldap-ldif-LdifReader.level = ERROR +logger.org-apache-directory-shared-ldap-ldif-LdifReader.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.org-apache-directory-server-ldap-LdapProtocolHandler.name = org.apache.directory.server.ldap.LdapProtocolHandler +logger.org-apache-directory-server-ldap-LdapProtocolHandler.level = ERROR +logger.org-apache-directory-server-ldap-LdapProtocolHandler.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.org-apache-directory-server-core.name = org.apache.directory.server.core +logger.org-apache-directory-server-core.level = ERROR +logger.org-apache-directory-server-core.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.org-apache-directory-server-ldap-LdapSession.name = org.apache.directory.server.ldap.LdapSession +logger.org-apache-directory-server-ldap-LdapSession.level = Error +logger.org-apache-directory-server-ldap-LdapSession.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE + +logger.correlation.name = correlation +logger.correlation.level = INFO +logger.correlation.appenderRef.CORRELATION.ref = CORRELATION +logger.correlation.additivity = false + +# Hive Related Log configurations +logger.DataNucleus.name = DataNucleus +logger.DataNucleus.level = ERROR + +logger.Datastore.name = Datastore +logger.Datastore.level = ERROR + +logger.Datastore-Schema.name = Datastore.Schema +logger.Datastore-Schema.level = ERROR + +logger.JPOX-Datastore.name = JPOX.Datastore +logger.JPOX-Datastore.level = ERROR + +logger.JPOX-Plugin.name = JPOX.Plugin +logger.JPOX-Plugin.level = ERROR + +logger.JPOX-MetaData.name = JPOX.MetaData +logger.JPOX-MetaData.level = ERROR + +logger.JPOX-Query.name = JPOX.Query +logger.JPOX-Query.level = ERROR + +logger.JPOX-General.name = JPOX.General +logger.JPOX-General.level = ERROR + +logger.JPOX-Enhancer.name = JPOX.Enhancer +logger.JPOX-Enhancer.level = ERROR + +logger.org-apache-hadoop-hive.name = org.apache.hadoop.hive +logger.org-apache-hadoop-hive.level = WARN + +logger.hive.name = hive +logger.hive.level = WARN + +logger.ExecMapper.name = ExecMapper +logger.ExecMapper.level = WARN + +logger.ExecReducer.name = ExecReducer +logger.ExecReducer.level = WARN + +logger.net-sf-ehcache-config-ConfigurationFactory.name = net.sf.ehcache.config.ConfigurationFactory +logger.net-sf-ehcache-config-ConfigurationFactory.level = ERROR + +logger.axis2Deployment.name = org.apache.axis2.deployment +logger.axis2Deployment.level = WARN + +logger.equinox.name = org.eclipse.equinox +logger.equinox.level = FATAL + +logger.tomcat2.name = tomcat +logger.tomcat2.level = FATAL + +logger.StAXDialectDetector.name = org.apache.axiom.util.stax.dialect.StAXDialectDetector +logger.StAXDialectDetector.level = ERROR + +logger.trace.name = tracer +logger.trace.level = TRACE +logger.trace.appenderRef.OPEN_TRACING.ref = OPEN_TRACING + +logger.synapse.name = org.apache.synapse +logger.synapse.level = INFO + +logger.synapse_transport.name = org.apache.synapse.transport +logger.synapse_transport.level = INFO + +logger.axis2.name = org.apache.axis2 +logger.axis2.level = INFO + +logger.axis2_transport.name = org.apache.axis2.transport +logger.axis2_transport.level = INFO + +logger.hunsicker.name = de.hunsicker.jalopy.io +logger.hunsicker.level = FATAL + +logger.synapse-headers.name = org.apache.synapse.transport.http.headers +logger.synapse-headers.level = DEBUG + +logger.synapse-wire.name = org.apache.synapse.transport.http.wire +logger.synapse-wire.level = DEBUG + +logger.thrift-publisher.name = org.wso2.carbon.databridge.agent.thrift.AsyncDataPublisher +logger.thrift-publisher.level = WARN + +logger.service_logger.name = SERVICE_LOGGER +logger.service_logger.level = INFO +logger.service_logger.additivity = false +logger.service_logger.appenderRef.SERVICE_APPENDER.ref = SERVICE_APPENDER + +logger.wso2-callhome.name = org.wso2.callhome +logger.wso2-callhome.level = INFO + +logger.trace_logger.name = TRACE_LOGGER +logger.trace_logger.level = INFO +logger.trace_logger.appenderRef.TRACE_APPENDER.ref = TRACE_APPENDER + +# root loggers +rootLogger.level = ERROR +rootLogger.appenderRef.CARBON_CONSOLE.ref = CARBON_CONSOLE +rootLogger.appenderRef.CARBON_LOGFILE.ref = CARBON_LOGFILE +rootLogger.appenderRef.ERROR_LOGFILE.ref = ERROR_LOGFILE +rootLogger.appenderRef.PaxOsgi.ref = PaxOsgi +#rootLogger.appenderReg.CARBON_SYS_LOG.ref = CARBON_SYS_LOG +#rootLogger.appenderRef.syslog.ref = syslog + +# bot detection feature appender +appender.BOTDATA_APPENDER.type = RollingFile +appender.BOTDATA_APPENDER.name = BOTDATA_APPENDER +appender.BOTDATA_APPENDER.fileName = ${sys:carbon.home}/repository/logs/wso2-BotDetectedData.log +appender.BOTDATA_APPENDER.filePattern = ${sys:carbon.home}/repository/logs/wso2-BotDetectedData-%d{MM-dd-yyyy}.log +appender.BOTDATA_APPENDER.layout.type = PatternLayout +appender.BOTDATA_APPENDER.layout.pattern = [%d] [%tenantId] %5p {%c} - %m%ex%n +appender.BOTDATA_APPENDER.policies.type = Policies +appender.BOTDATA_APPENDER.policies.time.type = TimeBasedTriggeringPolicy +appender.BOTDATA_APPENDER.policies.time.interval = 1 +appender.BOTDATA_APPENDER.policies.time.modulate = true +appender.BOTDATA_APPENDER.policies.size.type = SizeBasedTriggeringPolicy +appender.BOTDATA_APPENDER.policies.size.size = 10MB +appender.BOTDATA_APPENDER.strategy.type = DefaultRolloverStrategy +appender.BOTDATA_APPENDER.strategy.max = 20 + +logger.org-wso2-carbon-apimgt-gateway-mediators-BotDetectionMediator.name = org.wso2.carbon.apimgt.gateway.mediators.BotDetectionMediator +logger.org-wso2-carbon-apimgt-gateway-mediators-BotDetectionMediator.level = INFO +logger.org-wso2-carbon-apimgt-gateway-mediators-BotDetectionMediator.appenderRef.BOTDATA_APPENDER.ref = BOTDATA_APPENDER +logger.org-wso2-carbon-apimgt-gateway-mediators-BotDetectionMediator.additivity = false + +category.SERVICE_APPENDER._OpenService_ = TRACE_APPENDER, BOTDATA_APPENDER diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/confs/secret-conf.properties b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/secret-conf.properties new file mode 100644 index 000000000..645e5539b --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/confs/secret-conf.properties @@ -0,0 +1,12 @@ +keystore.identity.location=/home/wso2carbon/wso2am-{{ .Values.wso2.apim.version }}/repository/resources/security/{{ .Values.wso2.apim.configurations.security.keystores.internal.name }} +keystore.identity.type=JKS +keystore.identity.store.password=identity.store.password +keystore.identity.store.secretProvider=org.wso2.carbon.securevault.DefaultSecretCallbackHandler +secretRepositories.file.provider=org.wso2.securevault.secret.repository.FileBaseSecretRepositoryProvider +secretRepositories.file.location=repository/conf/security/cipher-text.properties +secretRepositories=file +secVault.enabled=true +keystore.identity.key.password=identity.key.password +carbon.secretProvider=org.wso2.securevault.secret.handler.SecretManagerSecretCallbackHandler +keystore.identity.key.secretProvider=org.wso2.carbon.securevault.DefaultSecretCallbackHandler +keystore.identity.alias={{ .Values.wso2.apim.configurations.security.keystores.internal.alias }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/_helpers.tpl b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/_helpers.tpl new file mode 100644 index 000000000..704ae2467 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/_helpers.tpl @@ -0,0 +1,69 @@ +{{/* +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# --------------------------------------------------------------------------------------s +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "apim-helm-cp.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "apim-helm-cp.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "apim-helm-cp.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "apim-helm-cp.labels" -}} +app.kubernetes.io/name: {{ include "apim-helm-cp.name" . }} +helm.sh/chart: {{ include "apim-helm-cp.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Common prefix prepended to Kubernetes resources of this chart +*/}} +{{- define "apim-helm-cp.resource.prefix" -}} +{{- if eq .Values.kubernetes.resourceSuffix "${RESOURCE_SUFFIX}" }} +{{- "wso2am-cp" }} +{{- else }} +{{- "wso2am-cp-" }}{{ .Values.kubernetes.resourceSuffix }} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-1/wso2am-cp-conf.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-1/wso2am-cp-conf.yaml new file mode 100644 index 000000000..76fbcebb4 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-1/wso2am-cp-conf.yaml @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-conf-1 + namespace : {{ .Release.Namespace }} +data: + deployment.toml: {{ tpl (.Files.Get "confs/instance-1/deployment.toml") . | quote }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-1/wso2am-cp-deployment.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-1/wso2am-cp-deployment.yaml new file mode 100644 index 000000000..50674373c --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-1/wso2am-cp-deployment.yaml @@ -0,0 +1,233 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-deployment-1 + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.wso2.deployment.replicas }} + strategy: + type: Recreate + selector: + matchLabels: + deployment: {{ template "apim-helm-cp.fullname" . }} + node: {{ template "apim-helm-cp.fullname" . }}-1 + template: + metadata: + annotations: + {{- if .Values.kubernetes.enableAppArmor }} + container.apparmor.security.beta.kubernetes.io/wso2am-control-plane: runtime/default + {{- end }} + checksum.am.cp.conf: {{ include (print $.Template.BasePath "/control-plane/instance-1/wso2am-cp-conf.yaml") . | sha256sum }} + checksum.am.cp.conf.log4j2: {{ include (print $.Template.BasePath "/control-plane/wso2am-cp-conf-log4j2.yaml") . | sha256sum }} + checksum.am.cp.conf.secret: {{ include (print $.Template.BasePath "/control-plane/wso2am-cp-conf-secret-conf.yaml") . | sha256sum }} + labels: + deployment: {{ template "apim-helm-cp.fullname" . }} + node: {{ template "apim-helm-cp.fullname" . }}-1 + product: apim + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: deployment + operator: In + values: + - {{ template "apim-helm-cp.fullname" . }} + topologyKey: "topology.kubernetes.io/zone" + weight: 100 + {{- if .Values.wso2.apim.secureVaultEnabled }} + {{- if .Values.aws.enabled }} + serviceAccount: {{ .Values.aws.serviceAccountName }} + {{- else if .Values.gcp.enabled }} + serviceAccount: {{ .Values.gcp.serviceAccountName }} + {{- else if .Values.azure.enabled }} + serviceAccount: {{ .Values.azure.serviceAccountName }} + {{- end }} + {{- end }} + securityContext: + seccompProfile: + type: RuntimeDefault + containers: + - name: wso2am-control-plane + image: sampathrajapakse/wso2am:4.3.0 + imagePullPolicy: {{ .Values.wso2.deployment.imagePullPolicy }} + env: + - name: PROFILE_NAME + value: control-plane + - name: NODE_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: JVM_MEM_OPTS + value: "-Xms{{ .Values.wso2.deployment.resources.jvm.memory.xms }} -Xmx{{ .Values.wso2.deployment.resources.jvm.memory.xmx }}" + startupProbe: + exec: + command: + - /bin/sh + - -c + - nc -z localhost {{ add 9443 .Values.wso2.apim.portOffset }} + initialDelaySeconds: {{ .Values.wso2.deployment.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.wso2.deployment.startupProbe.periodSeconds }} + failureThreshold: {{ .Values.wso2.deployment.startupProbe.failureThreshold }} + livenessProbe: + httpGet: + path: /services/Version + port: {{ add 9763 .Values.wso2.apim.portOffset }} + initialDelaySeconds: {{ .Values.wso2.deployment.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.wso2.deployment.livenessProbe.periodSeconds }} + failureThreshold: {{ .Values.wso2.deployment.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /services/Version + port: {{ add 9763 .Values.wso2.apim.portOffset }} + initialDelaySeconds: {{ .Values.wso2.deployment.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.wso2.deployment.readinessProbe.periodSeconds }} + failureThreshold: {{ .Values.wso2.deployment.readinessProbe.failureThreshold }} + lifecycle: + preStop: + exec: + command: + - "sh" + - "-c" + - > + echo "Pre stop hook triggered"; + sleep {{ .Values.wso2.deployment.lifecycle.preStopHook.sleepSeconds }}; + echo "Shutdown APIM Server"; + ${WSO2_SERVER_HOME}/bin/api-manager.sh stop + resources: + requests: + memory: {{ .Values.wso2.deployment.resources.requests.memory }} + cpu: {{ .Values.wso2.deployment.resources.requests.cpu }} + limits: + memory: {{ .Values.wso2.deployment.resources.limits.memory }} + cpu: {{ .Values.wso2.deployment.resources.limits.cpu }} + securityContext: + runAsUser: {{ .Values.kubernetes.securityContext.runAsUser }} + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - all + ports: + - containerPort: {{ add 9763 .Values.wso2.apim.portOffset }} + protocol: "TCP" + - containerPort: {{ add 9443 .Values.wso2.apim.portOffset }} + protocol: "TCP" + - containerPort: {{ add 9711 .Values.wso2.apim.portOffset }} + protocol: "TCP" + - containerPort: {{ add 9611 .Values.wso2.apim.portOffset }} + protocol: "TCP" + - containerPort: {{ add 5672 .Values.wso2.apim.portOffset }} + protocol: "TCP" + volumeMounts: + - name: wso2am-control-plane-conf + mountPath: /home/wso2carbon/wso2-config-volume/repository/conf/deployment.toml + subPath: deployment.toml + - name: wso2am-control-plane-entrypoint + mountPath: /home/wso2carbon/docker-entrypoint.sh + subPath: docker-entrypoint.sh + - name: wso2am-control-plane-log4j2 + mountPath: /home/wso2carbon/wso2-config-volume/repository/conf/log4j2.properties + subPath: log4j2.properties + - name: wso2am-sh-conf + mountPath: /home/wso2carbon/wso2-config-volume/bin/api-manager.sh + subPath: api-manager.sh + {{- if .Values.wso2.apim.secureVaultEnabled }} + - name: wso2am-control-plane-secret-conf + mountPath: /home/wso2carbon/wso2-config-volume/repository/conf/security/secret-conf.properties + subPath: secret-conf.properties + - name: wso2am-control-plane-secret-store-csi + mountPath: /mnt/secrets-store + readOnly: true + {{- end }} +# - name: wso2am-control-plane-keystores +# mountPath: /home/wso2carbon/wso2-config-volume/repository/resources/security/{{ .Values.wso2.apim.configurations.security.truststore.name }} +# subPath: {{ .Values.wso2.apim.configurations.security.truststore.name }} +# {{- if .Values.wso2.apim.configurations.security.keystores.primary.enabled }} +# - name: wso2am-control-plane-keystores +# mountPath: /home/wso2carbon/wso2-config-volume/repository/resources/security/{{ .Values.wso2.apim.configurations.security.keystores.primary.name }} +# subPath: {{ .Values.wso2.apim.configurations.security.keystores.primary.name }} +# {{- end }} +# {{- if .Values.wso2.apim.configurations.security.keystores.tls.enabled }} +# - name: wso2am-control-plane-keystores +# mountPath: /home/wso2carbon/wso2-config-volume/repository/resources/security/{{ .Values.wso2.apim.configurations.security.keystores.tls.name }} +# subPath: {{ .Values.wso2.apim.configurations.security.keystores.tls.name }} +# {{- end }} +# {{- if .Values.wso2.apim.configurations.security.keystores.internal.enabled }} +# - name: wso2am-control-plane-keystores +# mountPath: /home/wso2carbon/wso2-config-volume/repository/resources/security/{{ .Values.wso2.apim.configurations.security.keystores.internal.name }} +# subPath: {{ .Values.wso2.apim.configurations.security.keystores.internal.name }} +# {{- end }} + {{ if .Values.wso2.deployment.persistence.solrIndexing.enabled }} + - name: wso2am-control-plane-local-carbondb + mountPath: /home/wso2carbon/solr/database + - name: wso2am-control-plane-solr + mountPath: /home/wso2carbon/solr/indexed-data + {{ end }} + {{- if .Values.wso2.deployment.nodeSelector }} + nodeSelector: + {{- toYaml .Values.wso2.deployment.nodeSelector | nindent 8 }} + {{- end }} + volumes: + - name: wso2am-control-plane-conf + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-1 + defaultMode: 0407 + - name: wso2am-control-plane-entrypoint + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-entrypoint + defaultMode: 0407 + - name: wso2am-control-plane-log4j2 + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-log4j2 + defaultMode: 0407 + - name: wso2am-sh-conf + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-sh + defaultMode: 0407 + {{- if .Values.wso2.apim.secureVaultEnabled }} + - name: wso2am-control-plane-secret-conf + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-secret-conf + - name: wso2am-control-plane-secret-store-csi + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + {{- if .Values.azure.enabled }} + volumeAttributes: + secretProviderClass: {{ .Values.azure.keyVault.secretProviderClass }} + nodePublishSecretRef: + name: {{ .Values.azure.keyVault.activeDirectory.servicePrincipal.credentialsSecretName }} + {{- else if .Values.aws.enabled }} + volumeAttributes: + secretProviderClass: {{ .Values.aws.secretsManager.secretProviderClass }} + {{- else if .Values.gcp.enabled }} + volumeAttributes: + secretProviderClass: {{ .Values.gcp.secretsManager.secretProviderClass }} + {{- end }} + {{- end }} +# - name: wso2am-control-plane-keystores +# secret: +# secretName: {{ .Values.wso2.apim.configurations.security.jksSecretName }} + {{ if .Values.wso2.deployment.persistence.solrIndexing.enabled }} + - name: wso2am-control-plane-local-carbondb + persistentVolumeClaim: + claimName: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-1 + - name: wso2am-control-plane-solr + persistentVolumeClaim: + claimName: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-1 + {{ end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-1/wso2am-cp-service.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-1/wso2am-cp-service.yaml new file mode 100644 index 000000000..f35478553 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-1/wso2am-cp-service.yaml @@ -0,0 +1,35 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: Service +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-1-service + namespace : {{ .Release.Namespace }} +spec: + # label keys and values that must match in order to receive traffic for this service + selector: + deployment: {{ template "apim-helm-cp.fullname" . }} + node: {{ template "apim-helm-cp.fullname" . }}-1 + ports: + # ports that this service should serve on + - name: binary + protocol: TCP + port: {{ add 9611 .Values.wso2.apim.portOffset }} + - name: binary-secure + protocol: TCP + port: {{ add 9711 .Values.wso2.apim.portOffset }} + - name: jms-tcp + protocol: TCP + port: {{ add 5672 .Values.wso2.apim.portOffset }} + - name: servlet-https + protocol: TCP + port: {{ add 9443 .Values.wso2.apim.portOffset }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-2/wso2am-cp-conf.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-2/wso2am-cp-conf.yaml new file mode 100644 index 000000000..368f29442 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-2/wso2am-cp-conf.yaml @@ -0,0 +1,20 @@ +{{- if .Values.wso2.deployment.highAvailability}} +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-conf-2 + namespace : {{ .Release.Namespace }} +data: + deployment.toml: {{ tpl (.Files.Get "confs/instance-2/deployment.toml") . | quote }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-2/wso2am-cp-deployment.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-2/wso2am-cp-deployment.yaml new file mode 100644 index 000000000..a3a3de888 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-2/wso2am-cp-deployment.yaml @@ -0,0 +1,235 @@ +{{- if .Values.wso2.deployment.highAvailability}} +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-deployment-2 + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.wso2.deployment.replicas }} + strategy: + type: Recreate + selector: + matchLabels: + deployment: {{ template "apim-helm-cp.fullname" . }} + node: {{ template "apim-helm-cp.fullname" . }}-2 + template: + metadata: + annotations: + {{- if .Values.kubernetes.enableAppArmor }} + container.apparmor.security.beta.kubernetes.io/wso2am-control-plane: runtime/default + {{- end }} + checksum.am.cp.conf: {{ include (print $.Template.BasePath "/control-plane/instance-2/wso2am-cp-conf.yaml") . | sha256sum }} + checksum.am.cp.conf.log4j2: {{ include (print $.Template.BasePath "/control-plane/wso2am-cp-conf-log4j2.yaml") . | sha256sum }} + checksum.am.cp.conf.secret: {{ include (print $.Template.BasePath "/control-plane/wso2am-cp-conf-secret-conf.yaml") . | sha256sum }} + labels: + deployment: {{ template "apim-helm-cp.fullname" . }} + node: {{ template "apim-helm-cp.fullname" . }}-2 + product: apim + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: deployment + operator: In + values: + - {{ template "apim-helm-cp.fullname" . }} + topologyKey: "topology.kubernetes.io/zone" + weight: 100 + {{- if .Values.wso2.apim.secureVaultEnabled }} + {{- if .Values.aws.enabled }} + serviceAccount: {{ .Values.aws.serviceAccountName }} + {{- else if .Values.gcp.enabled }} + serviceAccount: {{ .Values.gcp.serviceAccountName }} + {{- else if .Values.azure.enabled }} + serviceAccount: {{ .Values.azure.serviceAccountName }} + {{- end }} + {{- end }} + securityContext: + seccompProfile: + type: RuntimeDefault + containers: + - name: wso2am-control-plane + image: {{ .Values.wso2.deployment.image.registry }}/{{ .Values.wso2.deployment.image.repository }}@{{ .Values.wso2.deployment.image.digest }} + imagePullPolicy: {{ .Values.wso2.deployment.imagePullPolicy }} + env: + - name: PROFILE_NAME + value: control-plane + - name: NODE_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: JVM_MEM_OPTS + value: "-Xms{{ .Values.wso2.deployment.resources.jvm.memory.xms }} -Xmx{{ .Values.wso2.deployment.resources.jvm.memory.xmx }}" + startupProbe: + exec: + command: + - /bin/sh + - -c + - nc -z localhost {{ add 9443 .Values.wso2.apim.portOffset }} + initialDelaySeconds: {{ .Values.wso2.deployment.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.wso2.deployment.startupProbe.periodSeconds }} + failureThreshold: {{ .Values.wso2.deployment.startupProbe.failureThreshold }} + livenessProbe: + httpGet: + path: /services/Version + port: {{ add 9763 .Values.wso2.apim.portOffset }} + initialDelaySeconds: {{ .Values.wso2.deployment.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.wso2.deployment.livenessProbe.periodSeconds }} + failureThreshold: {{ .Values.wso2.deployment.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /services/Version + port: {{ add 9763 .Values.wso2.apim.portOffset }} + initialDelaySeconds: {{ .Values.wso2.deployment.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.wso2.deployment.readinessProbe.periodSeconds }} + failureThreshold: {{ .Values.wso2.deployment.readinessProbe.failureThreshold }} + lifecycle: + preStop: + exec: + command: + - "sh" + - "-c" + - > + echo "Pre stop hook triggered"; + sleep {{ .Values.wso2.deployment.lifecycle.preStopHook.sleepSeconds }}; + echo "Shutdown APIM Server"; + ${WSO2_SERVER_HOME}/bin/api-manager.sh stop + resources: + requests: + memory: {{ .Values.wso2.deployment.resources.requests.memory }} + cpu: {{ .Values.wso2.deployment.resources.requests.cpu }} + limits: + memory: {{ .Values.wso2.deployment.resources.limits.memory }} + cpu: {{ .Values.wso2.deployment.resources.limits.cpu }} + securityContext: + runAsUser: {{ .Values.kubernetes.securityContext.runAsUser }} + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - all + ports: + - containerPort: {{ add 9763 .Values.wso2.apim.portOffset }} + protocol: "TCP" + - containerPort: {{ add 9443 .Values.wso2.apim.portOffset }} + protocol: "TCP" + - containerPort: {{ add 9711 .Values.wso2.apim.portOffset }} + protocol: "TCP" + - containerPort: {{ add 9611 .Values.wso2.apim.portOffset }} + protocol: "TCP" + - containerPort: {{ add 5672 .Values.wso2.apim.portOffset }} + protocol: "TCP" + volumeMounts: + - name: wso2am-control-plane-conf + mountPath: /home/wso2carbon/wso2-config-volume/repository/conf/deployment.toml + subPath: deployment.toml + - name: wso2am-control-plane-entrypoint + mountPath: /home/wso2carbon/docker-entrypoint.sh + subPath: docker-entrypoint.sh + - name: wso2am-control-plane-log4j2 + mountPath: /home/wso2carbon/wso2-config-volume/repository/conf/log4j2.properties + subPath: log4j2.properties + - name: wso2am-sh-conf + mountPath: /home/wso2carbon/wso2-config-volume/bin/api-manager.sh + subPath: api-manager.sh + {{- if .Values.wso2.apim.secureVaultEnabled }} + - name: wso2am-control-plane-secret-conf + mountPath: /home/wso2carbon/wso2-config-volume/repository/conf/security/secret-conf.properties + subPath: secret-conf.properties + - name: wso2am-control-plane-secret-store-csi + mountPath: /mnt/secrets-store + readOnly: true + {{- end }} + - name: wso2am-control-plane-keystores + mountPath: /home/wso2carbon/wso2-config-volume/repository/resources/security/{{ .Values.wso2.apim.configurations.security.truststore.name }} + subPath: {{ .Values.wso2.apim.configurations.security.truststore.name }} + {{- if .Values.wso2.apim.configurations.security.keystores.primary.enabled }} + - name: wso2am-control-plane-keystores + mountPath: /home/wso2carbon/wso2-config-volume/repository/resources/security/{{ .Values.wso2.apim.configurations.security.keystores.primary.name }} + subPath: {{ .Values.wso2.apim.configurations.security.keystores.primary.name }} + {{- end }} + {{- if .Values.wso2.apim.configurations.security.keystores.tls.enabled }} + - name: wso2am-control-plane-keystores + mountPath: /home/wso2carbon/wso2-config-volume/repository/resources/security/{{ .Values.wso2.apim.configurations.security.keystores.tls.name }} + subPath: {{ .Values.wso2.apim.configurations.security.keystores.tls.name }} + {{- end }} + {{- if .Values.wso2.apim.configurations.security.keystores.internal.enabled }} + - name: wso2am-control-plane-keystores + mountPath: /home/wso2carbon/wso2-config-volume/repository/resources/security/{{ .Values.wso2.apim.configurations.security.keystores.internal.name }} + subPath: {{ .Values.wso2.apim.configurations.security.keystores.internal.name }} + {{- end }} + {{ if .Values.wso2.deployment.persistence.solrIndexing.enabled }} + - name: wso2am-control-plane-local-carbondb + mountPath: /home/wso2carbon/solr/database + - name: wso2am-control-plane-solr + mountPath: /home/wso2carbon/solr/indexed-data + {{ end }} + {{- if .Values.wso2.deployment.nodeSelector }} + nodeSelector: + {{- toYaml .Values.wso2.deployment.nodeSelector | nindent 8 }} + {{- end }} + volumes: + - name: wso2am-control-plane-conf + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-2 + defaultMode: 0407 + - name: wso2am-control-plane-entrypoint + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-entrypoint + defaultMode: 0407 + - name: wso2am-control-plane-log4j2 + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-log4j2 + defaultMode: 0407 + - name: wso2am-sh-conf + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-sh + defaultMode: 0407 + {{- if .Values.wso2.apim.secureVaultEnabled }} + - name: wso2am-control-plane-secret-conf + configMap: + name: {{ template "apim-helm-cp.fullname" . }}-conf-secret-conf + - name: wso2am-control-plane-secret-store-csi + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + {{- if .Values.azure.enabled }} + volumeAttributes: + secretProviderClass: {{ .Values.azure.keyVault.secretProviderClass }} + nodePublishSecretRef: + name: {{ .Values.azure.keyVault.activeDirectory.servicePrincipal.credentialsSecretName }} + {{- else if .Values.aws.enabled }} + volumeAttributes: + secretProviderClass: {{ .Values.aws.secretsManager.secretProviderClass }} + {{- else if .Values.gcp.enabled }} + volumeAttributes: + secretProviderClass: {{ .Values.gcp.secretsManager.secretProviderClass }} + {{- end }} + {{- end }} + - name: wso2am-control-plane-keystores + secret: + secretName: {{ .Values.wso2.apim.configurations.security.jksSecretName }} + {{ if .Values.wso2.deployment.persistence.solrIndexing.enabled }} + - name: wso2am-control-plane-local-carbondb + persistentVolumeClaim: + claimName: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-2 + - name: wso2am-control-plane-solr + persistentVolumeClaim: + claimName: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-2 + {{ end }} +{{- end }} \ No newline at end of file diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-2/wso2am-cp-service.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-2/wso2am-cp-service.yaml new file mode 100644 index 000000000..8a9e8e3a5 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/instance-2/wso2am-cp-service.yaml @@ -0,0 +1,37 @@ +{{- if .Values.wso2.deployment.highAvailability}} +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: Service +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-2-service + namespace : {{ .Release.Namespace }} +spec: + # label keys and values that must match in order to receive traffic for this service + selector: + deployment: {{ template "apim-helm-cp.fullname" . }} + node: {{ template "apim-helm-cp.fullname" . }}-2 + ports: + # ports that this service should serve on + - name: binary + protocol: TCP + port: {{ add 9611 .Values.wso2.apim.portOffset }} + - name: binary-secure + protocol: TCP + port: {{ add 9711 .Values.wso2.apim.portOffset }} + - name: jms-tcp + protocol: TCP + port: {{ add 5672 .Values.wso2.apim.portOffset }} + - name: servlet-https + protocol: TCP + port: {{ add 9443 .Values.wso2.apim.portOffset }} +{{- end }} \ No newline at end of file diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-conf-script.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-conf-script.yaml new file mode 100644 index 000000000..3c6ea7125 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-conf-script.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-conf-sh + namespace : {{ .Release.Namespace }} +data: + api-manager.sh: {{ tpl (.Files.Get "confs/api-manager.sh") . | quote}} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-conf-entrypoint.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-conf-entrypoint.yaml new file mode 100644 index 000000000..e40243972 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-conf-entrypoint.yaml @@ -0,0 +1,71 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-conf-entrypoint + namespace: {{ .Release.Namespace }} +data: + docker-entrypoint.sh: | + #!/bin/bash + set -e + + # volume mounts + config_volume=${WORKING_DIRECTORY}/wso2-config-volume + artifact_volume=${WORKING_DIRECTORY}/wso2-artifact-volume + + # check if the WSO2 non-root user home exists + test ! -d ${WORKING_DIRECTORY} && echo "WSO2 Docker non-root user home does not exist" && exit 1 + + # check if the WSO2 product home exists + test ! -d ${WSO2_SERVER_HOME} && echo "WSO2 Docker product home does not exist" && exit 1 + + # Copying carbon_db + if ! test -f /home/wso2carbon/solr/database/WSO2CARBON_DB.mv.db + then + echo "Copying WSO2CARBON_DB.mv.db" >&2 + cp ${WSO2_SERVER_HOME}/repository/database/WSO2CARBON_DB.mv.db /home/wso2carbon/solr/database/ + fi + + # optimize WSO2 Carbon Server, if the profile name is defined as an environment variable + if [[ ! -z "${PROFILE_NAME}" ]] + then + echo "Optimizing WSO2 Carbon Server" >&2 + sh ${WSO2_SERVER_HOME}/bin/profileSetup.sh -Dprofile=${PROFILE_NAME} + fi + + # copy any configuration changes mounted to config_volume + test -d ${config_volume} && [[ "$(ls -A ${config_volume})" ]] && cp -RL ${config_volume}/* ${WSO2_SERVER_HOME}/ + # copy any artifact changes mounted to artifact_volume + test -d ${artifact_volume} && [[ "$(ls -A ${artifact_volume})" ]] && cp -RL ${artifact_volume}/* ${WSO2_SERVER_HOME}/ + + {{- if .Values.wso2.apim.secureVaultEnabled }} + # copy internal keystore credentials to password-tmp file for cipher-tool usage + {{- if .Values.azure.enabled }} + cp /mnt/secrets-store/{{ .Values.azure.keyVault.secretIdentifiers.internalKeystorePassword }} ${WSO2_SERVER_HOME}/password-tmp + {{- else if .Values.aws.enabled }} + cp /mnt/secrets-store/{{ .Values.aws.secretsManager.secretIdentifiers.internalKeystorePassword.secretKey }} ${WSO2_SERVER_HOME}/password-tmp + {{- else if .Values.gcp.enabled }} + cp /mnt/secrets-store/{{ .Values.gcp.secretsManager.secret.secretName }} ${WSO2_SERVER_HOME}/password-tmp + {{- end }} + {{- end }} + + # start WSO2 Carbon server + echo "Start WSO2 Carbon server" >&2 + if [[ -z "${PROFILE_NAME}" ]] + then + # start the server with the provided startup arguments + sh ${WSO2_SERVER_HOME}/bin/api-manager.sh "$@" {{ .Values.wso2.apim.startupArgs }} + else + # start the server with the specified profile and provided startup arguments + sh ${WSO2_SERVER_HOME}/bin/api-manager.sh -Dprofile=${PROFILE_NAME} "$@" {{ .Values.wso2.apim.startupArgs }} + fi diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-conf-log4j2.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-conf-log4j2.yaml new file mode 100644 index 000000000..c86cd0433 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-conf-log4j2.yaml @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-conf-log4j2 + namespace : {{ .Release.Namespace }} +data: + log4j2.properties: {{ tpl (.Files.Get "confs/log4j2.properties") . | quote }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-conf-secret-conf.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-conf-secret-conf.yaml new file mode 100644 index 000000000..10e9fffdb --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-conf-secret-conf.yaml @@ -0,0 +1,19 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- +{{- if .Values.wso2.apim.secureVaultEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-conf-secret-conf + namespace : {{ .Release.Namespace }} +data: + secret-conf.properties: {{ tpl (.Files.Get "confs/secret-conf.properties") . | quote}} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-ingress.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-ingress.yaml new file mode 100644 index 000000000..6e60304d4 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-ingress.yaml @@ -0,0 +1,47 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-ingress + namespace : {{ .Release.Namespace }} +{{- if .Values.kubernetes.ingress.controlPlane.annotations }} + annotations: +{{ toYaml .Values.kubernetes.ingress.controlPlane.annotations | indent 4 }} + {{- if .Values.kubernetes.ingress.ratelimit.enabled }} + nginx.ingress.kubernetes.io/configuration-snippet: | + limit_req zone={{ .Values.kubernetes.ingress.ratelimit.zoneName }} burst={{ .Values.kubernetes.ingress.ratelimit.burstLimit }} nodelay; + limit_req_status 429; + set $rangeheadervalue $http_range; + if ($http_accept_encoding = "gzip") { + set $rangeheadervalue ""; + } + proxy_set_header Range $rangeheadervalue; + {{- end }} +{{- end }} +spec: + ingressClassName: {{ .Values.kubernetes.ingressClass }} + tls: + - hosts: + - {{ .Values.kubernetes.ingress.controlPlane.hostname }} + secretName: {{ .Values.kubernetes.ingress.tlsSecret }} + rules: + - host: {{ .Values.kubernetes.ingress.controlPlane.hostname }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ template "apim-helm-cp.fullname" . }}-service + port: + number: {{ add 9443 .Values.wso2.apim.portOffset }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-pdb.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-pdb.yaml new file mode 100644 index 000000000..8f4e9613e --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-pdb.yaml @@ -0,0 +1,20 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-pdb +spec: + minAvailable: {{ .Values.wso2.deployment.minAvailable | quote }} + selector: + matchLabels: + deployment: {{ template "apim-helm-cp.fullname" . }}-deployment diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-secret-store-provider-gcp.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-secret-store-provider-gcp.yaml new file mode 100644 index 000000000..27fa49ecb --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-secret-store-provider-gcp.yaml @@ -0,0 +1,24 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +{{- if and .Values.wso2.apim.secureVaultEnabled .Values.gcp.enabled }} +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: {{ .Values.gcp.secretsManager.secretProviderClass }} + namespace: {{ .Release.Namespace }} +spec: + provider: gcp + parameters: + secrets: | + - resourceName: "projects/{{ .Values.gcp.secretsManager.projectId }}/secrets/{{ .Values.gcp.secretsManager.secret.secretName }}/versions/{{ .Values.gcp.secretsManager.secret.secretVersion }}" + path: {{ .Values.gcp.secretsManager.secret.secretName }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-service.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-service.yaml new file mode 100644 index 000000000..6a6bb2637 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-service.yaml @@ -0,0 +1,28 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: Service +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-service + namespace : {{ .Release.Namespace }} +spec: + # label keys and values that must match in order to receive traffic for this service + selector: + deployment: {{ template "apim-helm-cp.fullname" . }} + ports: + # ports that this service should serve on + - name: servlet-http + protocol: TCP + port: {{ add 9763 .Values.wso2.apim.portOffset }} + - name: servlet-https + protocol: TCP + port: {{ add 9443 .Values.wso2.apim.portOffset }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-storageclass-aws.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-storageclass-aws.yaml new file mode 100644 index 000000000..d70d2bc32 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-storageclass-aws.yaml @@ -0,0 +1,24 @@ +{{ if and .Values.wso2.deployment.persistence.solrIndexing.enabled .Values.aws.enabled }} +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-sc +provisioner: efs.csi.aws.com +parameters: + provisioningMode: efs-ap + fileSystemId: {{ .Values.aws.efs.fileSystemId | quote }} + directoryPerms: {{ .Values.aws.efs.directoryPerms | quote }} + uid: {{ .Values.kubernetes.securityContext.runAsUser | quote }} + gid: {{ .Values.kubernetes.securityContext.runAsUser | quote }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-storageclass-gcp.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-storageclass-gcp.yaml new file mode 100644 index 000000000..8c86b4ad2 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-storageclass-gcp.yaml @@ -0,0 +1,23 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +{{ if and .Values.wso2.deployment.persistence.solrIndexing.enabled .Values.gcp.enabled }} +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-sc +provisioner: filestore.csi.storage.gke.io +parameters: + tier: {{ .Values.gcp.fs.tier | quote }} + network: {{ .Values.gcp.fs.network | quote }} + uid: {{ .Values.kubernetes.securityContext.runAsUser | quote }} + gid: {{ .Values.kubernetes.securityContext.runAsUser | quote }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-aws.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-aws.yaml new file mode 100644 index 000000000..60e79f04c --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-aws.yaml @@ -0,0 +1,92 @@ +{{ if and .Values.wso2.deployment.persistence.solrIndexing.enabled .Values.aws.enabled }} +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-1 + labels: + purpose: cp-carbondb-1 +spec: + capacity: + storage: {{ .Values.aws.efs.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteMany + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + persistentVolumeReclaimPolicy: Retain + csi: + driver: efs.csi.aws.com + volumeHandle: {{ .Values.aws.efs.fileSystemId }}::{{ .Values.aws.efs.accessPoints.carbonDb1 }} + +--- + +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-1 + labels: + purpose: cp-solr-1 +spec: + capacity: + storage: {{ .Values.aws.efs.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteMany + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + persistentVolumeReclaimPolicy: Retain + csi: + driver: efs.csi.aws.com + volumeHandle: {{ .Values.aws.efs.fileSystemId }}::{{ .Values.aws.efs.accessPoints.solr1 }} + +--- +{{ if .Values.wso2.deployment.highAvailability }} + +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-2 + labels: + purpose: cp-carbondb-2 +spec: + capacity: + storage: {{ .Values.aws.efs.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteMany + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + persistentVolumeReclaimPolicy: Retain + csi: + driver: efs.csi.aws.com + volumeHandle: {{ .Values.aws.efs.fileSystemId }}::{{ .Values.aws.efs.accessPoints.carbonDb2 }} + +--- + +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-2 + labels: + purpose: cp-solr-2 +spec: + capacity: + storage: {{ .Values.aws.efs.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteMany + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + persistentVolumeReclaimPolicy: Retain + csi: + driver: efs.csi.aws.com + volumeHandle: {{ .Values.aws.efs.fileSystemId }}::{{ .Values.aws.efs.accessPoints.solr2 }} +{{- end }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-azure.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-azure.yaml new file mode 100644 index 000000000..f5da5e681 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-azure.yaml @@ -0,0 +1,36 @@ +{{ if and .Values.wso2.deployment.persistence.solrIndexing.enabled .Values.azure.enabled }} +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ template "apim-helm-cp.fullname" . }} + labels: + purpose: cp-volume +spec: + accessModes: + - ReadWriteMany + capacity: + storage: {{ .Values.azure.persistence.capacity }} + persistentVolumeReclaimPolicy: Retain + volumeMode: Filesystem + azureFile: + secretName: {{ .Values.azure.persistence.secretName }} + secretNamespace: {{ .Release.Namespace }} + shareName: {{ .Values.azure.persistence.fileShare }} + mountOptions: + - dir_mode=0777 + - file_mode=0777 + - uid=10001 + - gid=10001 + - cache=strict +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-claims-aws.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-claims-aws.yaml new file mode 100644 index 000000000..af8615766 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-claims-aws.yaml @@ -0,0 +1,87 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +{{ if and .Values.wso2.deployment.persistence.solrIndexing.enabled .Values.aws.enabled }} + +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-1 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.carbonDatabase }} + selector: + matchLabels: + purpose: cp-carbondb-1 + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-1 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.solrIndexedData }} + selector: + matchLabels: + purpose: cp-solr-1 + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + +--- +{{ if .Values.wso2.deployment.highAvailability }} + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-2 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.carbonDatabase }} + selector: + matchLabels: + purpose: cp-carbondb-2 + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-2 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.solrIndexedData }} + selector: + matchLabels: + purpose: cp-solr-2 + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + {{ end }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-claims-azure.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-claims-azure.yaml new file mode 100644 index 000000000..d8595e8a5 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-claims-azure.yaml @@ -0,0 +1,87 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +{{ if and .Values.wso2.deployment.persistence.solrIndexing.enabled .Values.azure.enabled }} + +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-1 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.carbonDatabase }} + selector: + matchLabels: + purpose: cp-volume + storageClassName: {{ .Values.azure.persistence.storageClass | default "" }} + +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-1 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.solrIndexedData }} + selector: + matchLabels: + purpose: cp-volume + storageClassName: {{ .Values.azure.persistence.storageClass | default "" }} + +--- +{{ if .Values.wso2.deployment.highAvailability }} + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-2 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.carbonDatabase }} + selector: + matchLabels: + purpose: cp-volume + storageClassName: {{ .Values.azure.persistence.storageClass | default "" }} + +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-2 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.solrIndexedData }} + selector: + matchLabels: + purpose: cp-volume + storageClassName: {{ .Values.azure.persistence.storageClass | default "" }} + {{ end }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-gcp.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-gcp.yaml new file mode 100644 index 000000000..742229bd8 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-cp-volume-gcp.yaml @@ -0,0 +1,105 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +{{ if and .Values.wso2.deployment.persistence.solrIndexing.enabled .Values.gcp.enabled }} +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-1 + labels: + purpose: am-carbondb-1 +spec: + capacity: + storage: {{ .Values.gcp.fs.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteMany + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + persistentVolumeReclaimPolicy: Retain + csi: + driver: filestore.csi.storage.gke.io + volumeHandle: "modeInstance/{{ .Values.gcp.fs.location }}/{{ .Values.gcp.fs.fileshares.carbonDB1.fileStoreName }}/{{ .Values.gcp.fs.fileshares.carbonDB1.fileShareName }}" + volumeAttributes: + ip: {{ .Values.gcp.fs.fileshares.carbonDB1.ip }} + volume: {{ .Values.gcp.fs.fileshares.carbonDB1.fileShareName }} + +--- + +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-1 + labels: + purpose: am-solr-1 +spec: + capacity: + storage: {{ .Values.gcp.fs.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteMany + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + persistentVolumeReclaimPolicy: Retain + csi: + driver: filestore.csi.storage.gke.io + volumeHandle: "modeInstance/{{ .Values.gcp.fs.location }}/{{ .Values.gcp.fs.fileshares.solr1.fileStoreName }}/{{ .Values.gcp.fs.fileshares.solr1.fileShareName }}" + volumeAttributes: + ip: {{ .Values.gcp.fs.fileshares.solr1.ip }} + volume: {{ .Values.gcp.fs.fileshares.solr1.fileShareName }} + +--- +{{ if .Values.wso2.deployment.highAvailability }} + +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-2 + labels: + purpose: am-carbondb-2 +spec: + capacity: + storage: {{ .Values.gcp.fs.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteMany + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + persistentVolumeReclaimPolicy: Retain + csi: + driver: filestore.csi.storage.gke.io + volumeHandle: "modeInstance/{{ .Values.gcp.fs.location }}/{{ .Values.gcp.fs.fileshares.carbonDB2.fileStoreName }}/{{ .Values.gcp.fs.fileshares.carbonDB2.fileShareName }}" + volumeAttributes: + ip: {{ .Values.gcp.fs.fileshares.carbonDB2.ip }} + volume: {{ .Values.gcp.fs.fileshares.carbonDB2.fileShareName }} + +--- + +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-2 + labels: + purpose: am-solr-2 +spec: + capacity: + storage: {{ .Values.gcp.fs.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteMany + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + persistentVolumeReclaimPolicy: Retain + csi: + driver: filestore.csi.storage.gke.io + volumeHandle: "modeInstance/{{ .Values.gcp.fs.location }}/{{ .Values.gcp.fs.fileshares.solr2.fileStoreName }}/{{ .Values.gcp.fs.fileshares.solr2.fileShareName }}" + volumeAttributes: + ip: {{ .Values.gcp.fs.fileshares.solr2.ip }} + volume: {{ .Values.gcp.fs.fileshares.solr2.fileShareName }} + +{{- end }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-volume-claims-gcp.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-volume-claims-gcp.yaml new file mode 100644 index 000000000..a9e9f589e --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/control-plane/wso2am-volume-claims-gcp.yaml @@ -0,0 +1,85 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +{{ if and .Values.wso2.deployment.persistence.solrIndexing.enabled .Values.gcp.enabled }} + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-1 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.carbonDatabase }} + selector: + matchLabels: + purpose: am-carbondb-1 + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-1 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.solrIndexedData }} + selector: + matchLabels: + purpose: am-solr-1 + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + +--- +{{ if .Values.wso2.deployment.highAvailability }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-local-carbon-database-2 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.carbonDatabase }} + selector: + matchLabels: + purpose: am-carbondb-2 + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-solr-indexed-data-2 + namespace : {{ .Release.Namespace }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.wso2.deployment.persistence.solrIndexing.capacity.solrIndexedData }} + selector: + matchLabels: + purpose: am-solr-2 + storageClassName: {{ template "apim-helm-cp.fullname" . }}-sc + +{{- end }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/secrets/wso2am-cp-secret-store-csi.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/secrets/wso2am-cp-secret-store-csi.yaml new file mode 100644 index 000000000..d9b875d31 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/secrets/wso2am-cp-secret-store-csi.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.wso2.apim.secureVaultEnabled .Values.azure.enabled }} +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "apim-helm-cp.fullname" . }}-secret-store-csi + namespace: {{ .Release.Namespace }} +type: Opaque +data: + clientid: {{ .Values.azure.keyVault.activeDirectory.servicePrincipal.appId | b64enc }} + clientsecret: {{ .Values.azure.keyVault.activeDirectory.servicePrincipal.clientSecretName | b64enc }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/secrets/wso2am-cp-secret-store-provider-aws.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/secrets/wso2am-cp-secret-store-provider-aws.yaml new file mode 100644 index 000000000..019c9c95d --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/secrets/wso2am-cp-secret-store-provider-aws.yaml @@ -0,0 +1,29 @@ +{{- if and .Values.wso2.apim.secureVaultEnabled .Values.aws.enabled }} + +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: {{ .Values.aws.secretsManager.secretProviderClass }} + namespace: {{ .Release.Namespace }} +spec: + provider: aws + parameters: + region: {{ .Values.aws.region }} + objects: | + - objectName: {{ .Values.aws.secretsManager.secretIdentifiers.internalKeystorePassword.secretName | quote }} + objectType: "secretsmanager" + jmesPath: + - path: {{ .Values.aws.secretsManager.secretIdentifiers.internalKeystorePassword.secretKey }} + objectAlias: {{ .Values.aws.secretsManager.secretIdentifiers.internalKeystorePassword.secretKey }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/templates/secrets/wso2am-cp-secret-store-provider-azure.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/secrets/wso2am-cp-secret-store-provider-azure.yaml new file mode 100644 index 000000000..987d79485 --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/templates/secrets/wso2am-cp-secret-store-provider-azure.yaml @@ -0,0 +1,35 @@ +{{- if and .Values.wso2.apim.secureVaultEnabled .Values.azure.enabled }} +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: {{ .Values.azure.keyVault.secretProviderClass }} +spec: + provider: azure + parameters: + keyvaultName: {{ .Values.azure.keyVault.name }} + userAssignedIdentityID: "{{ .Values.azure.keyVault.activeDirectory.servicePrincipal.appId }}" + objects: | + array: + - | + objectName: {{ .Values.azure.keyVault.secretIdentifiers.internalKeystorePassword }} + objectType: secret + objectVersion: "" + - | + objectName: {{ .Values.azure.keyVault.secretIdentifiers.internalKeystoreKeyPassword }} + objectType: secret + objectVersion: "" + tenantId: {{ .Values.azure.keyVault.activeDirectory.tenantId }} + resourceGroup: {{ .Values.azure.keyVault.resourceManager.resourceGroup }} + subscriptionId: {{ .Values.azure.keyVault.resourceManager.subscriptionId }} +{{- end }} diff --git a/test/apim-apk-agent-test/apim-cp-helm-chart/values.yaml b/test/apim-apk-agent-test/apim-cp-helm-chart/values.yaml new file mode 100644 index 000000000..a23bebd2e --- /dev/null +++ b/test/apim-apk-agent-test/apim-cp-helm-chart/values.yaml @@ -0,0 +1,448 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). All Rights Reserved. +# +# This software is the property of WSO2 LLC. and its suppliers, if any. +# Dissemination of any information or reproduction of any material contained +# herein is strictly forbidden, unless permitted by WSO2 in accordance with the +# WSO2 Commercial License available at https://wso2.com/licenses/eula/3.2 +# +# -------------------------------------------------------------------------------------- + +aws: + # -- If AWS is used as the cloud provider + enabled: false + efs: + # -- EFS capacity + capacity: "" + # -- EFS directory permissions + directoryPerms: "0777" + # -- EFS file system ID for mounting the persistent volume + fileSystemId: "" + # -- EFS Access Points for static provisioning + accessPoints: + carbonDb1: "" + solr1: "" + carbonDb2: "" + solr2: "" + # -- AWS region + region: "" + secretsManager: + # -- AWS Secrets Manager secret provider class name + secretProviderClass: "wso2am-cp-secret-provider-class" + secretIdentifiers: + # -- Internal keystore password identifier in secrets manager + internalKeystorePassword: + # -- AWS Secrets Manager secret name + secretName: "" + # -- AWS Secrets Manager secret key + secretKey: "" + serviceAccountName: "" +azure: + # -- If Azure is used as the cloud provider + enabled: false + keyVault: + # -- Azure Key vault used for credential management + name: "" + # -- Azure Key vault secret provider class name + secretProviderClass: "wso2am-cp-secret-provider-class" + secretIdentifiers: + # -- Internal keystore password identifier in keyvault + internalKeystorePassword: "" + # -- Internal keystore key password identifier in keyvault + internalKeystoreKeyPassword: "" + activeDirectory: + # -- Service Principal created for transacting with the target Azure Key Vault + # For advanced details refer to official documentation (https://github.com/Azure/secrets-store-csi-driver-provider-azure/blob/master/docs/service-principal-mode.md) + servicePrincipal: + # -- Application ID of the service principal used in secret-store-csi + appId: "" + # -- Client secret name of the service principal used in secret-store-csi + clientSecretName: "" + # -- Credentials secret name of the service principal used as nodePublisherRef + credentialsSecretName: "" + # -- Azure Active Directory tenant ID of the target Key Vault + tenantId: "" + resourceManager: + # -- Subscription ID of the target Azure Key Vault + subscriptionId: "" + # -- Name of the Azure Resource Group to which the target Azure Key Vault belongs + resourceGroup: "" + persistence: + # Needed for persisting indexing related data + # -- Persistent volume capacity + capacity: "" + # -- Persistent volume storage class + storageClass: "" + # -- Azure file secret name + secretName: "" + # -- Azure fileshare name + fileShare: "" + +# Google Cloud Platform (GCP) integration status +gcp: + # -- If GCP is used as the cloud provider + enabled: false + # -- File Store configuration parameters + fs: + # -- Storage capacity of the file system (in GB or other appropriate units) + capacity: "" + # -- FileStore configuration for specific services + fileshares: + # -- FileShare configs for CarbonDB persistent storage for instance 1 + carbonDB1: + # -- FileStore of the CarbonDB persistent storage for instance 1 + fileStoreName: "" + # -- FileShare of the CarbonDB persistent storage for instance 1 + fileShareName: "" + # -- IP of the CarbonDB persistent storage for instance 1 + ip: "" + # -- FileShare configs for Solr persistent storage for instance 1 + solr1: + # -- FileStore of the Solr persistent storage for instance 1 + fileStoreName: "" + # -- FileShare of the Solr persistent storage for instance 1 + fileShareName: "" + # -- IP of the Solr persistent storage for instance 1 + ip: "" + # -- FileShare configs for CarbonDB2 persistent storage for instance 2 + carbonDB2: + # -- FileStore of the CarbonDB persistent storage for instance 2 + fileStoreName: "" + # -- FileShare of the CarbonDB persistent storage for instance 2 + fileShareName: "" + # -- IP of the CarbonDB persistent storage for instance 2 + ip: "" + # -- FileShare configs for Solr persistent storage for instance 2 + solr2: + # -- FileStore of the Solr persistent storage for instance 2 + fileStoreName: "" + # -- FileShare of the Solr persistent storage for instance 2 + fileShareName: "" + # -- IP of the Solr persistent storage for instance 2 + ip: "" + # -- Tier of the FileStore + tier: "" + # -- Network of the FileStore + network: "" + # -- Region of the FileStore + location: "" + + # -- Secrets Manager configuration parameters + secretsManager: + # -- Project ID + projectId: "" + # -- Secret provider class + secretProviderClass: "" + secret: + # -- Name of the secret + secretName: "" + # -- Version of the secret + secretVersion: "" + # -- Service Account with access to read secrets + serviceAccountName: "" + +kubernetes: + # -- Ingress class to be used for the ingress resource + ingressClass: "nginx" + ingress: + # -- Kubernetes secret created for Ingress TLS + tlsSecret: "" + ratelimit: + # -- Ingress rate limit + enabled: false + # -- Ingress ratelimit zone name + zoneName: "" + # -- Ingress ratelimit burst limit + burstLimit: "" + controlPlane: + # -- Ingress hostname + hostname: "am.wso2.com" + # -- Ingress annotations + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + nginx.ingress.kubernetes.io/affinity: "cookie" + nginx.ingress.kubernetes.io/session-cookie-name: "route" + nginx.ingress.kubernetes.io/session-cookie-hash: "sha1" + + securityContext: + # -- User ID of the container + runAsUser: 802 + # -- Enable AppArmor profiles for the deployment + enableAppArmor: false + +wso2: + apim: + # -- APIM version + version: "4.3.0" + # -- Secure vauld enabled + secureVaultEnabled: false + # Logging related configurations + log4j2: + # -- Console loggers that can be enabled. Allowed values are AUDIT_LOG_CONSOLE, HTTP_ACCESS_CONSOLE, TRANSACTION_CONSOLE, CORRELATION_CONSOLE + loggers: "" + # -- Appenders + appenders: "" + # -- Startup arguments for APIM + startupArgs: "" + # -- Port Offset for APIM deployment + portOffset: 0 + # TOML configurations + configurations: + userStore: + # -- User store type. + # https://apim.docs.wso2.com/en/latest/administer/managing-users-and-roles/managing-user-stores/configure-primary-user-store/configuring-the-primary-user-store/ + type: "database_unique_id" + # -- User store properties + properties: + key: value + # -- Super admin username + adminUsername: "admin" + # -- Super admin password + adminPassword: "admin" + databases: + # -- Database type. eg: mysql, oracle, mssql, postgres + type: "h2" + jdbc: + # -- JDBC driver class name + driver: "" + # -- APIM AM_DB configurations. + apim_db: + # -- APIM AM_DB URL + url: "jdbc:h2:./repository/database/WSO2AM_DB;DB_CLOSE_ON_EXIT=FALSE" + # -- APIM AM_DB username + username: "wso2carbon" + # -- APIM AM_DB password + password: "wso2carbon" + # -- APIM database JDBC pool parameters + poolParameters: + defaultAutoCommit: false + testOnBorrow: true + testWhileIdle: true + validationInterval: 30000 + maxActive: 100 + maxWait: 60000 + minIdle: 5 + # -- APIM SharedDB configurations. + shared_db: + # -- APIM SharedDB URL + url: "jdbc:h2:./repository/database/WSO2SHARED_DB;DB_CLOSE_ON_EXIT=FALSE" + # -- APIM SharedDB username + username: "wso2carbon" + # -- APIM SharedDB password + password: "wso2carbon" + # -- APIM shared database JDBC pool parameters + poolParameters: + defaultAutoCommit: false + testOnBorrow: true + testWhileIdle: true + validationInterval: 30000 + maxActive: 100 + maxWait: 60000 + minIdle: 5 + + security: + # -- Kubernetes secret containing the keystores and truststore + #jksSecretName: "apim-keystore-secret" + keystores: + primary: + # -- Primary keystore enabled + enabled: false + # -- Primary keystore name + name: "wso2carbon.jks" + # -- Primary keystore alias + alias: "wso2carbon" + # -- Primary keystore password + password: "wso2carbon" + # -- Primary keystore key password + keyPassword: "wso2carbon" + tls: + # -- TLS keystore enabled + enabled: true + # -- TLS keystore name + name: "wso2carbon.jks" + # -- TLS keystore alias + alias: "wso2carbon" + # -- TLS keystore password + password: "wso2carbon" + # -- TLS keystore key password + keyPassword: "wso2carbon" + internal: + # -- Internal keystore enabled + enabled: false + # -- Internal keystore name + name: "wso2carbon.jks" + # -- Internal keystore alias + alias: "wso2carbon" + # -- Internal keystore password + password: "wso2carbon" + # -- Internal keystore key password + keyPassword: "wso2carbon" + truststore: + # -- Truststore name + name: "client-truststore.jks" + # -- Truststore password + password: "wso2carbon" + + gateway: + # -- APIM Gateway environments + environments: + - name: "Default" + type: "hybrid" + provider: "wso2" + displayInApiConsole: true + description: "This is a hybrid gateway that handles both production and sandbox token traffic." + showAsTokenEndpointUrl: true + serviceName: "wso2am-gateway-service" + servicePort: 9443 + wsHostname: "websocket.wso2.com" + httpHostname: "default.gw.wso2.com" + websubHostname: "websub.wso2.com" + + iskm: + # -- If Identity Server is used as the Resident KM + enabled: false + # -- Kubernetes service name exposing Identity Server + serviceName: "" + # -- Kubernetes service port exposing Identity Serve + servicePort: 9443 + + publisher: + # -- Supported document types in Publisher. + # This should be used only if there are additional document types to be supported. + supportedDocumentTypes: "" + + devportal: + enableApplicationSharing: + applicationSharingType: + applicationSharingImpl: + displayMutipleVersions: + displayDeprecatedAPIs: + enableComments: + enableRatings: + enableForum: + enableAnonymousMode: + enableCrossTenantSubscriptions: + defaultReservedUsername: + loginUsernameCaseInsensitive: + enableKeyProvisioning: + + # APIM OAuth configurations + oauth_config: + # -- Enable token encryption + enableTokenEncryption: false + # -- Enable token hashing + enableTokenHashing: false + # -- List of allow-listed scopes + allowedScopes: ["^device_.*,openid"] + + # APIM Open Tracing configurations + # https://apim.docs.wso2.com/en/latest/observe/api-manager/traces/monitoring-with-opentracing/ + openTracer: + # -- Open Tracing enabled + enabled: false + # -- Remote tracer name. e.g. jaeger, zipkin + name: "" + properties: + # -- Remote tracer hostname + hostname: "" + # -- Remote tracer port + port: "" + # APIM Open Telemetry configurations + openTelemetry: + # -- Open Telemetry enabled + enabled: false + # -- Remote tracer name. e.g. jaeger, zipkin, OTLP + name: "" + # -- Remote tracer hostname + hostname: "" + # -- Remote tracer port + port: "" + + deployment: + # Container image configurations + image: + # -- Container registry hostname + registry: "" + # -- Azure ACR repository name consisting the image + repository: "sampathrajapakse/wso2am" + # -- Docker image digest + digest: "" + # -- Refer to the Kubernetes documentation on updating images (https://kubernetes.io/docs/concepts/containers/images/#updating-images) + imagePullPolicy: Always + + resources: + # These are the resource recommendations for running WSO2 API Management product profiles with profile optimization + # Resource configurations defined here are applicable for all API Manager product profiles of this deployment + requests: + # -- Memory request for API Manager + memory: "2Gi" + # -- CPU request for API Manager + cpu: "2000m" + limits: + # -- Memory limit for API Manager + memory: "3Gi" + # -- CPU limit for API Manager + cpu: "3000m" + jvm: + memory: + # -- JVM heap memory Xms + xms: "2048m" + # -- JVM heap memory Xmx + xmx: "2048m" + + # Kubernetes Probes + # Indicates whether the container starting + startupProbe: + # -- Number of seconds after the container has started before startup probes are initiated + initialDelaySeconds: 60 + # -- How often (in seconds) to perform the probe + periodSeconds: 10 + # -- Minimum consecutive successes for the probe to be considered successful after having failed + failureThreshold: 3 + # Indicates whether the container is running + livenessProbe: + # -- Number of seconds after the container has started before liveness probes are initiated + initialDelaySeconds: 60 + # -- How often (in seconds) to perform the probe + periodSeconds: 10 + # -- Minimum consecutive successes for the probe to be considered successful after having failed + failureThreshold: 3 + # Indicates whether the container is ready to service requests + readinessProbe: + # -- Number of seconds after the container has started before readiness probes are initiated + initialDelaySeconds: 60 + # -- How often (in seconds) to perform the probe + periodSeconds: 10 + # -- Minimum consecutive successes for the probe to be considered successful after having failed + failureThreshold: 3 + + lifecycle: + preStopHook: + # -- Number of seconds to sleep before sending SIGTERM to the pod + sleepSeconds: 10 + + # Number of deployment replicas + replicas: 1 + # -- Minimum available pod counts for PDB + minAvailable: "50%" + + # -- Node selector to deploy pod in selected node. Add label to the node and specify the label here. + nodeSelector: + + # -- Enable high availability for traffic manager. If this is enabled, two traffic manager instances will be deployed. + # This is not relavant to HA in Kubernetes. Multiple replicas of the same instance will not count as HA for TM. + highAvailability: false + + persistence: + # -- Persistent runtime artifacts for Apache Solr-based indexing + solrIndexing: + # -- Indicates if persistence of the runtime artifacts for Apache Solr-based indexing is enabled + # By default, this is disabled + enabled: false + # Define capacities for persistent runtime artifact directories + capacity: + # -- For persisting the H2 based local Carbon database file + carbonDatabase: 50M + # -- For persisting the indexed solr data + solrIndexedData: 50M \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/.gitattributes b/test/apim-apk-agent-test/cucumber-tests/.gitattributes new file mode 100644 index 000000000..097f9f98d --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/.gitattributes @@ -0,0 +1,9 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# Linux start script should use lf +/gradlew text eol=lf + +# These are Windows script files and should use crlf +*.bat text eol=crlf + diff --git a/test/apim-apk-agent-test/cucumber-tests/.gitignore b/test/apim-apk-agent-test/cucumber-tests/.gitignore new file mode 100644 index 000000000..1b6985c00 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/.gitignore @@ -0,0 +1,5 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build diff --git a/test/apim-apk-agent-test/cucumber-tests/CRs/artifacts.yaml b/test/apim-apk-agent-test/cucumber-tests/CRs/artifacts.yaml new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/CRs/artifacts.yaml @@ -0,0 +1,2 @@ + + diff --git a/test/apim-apk-agent-test/cucumber-tests/README.md b/test/apim-apk-agent-test/cucumber-tests/README.md new file mode 100644 index 000000000..4786daefd --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/README.md @@ -0,0 +1,91 @@ +# WSO2 APK Cucumber Based Integration Tests + +This folder contains APK cucumber integration tests that is used to test APK product capabilities + +## Pre-requisites + +1. [Helm](https://helm.sh/docs/intro/install/) +2. [Kubernetes Client](https://kubernetes.io/docs/tasks/tools/install-kubectl/) +3. [Kubernetes Cluster](https://kubernetes.io/docs/setup) + +## Overview + +This test module use the [Cucumber](https://cucumber.io/) framework and [Gherkin](https://cucumber.io/docs/gherkin/) Syntax to write the integration tests. + +## Writing Tests + +The tests are written using the Cucumber syntax in feature files located under the `src/test/resources/tests` directory. Each feature file represents a set of related test scenarios written in the Gherkin language. + +To create a new feature, follow these steps: + +1. Create a new feature file in the `src/test/resources/tests` directory with a `.feature` extension. + +2. Write your test scenarios in Gherkin syntax. + +3. Step definitions are written in Java and can be found under the `src/test/java/org/wso2/apk/integration` directory. You may need to add new step definitions to support your new scenarios. + +4. Add the new feature file to the `src/resources/testng.xml` file to run the tests. + +## Run or Debug the Integration Tests Locally + +1. Setup the deployment namespace. + + ```bash + kubectl create namespace apk + ``` + +2. Go to the `product-apim-tooling/apim-apk-agent-test/apk-helm-chart` directory and run following commands to install the APK components. + + ```bash + helm repo add bitnami https://charts.bitnami.com/bitnami + helm repo add jetstack https://charts.jetstack.io + helm dependency build + helm install apk-test-setup . -n apk + ``` + +3. Port forward router-service to use localhost. + + ```bash + kubectl port-forward svc/apk-test-setup-wso2-apk-router-service -n apk 9095:9095 + ``` + +4. Add the following DNS mappings to `/etc/hosts` file. + + ```bash + IP=127.0.0.1 + sudo echo "$IP idp.am.wso2.com" | sudo tee -a /etc/hosts + sudo echo "$IP api.am.wso2.com" | sudo tee -a /etc/hosts + sudo echo "$IP default.gw.wso2.com" | sudo tee -a /etc/hosts + sudo echo "$IP default.sandbox.gw.wso2.com" | sudo tee -a /etc/hosts + ``` + +5. Go to the `product-apim-tooling/apim-apk-agent-test/apim-cp-helm-chart` directory and run following commands to install the APIM CP component. + + ```bash + helm dependency build + helm install apim . -n apk + `` + +6. Port forward router-service to use localhost. + + ```bash + kubectl port-forward svc/apim-wso2am-cp-1-service -n apk 9443:9443 + ``` + +7. Go to the `product-apim-tooling/helm-charts` directory and run following commands to install the APIM APK Agent components. + + ```bash + helm dependency build + helm install apim-apk-agent . -n apk + ``` + +8. Run or debug integration tests. + + - Run following command from `product-apim-tooling/apim-apk-agent-test/cucumber-tests` directory to run the integration tests. + + ```bash + gradle runTests + ``` + - To run a single test, update the `product-apim-tooling/apim-apk-agent-test/cucumber-tests/src/resources/testng.xml` file with the required feature file and run the above command. + + - Run the `gradle runTests --debug-jvm` command and attach the debugger in the IDE to debug the integration tests. diff --git a/test/apim-apk-agent-test/cucumber-tests/build.gradle b/test/apim-apk-agent-test/cucumber-tests/build.gradle new file mode 100644 index 000000000..a681ff06a --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/build.gradle @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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. + * + */ + +plugins { + id 'java' +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'io.cucumber:cucumber-picocontainer:7.2.3' + testImplementation 'io.cucumber:cucumber-core:7.2.3' + testImplementation 'com.google.guava:guava:32.1.1-jre' + testImplementation 'com.google.code.gson:gson:2.10.1' + testImplementation 'org.apache.httpcomponents:httpmime:4.5.13' + testImplementation 'org.apache.httpcomponents:httpclient:4.5.13' + testImplementation 'org.apache.httpcomponents:httpcore:4.4.14' + testImplementation 'io.cucumber:cucumber-java:7.13.0' + testImplementation 'io.cucumber:cucumber-testng:7.13.0' + testImplementation 'commons-io:commons-io:2.13.0' + testImplementation 'com.nimbusds:nimbus-jose-jwt:9.31' + testImplementation 'com.googlecode.json-simple:json-simple:1.1.1' +} + +test { + reports.junitXml.enabled = true + useTestNG() + testLogging { + events "passed", "skipped", "failed", "standardOut", "standardError" + } +} + +task runTests(type: JavaExec, dependsOn: 'classes') { + main = 'org.testng.TestNG' + classpath = files("./src/test/resources", + project.sourceSets.main.compileClasspath, + project.sourceSets.test.compileClasspath, + project.sourceSets.main.runtimeClasspath, + project.sourceSets.test.runtimeClasspath) + args = ["-d", "./build/test-output", "./src/test/resources/testng.xml"] +} diff --git a/test/apim-apk-agent-test/cucumber-tests/gradle/wrapper/gradle-wrapper.properties b/test/apim-apk-agent-test/cucumber-tests/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..070cb702f --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/test/apim-apk-agent-test/cucumber-tests/gradlew b/test/apim-apk-agent-test/cucumber-tests/gradlew new file mode 100755 index 000000000..a69d9cb6c --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/gradlew @@ -0,0 +1,240 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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 +# +# https://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. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/test/apim-apk-agent-test/cucumber-tests/gradlew.bat b/test/apim-apk-agent-test/cucumber-tests/gradlew.bat new file mode 100644 index 000000000..f127cfd49 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/gradlew.bat @@ -0,0 +1,91 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/test/apim-apk-agent-test/cucumber-tests/scripts/setup-hosts.sh b/test/apim-apk-agent-test/cucumber-tests/scripts/setup-hosts.sh new file mode 100644 index 000000000..de2d21ddf --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/scripts/setup-hosts.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +kubectl apply -f ./CRs/artifacts.yaml +kubectl wait deployment/wso2apim -n apk --for=condition=available --timeout=600s +kubectl wait --timeout=5m -n apk deployment/apk-test-setup-wso2-apk-adapter-deployment --for=condition=Available +kubectl wait --timeout=15m -n apk deployment/apk-test-setup-wso2-apk-gateway-runtime-deployment --for=condition=Available +kubectl wait --timeout=5m -n apk deployment/apim-apk-agent --for=condition=Available +IP=$(kubectl get svc apk-test-setup-wso2-apk-gateway-service -n apk-integration-test --output jsonpath='{.status.loadBalancer.ingress[0].ip}') +CC_IP=$(kubectl get svc apk-test-setup-wso2-apk-common-controller-web-server-service -n apk-integration-test --output jsonpath='{.status.loadBalancer.ingress[0].ip}') +sudo echo "$IP localhost" | sudo tee -a /etc/hosts +sudo echo "$IP idp.am.wso2.com" | sudo tee -a /etc/hosts +sudo echo "$CC_IP apk-test-setup-wso2-apk-common-controller-service.apk.svc" | sudo tee -a /etc/hosts +sudo echo "$IP am.wso2.com" | sudo tee -a /etc/hosts +sudo echo "$IP api.am.wso2.com" | sudo tee -a /etc/hosts +sudo echo "$IP default.gw.wso2.com" | sudo tee -a /etc/hosts +sudo echo "$IP default.sandbox.gw.wso2.com" | sudo tee -a /etc/hosts +sudo echo "255.255.255.255 broadcasthost" | sudo tee -a /etc/hosts +sudo echo "::1 localhost" | sudo tee -a /etc/hosts diff --git a/test/apim-apk-agent-test/cucumber-tests/settings.gradle b/test/apim-apk-agent-test/cucumber-tests/settings.gradle new file mode 100644 index 000000000..e44b1a136 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/7.5.1/userguide/multi_project_builds.html + */ + +rootProject.name = 'cucumber-tests' diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/APKIntegrationTestSuite.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/APKIntegrationTestSuite.java new file mode 100644 index 000000000..5acc772cd --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/APKIntegrationTestSuite.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration; + +import io.cucumber.testng.AbstractTestNGCucumberTests; + +public class APKIntegrationTestSuite extends AbstractTestNGCucumberTests { + +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APIDeploymentSteps.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APIDeploymentSteps.java new file mode 100644 index 000000000..7f5c74dc6 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APIDeploymentSteps.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2024, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration.api; + +import com.google.common.io.Resources; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.message.BasicNameValuePair; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.testng.Assert; +import org.wso2.apk.integration.utils.Constants; +import org.wso2.apk.integration.utils.Utils; +import org.wso2.apk.integration.utils.clients.SimpleHTTPClient; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class contains the step definitions for API Deployment. + */ +public class APIDeploymentSteps { + + private final SharedContext sharedContext; + private File payloadFile; + private File definitionFile; + + private String OASURL; + + private static final Log logger = LogFactory.getLog(APIDeploymentSteps.class); + + public APIDeploymentSteps(SharedContext sharedContext) { + + this.sharedContext = sharedContext; + } + + @When("I use the Payload file {string}") + public void iHaveTheAPKConf(String payloadFileName) throws IOException { + + URL url = Resources.getResource(payloadFileName); + payloadFile = new File(url.getPath()); + } + + @When("I use the OAS URL {string}") + public void iHaveTheOASURL(String pOASURL) throws IOException { + OASURL = pOASURL; + } + + @When("the definition file {string}") + public void iHaveTheDefinitionFile(String definitionFileName) throws IOException { + + URL url = Resources.getResource(definitionFileName); + definitionFile = new File(url.getPath()); + } + + @When("make the import API Creation request") + public void make_import_api_creation_request() throws Exception { + logger.info("OAS URL: " + OASURL); + + // Create a MultipartEntityBuilder to build the request entity + MultipartEntityBuilder builder = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addTextBody("url", OASURL, ContentType.TEXT_PLAIN) + .addPart("additionalProperties", new FileBody(payloadFile)); + + logger.info("Payload File: "+ new FileBody(payloadFile)); + + Map headers = new HashMap<>(); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken()); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); + + HttpEntity multipartEntity = builder.build(); + + HttpResponse response = sharedContext.getHttpClient().doPostWithMultipart(Utils.getImportAPIURL(), + multipartEntity, headers); + + sharedContext.setResponse(response); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + sharedContext.setApiUUID(Utils.extractID(sharedContext.getResponseBody())); + Thread.sleep(3000); + } + + @When("make the API Revision Deployment request") + public void make_a_api_revision_deployment_request() throws Exception { + String apiUUID = sharedContext.getApiUUID(); + String payload = "{\"description\":\"Initial Revision\"}"; + + Map headers = new HashMap<>(); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken()); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); + + HttpResponse response = sharedContext.getHttpClient().doPost(Utils.getAPIRevisionURL(apiUUID), + headers, payload, Constants.CONTENT_TYPES.APPLICATION_JSON); + + sharedContext.setRevisionUUID(Utils.extractID(SimpleHTTPClient.responseEntityBodyToString(response))); + + Thread.sleep(3000); + + String payload2 = "[{\"name\": \"Default\", \"vhost\": \"default.gw.wso2.com\", \"displayOnDevportal\": true}]"; + + HttpResponse response2 = sharedContext.getHttpClient().doPost(Utils.getAPIRevisionDeploymentURL(apiUUID, sharedContext.getRevisionUUID()), + headers, payload2, Constants.CONTENT_TYPES.APPLICATION_JSON); + + logger.info("Response: "+ response2); + + sharedContext.setResponse(response2); + Thread.sleep(3000); + } + + @When("make the API Deployment request") + public void make_a_api_deployment_request() throws Exception { + + // Create a MultipartEntityBuilder to build the request entity + MultipartEntityBuilder builder = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addPart("url", new FileBody(definitionFile)) + .addPart("apkConfiguration", new FileBody(payloadFile)); + + Map headers = new HashMap<>(); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken()); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); + + HttpEntity multipartEntity = builder.build(); + + HttpResponse response = sharedContext.getHttpClient().doPostWithMultipart(Utils.getAPIDeployerURL(), + multipartEntity, headers); + + sharedContext.setResponse(response); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + Thread.sleep(3000); + } + + @When("make the API deployment request for organization {string}") + public void makeAPIDeploymentFromOrganization(String organization) throws Exception { + + // Create a MultipartEntityBuilder to build the request entity + MultipartEntityBuilder builder = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addPart("definitionFile", new FileBody(definitionFile)) + .addPart("apkConfiguration", new FileBody(payloadFile)); + + Map headers = new HashMap<>(); + Object accessToken = sharedContext.getStoreValue(organization); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + accessToken); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); + + HttpEntity multipartEntity = builder.build(); + + HttpResponse response = sharedContext.getHttpClient().doPostWithMultipart(Utils.getAPIDeployerURL(), + multipartEntity, headers); + + sharedContext.setResponse(response); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + Thread.sleep(3000); + } + + + + @When("I undeploy the API whose ID is {string}") + public void i_undeploy_the_api_whose_id_is(String apiID) throws Exception { + + // Create query parameters + List queryParams = new ArrayList<>(); + queryParams.add(new BasicNameValuePair("apiId", apiID)); + + URI uri = new URIBuilder(Utils.getAPIUnDeployerURL()).addParameters(queryParams).build(); + + Map headers = new HashMap<>(); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken()); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); + + HttpResponse response = sharedContext.getHttpClient().doPost(uri.toString(), headers, "", + Constants.CONTENT_TYPES.APPLICATION_JSON); + + sharedContext.setResponse(response); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + } + + @When("I undeploy the API whose ID is {string} and organization {string}") + public void undeployAPIByIdAndOrganization(String apiID,String organization) throws Exception { + + // Create query parameters + List queryParams = new ArrayList<>(); + queryParams.add(new BasicNameValuePair("apiId", apiID)); + + URI uri = new URIBuilder(Utils.getAPIUnDeployerURL()).addParameters(queryParams).build(); + + Map headers = new HashMap<>(); + Object header = sharedContext.getStoreValue(organization); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + header); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); + + HttpResponse response = sharedContext.getHttpClient().doPost(uri.toString(), headers, "", + Constants.CONTENT_TYPES.APPLICATION_JSON); + + sharedContext.setResponse(response); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APKGenerationSteps.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APKGenerationSteps.java new file mode 100644 index 000000000..21f2b09a0 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APKGenerationSteps.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration.api; + +import com.google.common.io.Resources; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.testng.Assert; +import org.wso2.apk.integration.utils.Utils; + +import java.io.File; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +/** + * This class contains the step definitions for APK generation. + */ +public class APKGenerationSteps { + + private final SharedContext sharedContext; + private File definitionFile; + + public APKGenerationSteps(SharedContext sharedContext) { + + this.sharedContext = sharedContext; + } + + @When("I use the definition file {string} in resources") + public void i_use_the_definition_file_in_resources(String definitionFilePath) { + + URL url = Resources.getResource(definitionFilePath); + definitionFile = new File(url.getPath()); + } + + @When("generate the APK conf file for a {string} API") + public void generate_the_apk_conf_file(String apiType) throws Exception { + + // Create a MultipartEntityBuilder to build the request entity + MultipartEntityBuilder builder = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addTextBody("apiType", apiType) + .addPart("definition", new FileBody(definitionFile)); + + HttpEntity multipartEntity = builder.build(); + HttpResponse httpResponse = sharedContext.getHttpClient().doPostWithMultipart(Utils.getConfigGeneratorURL(), + multipartEntity); + sharedContext.setResponse(httpResponse); + } + + @Then("the response body should be {string} in resources") + public void the_response_body_should_be_in_resources(String expectedAPKConfFilePath) throws Exception { + + URL url = Resources.getResource(expectedAPKConfFilePath); + String text = Resources.toString(url, StandardCharsets.UTF_8); + + Assert.assertEquals(sharedContext.getHttpClient().getResponsePayload(sharedContext.getResponse()), text); + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java new file mode 100644 index 000000000..04db3306a --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2024, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration.api; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JOSEObjectType; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.jwk.source.JWKSource; +import com.nimbusds.jose.jwk.source.JWKSourceBuilder; +import com.nimbusds.jose.proc.BadJOSEException; +import com.nimbusds.jose.proc.DefaultJOSEObjectTypeVerifier; +import com.nimbusds.jose.proc.JWSKeySelector; +import com.nimbusds.jose.proc.JWSVerificationKeySelector; +import com.nimbusds.jose.proc.SecurityContext; +import com.nimbusds.jose.util.Resource; +import com.nimbusds.jose.util.ResourceRetriever; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.proc.ConfigurableJWTProcessor; +import com.nimbusds.jwt.proc.DefaultJWTProcessor; +import io.cucumber.core.options.CurlOption; +import io.cucumber.datatable.DataTable; +import io.cucumber.java.Before; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.testng.Assert; +import org.wso2.apk.integration.utils.Constants; +import org.wso2.apk.integration.utils.Utils; +import org.wso2.apk.integration.utils.clients.SimpleHTTPClient; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.text.ParseException; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class contains the common step definitions. + */ +public class BaseSteps { + + private static final Log logger = LogFactory.getLog(BaseSteps.class); + private final SharedContext sharedContext; + private SimpleHTTPClient httpClient; + private static final int MAX_WAIT_FOR_NEXT_MINUTE_IN_SECONDS = 10; + + public BaseSteps(SharedContext sharedContext) { + + this.sharedContext = sharedContext; + } + + @Before + public void setup() throws Exception { + + httpClient = sharedContext.getHttpClient(); + } + + @Given("The system is ready") + public void systemIsReady() { + + } + + @Then("the response body should contain {string}") + public void theResponseBodyShouldContain(String expectedText) throws IOException { + Assert.assertTrue(sharedContext.getResponseBody().contains(expectedText), "Actual response body: " + sharedContext.getResponseBody()); + } + @Then("the response body should not contain {string}") + public void theResponseBodyShouldNotContain(String expectedText) throws IOException { + Assert.assertFalse(sharedContext.getResponseBody().contains(expectedText), "Actual response body: " + sharedContext.getResponseBody()); + } + + @Then("the response body should contain") + public void theResponseBodyShouldContain(DataTable dataTable) throws IOException { + List responseBodyLines = dataTable.asList(String.class); + for (String line : responseBodyLines) { + Assert.assertTrue(sharedContext.getResponseBody().contains(line), "Actual response body: " + sharedContext.getResponseBody()); + } + } + + @Then("the response status code should be {int}") + public void theResponseStatusCodeShouldBe(int expectedStatusCode) throws IOException { + + int actualStatusCode = sharedContext.getResponse().getStatusLine().getStatusCode(); + Assert.assertEquals(actualStatusCode, expectedStatusCode); + } + + @Then("I send {string} request to {string} with body {string}") + public void sendHttpRequest(String httpMethod, String url, String body) throws IOException { + body = Utils.resolveVariables(body, sharedContext.getValueStore()); + if (sharedContext.getResponse() instanceof CloseableHttpResponse) { + ((CloseableHttpResponse) sharedContext.getResponse()).close(); + } + if (CurlOption.HttpMethod.GET.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + sharedContext.setResponse(httpClient.doGet(url, sharedContext.getHeaders())); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + } else if (CurlOption.HttpMethod.POST.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + sharedContext.setResponse(httpClient.doPost(url, sharedContext.getHeaders(), body, null)); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + } else if (CurlOption.HttpMethod.PUT.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + sharedContext.setResponse(httpClient.doPut(url, sharedContext.getHeaders(), body, null)); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + } else if (CurlOption.HttpMethod.DELETE.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + sharedContext.setResponse(httpClient.doDelete(url, sharedContext.getHeaders())); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + } else if (CurlOption.HttpMethod.OPTIONS.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + sharedContext.setResponse(httpClient.doOptions(url, sharedContext.getHeaders(), null, null)); + } + } + + // It will send request using a new thread and forget about the response + @Then("I send {string} async request to {string} with body {string}") + public void sendAsyncHttpRequest(String httpMethod, String url, String body) throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { + String finalBody = Utils.resolveVariables(body, sharedContext.getValueStore()); + if (sharedContext.getResponse() instanceof CloseableHttpResponse) { + ((CloseableHttpResponse) sharedContext.getResponse()).close(); + } + SimpleHTTPClient simpleHTTPClient = new SimpleHTTPClient(); + Thread thread = new Thread(() -> { + try { + if (CurlOption.HttpMethod.GET.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + simpleHTTPClient.doGet(url, sharedContext.getHeaders()); + } else if (CurlOption.HttpMethod.POST.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + simpleHTTPClient.doPost(url, sharedContext.getHeaders(), finalBody, null); + } else if (CurlOption.HttpMethod.PUT.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + simpleHTTPClient.doPut(url, sharedContext.getHeaders(), finalBody, null); + } else if (CurlOption.HttpMethod.DELETE.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + simpleHTTPClient.doPut(url, sharedContext.getHeaders(), finalBody, null); + } else if (CurlOption.HttpMethod.OPTIONS.toString().toLowerCase().equals(httpMethod.toLowerCase())) { + simpleHTTPClient.doOptions(url, sharedContext.getHeaders(), null, null); + } + } catch (IOException e) { + logger.warn("An async http request sending thread experienced an error: " + e); + } + }); + thread.start(); + } + + @Then("I set headers") + public void setHeaders(DataTable dataTable) { + List> rows = dataTable.asLists(String.class); + for (List columns : rows) { + String key = columns.get(0); + String value = columns.get(1); + key = Utils.resolveVariables(key, sharedContext.getValueStore()); + value = Utils.resolveVariables(value, sharedContext.getValueStore()); + sharedContext.addHeader(key, value); + } + } + + @Then("the response headers should contain") + public void theResponseHeadersShouldContain(DataTable dataTable) { + List> rows = dataTable.asLists(String.class); + for (List columns : rows) { + String key = columns.get(0); + String value = columns.get(1); + Header header = sharedContext.getResponse().getFirstHeader(key); + Assert.assertNotNull(header); + Assert.assertEquals(header.getValue(), value); + } + } + + @Then("the response headers should not contain") + public void theResponseHeadersShouldNotContain(DataTable dataTable) { + List> rows = dataTable.asLists(String.class); + for (List columns : rows) { + String key = columns.get(0); + Header header = sharedContext.getResponse().getFirstHeader(key); + Assert.assertNull(header); + } + } + + @Then("I eventually receive {int} response code, not accepting") + public void eventualSuccess(int statusCode, DataTable dataTable) throws IOException, InterruptedException { + List nonAcceptableCodes = dataTable.asList(Integer.class); + if (sharedContext.getResponse().getStatusLine().getStatusCode() == statusCode) { + Assert.assertTrue(true); + } else { + HttpResponse httpResponse = httpClient.executeLastRequestForEventualConsistentResponse(statusCode, + nonAcceptableCodes); + sharedContext.setResponse(httpResponse); + Assert.assertEquals(httpResponse.getStatusLine().getStatusCode(), statusCode); + } + } + + @Then("I wait for next minute") + public void waitForNextMinute() throws InterruptedException { + LocalDateTime now = LocalDateTime.now(); + LocalDateTime nextMinute = now.plusMinutes(1).withSecond(0).withNano(0); + long secondsToWait = now.until(nextMinute, ChronoUnit.SECONDS); + if (secondsToWait > MAX_WAIT_FOR_NEXT_MINUTE_IN_SECONDS) { + return; + } + Thread.sleep((secondsToWait+1) * 1000); + logger.info("Current time: " + LocalDateTime.now()); + } + + @Then("I wait for next minute strictly") + public void waitForNextMinuteStrictly() throws InterruptedException { + LocalDateTime now = LocalDateTime.now(); + LocalDateTime nextMinute = now.plusMinutes(1).withSecond(0).withNano(0); + long secondsToWait = now.until(nextMinute, ChronoUnit.SECONDS); + Thread.sleep((secondsToWait+1) * 1000); + logger.info("Current time: " + LocalDateTime.now()); + } + + @Then("I wait for {int} minute") + public void waitForMinute(int minute) throws InterruptedException { + Thread.sleep(minute * 1000); + } + + @Then("I wait for {int} seconds") + public void waitForSeconds(int seconds) throws InterruptedException { + Thread.sleep(seconds * 1000); + } + + @Then("the response headers contains key {string} and value {string}") + public void containsHeader(String key, String value) { + key = Utils.resolveVariables(key, sharedContext.getValueStore()); + value = Utils.resolveVariables(value, sharedContext.getValueStore()); + HttpResponse response = sharedContext.getResponse(); + if (response == null) { + Assert.fail("Response is null."); + } + Header header = response.getFirstHeader(key); + if (header == null) { + Assert.fail("Could not find a header with the given key: " + key); + } + if ("*".equals(value)) { + return; // Any value is acceptable + } + String actualValue = header.getValue(); + Assert.assertEquals(value, actualValue,"Header with key found but value mismatched."); + } + @Then("the response headers not contains key {string}") + public void notContainsHeader(String key) { + key = Utils.resolveVariables(key, sharedContext.getValueStore()); + HttpResponse response = sharedContext.getResponse(); + if (response == null) { + Assert.fail("Response is null."); + } + Header header = response.getFirstHeader(key); + Assert.assertNull(header,"header contains in response headers"); + } + + @Then("the {string} jwt should validate from JWKS {string} and contain") + public void decode_header_and_validate(String header,String jwksEndpoint, DataTable dataTable) throws MalformedURLException { + List> claims = dataTable.asMaps(String.class, String.class); + JsonObject jsonResponse = (JsonObject) JsonParser.parseString(sharedContext.getResponseBody()); + String headerValue = jsonResponse.get("headers").getAsJsonObject().get(header).getAsString(); + ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor<>(); + jwtProcessor.setJWSTypeVerifier(new DefaultJOSEObjectTypeVerifier<>(JOSEObjectType.JWT)); + ResourceRetriever retriever = url -> { + try { + HttpResponse httpResponse = new SimpleHTTPClient().doGet(url.toString(), Collections.emptyMap()); + StatusLine statusLine = httpResponse.getStatusLine(); + if (statusLine.getStatusCode() == 200) { + Header header1 = httpResponse.getFirstHeader("Content-Type"); + try (InputStream content = httpResponse.getEntity().getContent()) { + return new Resource(IOUtils.toString(content), header1.getValue()); + } + } else { + throw new IOException("HTTP " + statusLine.getStatusCode() + ": " + statusLine.getReasonPhrase()); + } + } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) { + throw new IOException(e); + } + }; + + JWKSource keySource = JWKSourceBuilder.create(new URL(jwksEndpoint), retriever).build(); + JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256; + JWSKeySelector keySelector = new JWSVerificationKeySelector<>(expectedJWSAlg, keySource); + jwtProcessor.setJWSKeySelector(keySelector); + try { + JWTClaimsSet claimsSet = jwtProcessor.process(headerValue, null); + for (Map claim : claims) { + Object claim1 = claimsSet.getClaim(claim.get("claim")); + Assert.assertNotNull(claim1, "Actual decoded JWT body: " + claimsSet); + Assert.assertEquals(claim.get("value"), claim1.toString(), "Actual " + + "decoded JWT body: " + claimsSet); + } + } catch (BadJOSEException | JOSEException|ParseException e) { + logger.error("JWT Signature verification fail", e); + Assert.fail("JWT Signature verification fail"); + } + } + + @Given("I have a DCR application for Publisher") + public void iHaveADCRApplicationForPublisher() throws Exception { + + Map headers = new HashMap<>(); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_IDP_HOST); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Basic YWRtaW46YWRtaW4="); + + HttpResponse httpResponse = httpClient.doPost(Utils.getDCREndpointURL(), headers, "{\n" + + " \"callbackUrl\":\"www.google.lk\",\n" + + " \"clientName\":\"rest_api_publisher\",\n" + + " \"owner\":\"admin\",\n" + + " \"grantType\":\"client_credentials password refresh_token\",\n" + + " \"saasApp\":true\n" + + " }", + Constants.CONTENT_TYPES.APPLICATION_JSON); + sharedContext.setPublisherBasicAuthToken(Utils.extractBasicToken(httpResponse)); + sharedContext.addStoreValue("publisherBasicAuthToken", sharedContext.getPublisherBasicAuthToken()); + } + + @Given("I have a DCR application for Devportal") + public void iHaveADCRApplicationForDevportal() throws Exception { + + Map headers = new HashMap<>(); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_IDP_HOST); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Basic YWRtaW46YWRtaW4="); + + HttpResponse httpResponse = httpClient.doPost(Utils.getDCREndpointURL(), headers, "{\n" + + " \"callbackUrl\":\"www.google.lk\",\n" + + " \"clientName\":\"rest_api_publisher\",\n" + + " \"owner\":\"admin\",\n" + + " \"grantType\":\"client_credentials password refresh_token\",\n" + + " \"saasApp\":true\n" + + " }", + Constants.CONTENT_TYPES.APPLICATION_JSON); + sharedContext.setDevportalBasicAuthToken(Utils.extractBasicToken(httpResponse)); + sharedContext.addStoreValue("devportalBasicAuthToken", sharedContext.getDevportalBasicAuthToken()); + } + + @Given("I have a valid Publisher access token") + public void iHaveValidPublisherAccessToken() throws Exception { + + Map headers = new HashMap<>(); + String basicAuthHeader = "Basic " + sharedContext.getPublisherBasicAuthToken(); + logger.info("Basic Auth Header: " + basicAuthHeader); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_IDP_HOST); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, basicAuthHeader); + + HttpResponse httpResponse = httpClient.doPost(Utils.getTokenEndpointURL(), headers, "grant_type=password&username=admin&password=admin&scope=apim:api_view apim:api_create", + Constants.CONTENT_TYPES.APPLICATION_X_WWW_FORM_URLENCODED); + logger.info("Response: " + httpResponse); + sharedContext.setPublisherAccessToken(Utils.extractToken(httpResponse)); + sharedContext.addStoreValue("publisherAccessToken", sharedContext.getPublisherAccessToken()); + } + + @Given("I have a valid Devportal access token") + public void iHaveValidDevportalAccessToken() throws Exception { + + Map headers = new HashMap<>(); + String basicAuthHeader = "Basic " + sharedContext.getDevportalBasicAuthToken(); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_IDP_HOST); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, basicAuthHeader); + + HttpResponse httpResponse = httpClient.doPost(Utils.getTokenEndpointURL(), headers, "grant_type=password&username=admin&password=admin&scope=apim:api_view apim:api_create", + Constants.CONTENT_TYPES.APPLICATION_JSON); + sharedContext.setDevportalAccessToken(Utils.extractToken(httpResponse)); + sharedContext.addStoreValue("devportalAccessToken", sharedContext.getDevportalAccessToken()); + } + +// @Given("I have a valid subscription without api deploy permission") +// public void iHaveValidSubscriptionWithAPICreateScope() throws Exception { +// +// Map headers = new HashMap<>(); +// headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_IDP_HOST); +// headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Basic NDVmMWM1YzgtYTkyZS0xMWVkLWFmYTEtMDI0MmFjMTIwMDAyOjRmYmQ2MmVjLWE5MmUtMTFlZC1hZmExLTAyNDJhYzEyMDAwMg=="); +// +// HttpResponse httpResponse = httpClient.doPost(Utils.getTokenEndpointURL(), headers, "grant_type=client_credentials", +// Constants.CONTENT_TYPES.APPLICATION_X_WWW_FORM_URLENCODED); +// sharedContext.setAccessToken(Utils.extractToken(httpResponse)); +// sharedContext.addStoreValue("accessToken", sharedContext.getAccessToken()); +// } +// +// @Given("I have a valid subscription with scopes") +// public void iHaveValidSubscriptionWithScope(DataTable dataTable) throws Exception { +// List> rows = dataTable.asLists(String.class); +// String scopes = Constants.EMPTY_STRING; +// for (List row : rows) { +// String scope = row.get(0); +// scopes += scope + Constants.SPACE_STRING; +// } +// Map headers = new HashMap<>(); +// headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_IDP_HOST); +// headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, Constants.SUBSCRIPTION_BASIC_AUTH_TOKEN); +// +// HttpResponse httpResponse = httpClient.doPost(Utils.getTokenEndpointURL(), headers, +// "grant_type=client_credentials&scope=" + scopes, +// Constants.CONTENT_TYPES.APPLICATION_X_WWW_FORM_URLENCODED); +// sharedContext.setAccessToken(Utils.extractToken(httpResponse)); +// sharedContext.addStoreValue(Constants.ACCESS_TOKEN, sharedContext.getAccessToken()); +// } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/JWTGeneratorSteps.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/JWTGeneratorSteps.java new file mode 100644 index 000000000..9b3d94028 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/JWTGeneratorSteps.java @@ -0,0 +1,113 @@ +package org.wso2.apk.integration.api; + +import com.google.common.io.Resources; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.crypto.RSASSASigner; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; +import io.cucumber.java.en.And; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.Date; +import java.util.UUID; + +import org.wso2.apk.integration.utils.Constants; + +public class JWTGeneratorSteps { + + private final SharedContext sharedContext; + + public JWTGeneratorSteps(SharedContext sharedContext) { + + this.sharedContext = sharedContext; + } + + @Then("I generate JWT token from idp1 with kid {string}") + public void generateTokenFromIdp1(String kid) throws IOException, CertificateException, KeyStoreException, + NoSuchAlgorithmException, JOSEException { + + URL url = Resources.getResource("artifacts/jwtcert/idp1.jks"); + File keyStoreFile = new File(url.getPath()); + KeyStore keyStore = KeyStore.getInstance(keyStoreFile, "wso2carbon".toCharArray()); + RSAKey rsaKey = RSAKey.load(keyStore, "idp1Key", "wso2carbon".toCharArray()); + JWSSigner signer = new RSASSASigner(rsaKey); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder() + .subject("alice") + .issuer("https://idp1.com") + .expirationTime(new Date(new Date().getTime() + 60 * 1000)) + .jwtID(UUID.randomUUID().toString()) + .claim("azp", UUID.randomUUID().toString()) + .claim("scope", Constants.API_CREATE_SCOPE) + .build(); + SignedJWT signedJWT = new SignedJWT( + new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(kid).build(), + claimsSet); + signedJWT.sign(signer); + String jwtToken = signedJWT.serialize(); + sharedContext.addStoreValue("idp-1-token", jwtToken); + } + @Then("I generate JWT token from idp1 with kid {string} and consumer_key {string}") + public void generateTokenFromIdp1WithConsumerKey(String kid,String consumerKey) throws IOException, CertificateException, KeyStoreException, + NoSuchAlgorithmException, JOSEException { + + URL url = Resources.getResource("artifacts/jwtcert/idp1.jks"); + File keyStoreFile = new File(url.getPath()); + KeyStore keyStore = KeyStore.getInstance(keyStoreFile, "wso2carbon".toCharArray()); + RSAKey rsaKey = RSAKey.load(keyStore, "idp1Key", "wso2carbon".toCharArray()); + JWSSigner signer = new RSASSASigner(rsaKey); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder() + .subject("alice") + .issuer("https://idp1.com") + .expirationTime(new Date(new Date().getTime() + 60 * 1000)) + .jwtID(UUID.randomUUID().toString()) + .claim("azp", consumerKey) + .claim("scope", Constants.API_CREATE_SCOPE) + .build(); + SignedJWT signedJWT = new SignedJWT( + new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(kid).build(), + claimsSet); + signedJWT.sign(signer); + String jwtToken = signedJWT.serialize(); + sharedContext.addStoreValue("idp-1-"+consumerKey+"-token", jwtToken); + } + + + @And("I have a valid token for organization {string}") + public void generateTokenFromIdp1WithOrganization(String organization) throws IOException, CertificateException, + KeyStoreException, + NoSuchAlgorithmException, JOSEException { + + URL url = Resources.getResource("artifacts/jwtcert/idp1.jks"); + File keyStoreFile = new File(url.getPath()); + KeyStore keyStore = KeyStore.getInstance(keyStoreFile, "wso2carbon".toCharArray()); + RSAKey rsaKey = RSAKey.load(keyStore, "idp1Key", "wso2carbon".toCharArray()); + JWSSigner signer = new RSASSASigner(rsaKey); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder() + .subject("alice") + .issuer("https://idp1.com") + .expirationTime(new Date(new Date().getTime() + 60 * 1000)) + .jwtID(UUID.randomUUID().toString()) + .claim("azp", UUID.randomUUID().toString()) + .claim("scope", Constants.API_CREATE_SCOPE) + .claim("organization", organization) + .build(); + SignedJWT signedJWT = new SignedJWT( + new JWSHeader.Builder(JWSAlgorithm.RS256).keyID("123-456").build(), + claimsSet); + signedJWT.sign(signer); + String jwtToken = signedJWT.serialize(); + sharedContext.addStoreValue(organization, jwtToken); + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/MTLSClientCertSteps.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/MTLSClientCertSteps.java new file mode 100644 index 000000000..b3f66a865 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/MTLSClientCertSteps.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration.api; + +import org.apache.http.HttpResponse; +import org.wso2.apk.integration.utils.Constants; +import org.wso2.apk.integration.utils.Utils; +import org.wso2.apk.integration.utils.clients.SimpleHTTPClient; + +import com.google.common.io.Resources; + +import io.cucumber.java.Before; +import io.cucumber.java.en.Then; + +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +/** + * This class contains the common step definitions. + */ +public class MTLSClientCertSteps { + + private final SharedContext sharedContext; + private SimpleHTTPClient httpClient; + + public MTLSClientCertSteps(SharedContext sharedContext) { + + this.sharedContext = sharedContext; + } + + @Before + public void setup() throws Exception { + + httpClient = sharedContext.getHttpClient(); + } + +// @Then("I have a valid token with a client certificate {string}") +// public void getValidClientCertificateForMTLS(String clientCertificatePath) throws Exception { +// +// Map headers = new HashMap<>(); +// headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_IDP_HOST); +// headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, +// "Basic NDVmMWM1YzgtYTkyZS0xMWVkLWFmYTEtMDI0MmFjMTIwMDAyOjRmYmQ2MmVjLWE5MmUtMTFlZC1hZmExLTAyNDJhYzEyMDAwMg=="); +// +// HttpResponse httpResponse = httpClient.doPost(Utils.getTokenEndpointURL(), headers, +// "grant_type=client_credentials&scope=" + Constants.API_CREATE_SCOPE, +// Constants.CONTENT_TYPES.APPLICATION_X_WWW_FORM_URLENCODED); +// sharedContext.setAccessToken(Utils.extractToken(httpResponse)); +// sharedContext.addStoreValue("accessToken", sharedContext.getAccessToken()); +// +// URL url = Resources.getResource("artifacts/certificates/" + clientCertificatePath); +// String clientCertificate = Resources.toString(url, StandardCharsets.UTF_8); +// sharedContext.addStoreValue("clientCertificate", clientCertificate); +// +// } +} \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/SharedContext.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/SharedContext.java new file mode 100644 index 000000000..402a937a8 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/SharedContext.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration.api; + +import org.apache.http.HttpResponse; +import org.wso2.apk.integration.utils.clients.SimpleHTTPClient; + +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class SharedContext { + + private SimpleHTTPClient httpClient; + private String publisherAccessToken; + private String devportalAccessToken; + private String publisherBasicAuthToken; + private String devportalBasicAuthToken; + private HttpResponse response; + private String responseBody; + private String apiUUID; + private String revisionUUID; + private HashMap valueStore = new HashMap<>(); + private HashMap headers = new HashMap<>(); + + public SimpleHTTPClient getHttpClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { + if (httpClient == null) { + httpClient = new SimpleHTTPClient(); + } + return httpClient; + } + + public String getPublisherAccessToken() { + + return publisherAccessToken; + } + + public void setPublisherAccessToken(String accessToken) { + + this.publisherAccessToken = accessToken; + } + + public String getDevportalAccessToken() { + + return devportalAccessToken; + } + + public void setDevportalAccessToken(String accessToken) { + + this.devportalAccessToken = accessToken; + } + + public String getPublisherBasicAuthToken() { + + return publisherBasicAuthToken; + } + + public void setPublisherBasicAuthToken(String basicAuthToken) { + + this.publisherBasicAuthToken = basicAuthToken; + } + + public String getDevportalBasicAuthToken() { + + return devportalBasicAuthToken; + } + + public void setDevportalBasicAuthToken(String basicAuthToken) { + + this.devportalBasicAuthToken = basicAuthToken; + } + + public HttpResponse getResponse() { + + return response; + } + + public void setResponse(HttpResponse response) { + + this.response = response; + } + + public Object getStoreValue(String key) { + return valueStore.get(key); + } + + public void addStoreValue(String key, Object value) { + valueStore.put(key, value); + } + + public Map getValueStore() { + return Collections.unmodifiableMap(valueStore); + } + + public Map getHeaders() { + return Collections.unmodifiableMap(headers); + } + + public void addHeader(String key, String value) { + headers.put(key, value); + } + + public String getResponseBody() { + + return responseBody; + } + + public void setResponseBody(String responseBody) { + + this.responseBody = responseBody; + } + + public String getApiUUID() { + + return apiUUID; + } + + public void setApiUUID(String apiUUID) { + + this.apiUUID = apiUUID; + } + + public String getRevisionUUID() { + + return revisionUUID; + } + + public void setRevisionUUID(String revisionUUID) { + + this.revisionUUID = revisionUUID; + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Constants.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Constants.java new file mode 100644 index 000000000..d2341bc3a --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Constants.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration.utils; + +public class Constants { + + public static final String DEFAULT_IDP_HOST = "am.wso2.com"; + public static final String DEFAULT_API_HOST = "am.wso2.com"; + public static final String DEFAULT_GW_PORT = "9443"; + public static final String DEFAULT_TOKEN_EP = "oauth2/token"; + public static final String DEFAULT_DCR_EP = "client-registration/v0.17/register"; + public static final String DEFAULT_API_CONFIGURATOR = "api/configurator/1.0.0/"; + public static final String DEFAULT_API_DEPLOYER = "api/am/publisher/v4/"; + public static final String ACCESS_TOKEN = "accessToken"; + public static final String EMPTY_STRING = ""; + public static final String API_CREATE_SCOPE = "apk:api_create"; + public static final String SPACE_STRING = " "; + public static final String SUBSCRIPTION_BASIC_AUTH_TOKEN = + "Basic NDVmMWM1YzgtYTkyZS0xMWVkLWFmYTEtMDI0MmFjMTIwMDAyOjRmYmQ2MmVjLWE5MmUtMTFlZC1hZmExLTAyNDJhYzEyMDAwMg=="; + + public class REQUEST_HEADERS { + + public static final String HOST = "Host"; + public static final String AUTHORIZATION = "Authorization"; + public static final String CONTENT_TYPE = "Content-Type"; + } + + public class CONTENT_TYPES { + + public static final String APPLICATION_JSON = "application/json"; + public static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; + + public static final String MULTIPART_FORM_DATA = "multipart/form-data"; + + public static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; + + public static final String APPLICATION_ZIP = "application/zip"; + + public static final String TEXT_PLAIN = "text/plain"; + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/MultipartFilePart.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/MultipartFilePart.java new file mode 100644 index 000000000..808ecd83f --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/MultipartFilePart.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration.utils; + +import java.io.File; + +public class MultipartFilePart { + + private String name; + private File file; + + public MultipartFilePart(String name, File file) { + + this.name = name; + this.file = file; + } + + public String getName() { + + return name; + } + + public File getFile() { + + return file; + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Utils.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Utils.java new file mode 100644 index 000000000..0023c1ea1 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Utils.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2023, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration.utils; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.entity.ContentType; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +public class Utils { + + public static String getConfigGeneratorURL() { + + return "https://" + Constants.DEFAULT_API_HOST + ":" + Constants.DEFAULT_GW_PORT + "/" + + Constants.DEFAULT_API_CONFIGURATOR + "apis/generate-configuration"; + } + + public static String getDCREndpointURL() { + + return "https://" + Constants.DEFAULT_IDP_HOST + ":" + Constants.DEFAULT_GW_PORT + "/" + + Constants.DEFAULT_DCR_EP; + } + + public static String getTokenEndpointURL() { + + return "https://" + Constants.DEFAULT_IDP_HOST + ":" + Constants.DEFAULT_GW_PORT + "/" + + Constants.DEFAULT_TOKEN_EP; + } + + public static String getAPIDeployerURL() { + + return "https://" + Constants.DEFAULT_API_HOST + ":" + Constants.DEFAULT_GW_PORT + "/" + + Constants.DEFAULT_API_DEPLOYER + "apis/deploy"; + } + + public static String getImportAPIURL() { + + return "https://" + Constants.DEFAULT_API_HOST + ":" + Constants.DEFAULT_GW_PORT + "/" + + Constants.DEFAULT_API_DEPLOYER + "apis/import-openapi"; + } + + public static String getAPIRevisionURL(String apiUUID) { + + return "https://" + Constants.DEFAULT_API_HOST + ":" + Constants.DEFAULT_GW_PORT + "/" + + Constants.DEFAULT_API_DEPLOYER + "apis/" + apiUUID + "/revisions"; + } + + public static String getAPIRevisionDeploymentURL(String apiUUID, String revisionId) { + + return "https://" + Constants.DEFAULT_API_HOST + ":" + Constants.DEFAULT_GW_PORT + "/" + + Constants.DEFAULT_API_DEPLOYER + "apis/" + apiUUID + "/deploy-revision?revisionId=" + revisionId; + } + + public static String getAPIUnDeployerURL() { + + return "https://" + Constants.DEFAULT_API_HOST + ":" + Constants.DEFAULT_GW_PORT + "/" + + Constants.DEFAULT_API_DEPLOYER + "apis/undeploy"; + } + + public static String extractID(String payload) throws IOException { + + JSONParser parser = new JSONParser(); + try { + // Parse the JSON string + JSONObject jsonObject = (JSONObject) parser.parse(payload); + + // Get the value of the "id" attribute + String idValue = (String) jsonObject.get("id"); + return idValue; + } catch (ParseException e) { + throw new IOException("Error while parsing the JSON payload: " + e.getMessage()); + } + } + + public static String extractToken(HttpResponse response) throws IOException { + + int responseCode = response.getStatusLine().getStatusCode(); + + HttpEntity entity = response.getEntity(); + Charset charset = ContentType.getOrDefault(entity).getCharset(); + if (charset == null) { + charset = StandardCharsets.UTF_8; + } + + BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), charset)); + String inputLine; + StringBuilder stringBuilder = new StringBuilder(); + + while ((inputLine = reader.readLine()) != null) { + stringBuilder.append(inputLine); + } + + if (responseCode != HttpStatus.SC_OK) { + throw new IOException("Error while accessing the Token URL. " + + response.getStatusLine()); + } + + JsonParser parser = new JsonParser(); + JsonObject jsonResponse = (JsonObject) parser.parse(stringBuilder.toString()); + if (jsonResponse.has("access_token")) { + return jsonResponse.get("access_token").getAsString(); + } + throw new IOException("Missing key [access_token] in the response from the OAuth server"); + } + + public static String extractBasicToken(HttpResponse response) throws IOException { + + int responseCode = response.getStatusLine().getStatusCode(); + String clientId = null; + String clientSecret = null; + + HttpEntity entity = response.getEntity(); + Charset charset = ContentType.getOrDefault(entity).getCharset(); + if (charset == null) { + charset = StandardCharsets.UTF_8; + } + + BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), charset)); + String inputLine; + StringBuilder stringBuilder = new StringBuilder(); + + while ((inputLine = reader.readLine()) != null) { + stringBuilder.append(inputLine); + } + + if (responseCode != HttpStatus.SC_OK) { + throw new IOException("Error while accessing the Token URL. " + + response.getStatusLine()); + } + + JsonParser parser = new JsonParser(); + JsonObject jsonResponse = (JsonObject) parser.parse(stringBuilder.toString()); + if (jsonResponse.has("clientId")) { + clientId = jsonResponse.get("clientId").getAsString(); + } + if (jsonResponse.has("clientSecret")) { + clientSecret = jsonResponse.get("clientSecret").getAsString(); + } + if (clientId != null && clientSecret != null) { + // base64 encode the clientId and clientSecret + return Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()); + + } + throw new IOException("Missing key [access_token] in the response from the OAuth server"); + } + + public static String resolveVariables(String input, Map valueStore) { + // Define the pattern to match variables like ${variableName} + Pattern pattern = Pattern.compile("\\$\\{([^}]*)\\}"); + Matcher matcher = pattern.matcher(input); + StringBuffer resolvedString = new StringBuffer(); + + while (matcher.find()) { + String variableName = matcher.group(1); + String variableValue = valueStore.get(variableName).toString(); + + // Replace the variable with its value from the value store if it exists + // Otherwise, keep the variable placeholder as is in the string + String replacement = (variableValue != null) ? variableValue : matcher.group(); + matcher.appendReplacement(resolvedString, Matcher.quoteReplacement(replacement)); + } + + matcher.appendTail(resolvedString); + return resolvedString.toString(); + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleHTTPClient.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleHTTPClient.java new file mode 100644 index 000000000..4a3595646 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleHTTPClient.java @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2023, WSO2 LLC (http://www.wso2.com). + * + * WSO2 LLC licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wso2.apk.integration.utils.clients; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpHeaders; +import javax.net.ssl.TrustManager; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpOptions; +import org.apache.http.client.methods.HttpPatch; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.conn.HttpClientConnectionManager; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustAllStrategy; +import org.apache.http.entity.ContentProducer; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.EntityTemplate; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContexts; +import org.wso2.apk.integration.utils.MultipartFilePart; +import org.wso2.apk.integration.utils.exceptions.TimeoutException; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.GZIPOutputStream; +import javax.net.ssl.SSLContext; +import javax.net.ssl.X509TrustManager; + +public class SimpleHTTPClient { + + protected Log log = LogFactory.getLog(getClass()); + private CloseableHttpClient client; + private HttpUriRequest lastRequest; + private static final int EVENTUAL_SUCCESS_RESPONSE_TIMEOUT_IN_SECONDS = 10; + + public SimpleHTTPClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { + +// final SSLContext sslcontext = SSLContexts.custom() +// .loadTrustMaterial(null, new TrustAllStrategy()) +// .build(); +// +// final SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslcontext); +// this.client = HttpClients.custom() +// .setSSLSocketFactory(csf) +// .evictExpiredConnections() +// .setMaxConnPerRoute(100) +// .setMaxConnTotal(1000) +// .build(); + + // Create SSL context that trusts all certificates + SSLContext sslContext = createAcceptAllSSLContext(); + + // Create a socket factory with custom SSL context and hostname verifier that accepts all hostnames + SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, + NoopHostnameVerifier.INSTANCE); + + // Create HttpClient with custom SSL socket factory + this.client = HttpClientBuilder.create().setSSLSocketFactory(sslSocketFactory).build(); + this.lastRequest = null; + } + + private SSLContext createAcceptAllSSLContext() throws NoSuchAlgorithmException, KeyManagementException { + // Create a TrustManager that trusts all certificates + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + } + }; + + // Create SSL context with the TrustManager that trusts all certificates + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + return sslContext; + } + + /** + * Function to extract response body as a string + * + * @param response org.apache.http.HttpResponse object containing response entity body + * @return returns the response entity body as a string + * @throws IOException + */ + public static String responseEntityBodyToString(HttpResponse response) throws IOException { + + if (response != null && response.getEntity() != null) { + try (InputStream inputStreamContent = response.getEntity().getContent()) { + return IOUtils.toString(inputStreamContent); + } + } + return null; + } + + /** + * Send a HTTP GET request to the specified URL + * + * @param url Target endpoint URL + * @param headers Any HTTP headers that should be added to the request + * @return Returned HTTP response + * @throws IOException If an error occurs while making the invocation + */ + public HttpResponse doGet(String url, Map headers) throws IOException { + + HttpUriRequest request = new HttpGet(url); + setHeaders(headers, request); + this.lastRequest = request; + return client.execute(request); + } + + /** + * Send a HTTP POST request to the specified URL + * + * @param url Target endpoint URL + * @param headers Any HTTP headers that should be added to the request + * @param payload Content payload that should be sent + * @param contentType Content-type of the request + * @return Returned HTTP response + * @throws IOException If an error occurs while making the invocation + */ + public HttpResponse doPost(String url, final Map headers, final String payload, String contentType) + throws IOException { + + HttpUriRequest request = new HttpPost(url); + setHeaders(headers, request); + HttpEntityEnclosingRequest entityEncReq = (HttpEntityEnclosingRequest) request; + final boolean zip = headers != null && "gzip".equals(headers.get(HttpHeaders.CONTENT_ENCODING)); + + EntityTemplate ent = new EntityTemplate(new ContentProducer() { + public void writeTo(OutputStream outputStream) throws IOException { + + OutputStream out = outputStream; + if (zip) { + out = new GZIPOutputStream(outputStream); + } + out.write(payload.getBytes()); + out.flush(); + out.close(); + } + }); + if (contentType != null) { + ent.setContentType(contentType); + } else { + ent.setContentType(MediaType.JSON.getValue()); + } + if (zip) { + ent.setContentEncoding("gzip"); + } + entityEncReq.setEntity(ent); + this.lastRequest = request; + log.info("Request: " + request); + return client.execute(request); + } + + /** + * Send a HTTP POST with multipart request to the specified URL + * + * @param url Target endpoint URL + * @return Returned HTTP response + * @throws IOException If an error occurs while making the invocation + */ + public HttpResponse doPostWithMultipart(String url, HttpEntity httpEntity) + throws IOException { + + return doPostWithMultipart(url, httpEntity, new HashMap<>()); + } + + public HttpResponse doPostWithMultipart(String url, HttpEntity httpEntity, Map header) + throws IOException { + + HttpPost request = new HttpPost(url); + for (String headerKey : header.keySet()) { + request.addHeader(headerKey, header.get(headerKey)); + } + request.setEntity(httpEntity); + this.lastRequest = request; + return client.execute(request); + } + + public HttpResponse doPostWithMultipart(String url, List fileParts, Map header) + throws IOException { + + MultipartEntityBuilder entitybuilder = MultipartEntityBuilder.create(); + entitybuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + for (MultipartFilePart filePart : fileParts) { + entitybuilder.addPart(filePart.getName(), new FileBody(filePart.getFile())); + } + HttpPost request = new HttpPost(url); + for (String headerKey : header.keySet()) { + request.addHeader(headerKey, header.get(headerKey)); + } + HttpEntity mutiPartHttpEntity = entitybuilder.build(); + request.setEntity(mutiPartHttpEntity); + this.lastRequest = request; + return client.execute(request); + } + + public HttpResponse doPutWithMultipart(String url, File file, Map header) + throws IOException { + + MultipartEntityBuilder entitybuilder = MultipartEntityBuilder.create(); + entitybuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + entitybuilder.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, file.getName()); + HttpPut request = new HttpPut(url); + for (String headerKey : header.keySet()) { + request.addHeader(headerKey, header.get(headerKey)); + } + HttpEntity mutiPartHttpEntity = entitybuilder.build(); + request.setEntity(mutiPartHttpEntity); + this.lastRequest = request; + return client.execute(request); + } + + /** + * Extracts the payload from a HTTP response. For a given HttpResponse object, this + * method can be called only once. + * + * @param response HttpResponse instance to be extracted + * @return Content payload + * @throws IOException If an error occurs while reading from the response + */ + public String getResponsePayload(HttpResponse response) throws IOException { + + if (response.getEntity() != null) { + InputStream in = response.getEntity().getContent(); + int length; + byte[] tmp = new byte[2048]; + StringBuilder buffer = new StringBuilder(); + while ((length = in.read(tmp)) != -1) { + buffer.append(new String(tmp, 0, length)); + } + return buffer.toString(); + } + return null; + } + + /** + * Send a HTTP PATCH request to the specified URL + * + * @param url Target endpoint URL + * @param headers Any HTTP headers that should be added to the request + * @param payload Content payload that should be sent + * @param contentType Content-type of the request + * @return Returned HTTP response + * @throws IOException If an error occurs while making the invocation + */ + public HttpResponse doPatch(String url, final Map headers, final String payload, String contentType) + throws IOException { + + HttpUriRequest request = new HttpPatch(url); + setHeaders(headers, request); + HttpEntityEnclosingRequest entityEncReq = (HttpEntityEnclosingRequest) request; + final boolean zip = headers != null && "gzip".equals(headers.get(HttpHeaders.CONTENT_ENCODING)); + + EntityTemplate ent = new EntityTemplate(new ContentProducer() { + public void writeTo(OutputStream outputStream) throws IOException { + + OutputStream out = outputStream; + if (zip) { + out = new GZIPOutputStream(outputStream); + } + out.write(payload.getBytes()); + out.flush(); + out.close(); + } + }); + ent.setContentType(contentType); + if (zip) { + ent.setContentEncoding("gzip"); + } + entityEncReq.setEntity(ent); + return client.execute(request); + } + + /** + * Send a HTTP OPTIONS request to the specified URL + * + * @param url Target endpoint URL + * @param headers Any HTTP headers that should be added to the request + * @param payload Content payload that should be sent + * @param contentType Content-type of the request + * @return Returned HTTP response + * @throws IOException If an error occurs while making the invocation + */ + public HttpResponse doOptions(String url, final Map headers, final String payload, + String contentType) throws IOException { + + HttpUriRequest request = new HttpOptions(url); + setHeaders(headers, request); + if (payload != null) { + HttpEntityEnclosingRequest entityEncReq = (HttpEntityEnclosingRequest) request; + final boolean zip = headers != null && "gzip".equals(headers.get(HttpHeaders.CONTENT_ENCODING)); + + EntityTemplate ent = new EntityTemplate(new ContentProducer() { + public void writeTo(OutputStream outputStream) throws IOException { + + OutputStream out = outputStream; + if (zip) { + out = new GZIPOutputStream(outputStream); + } + out.write(payload.getBytes()); + out.flush(); + out.close(); + } + }); + ent.setContentType(contentType); + if (zip) { + ent.setContentEncoding("gzip"); + } + entityEncReq.setEntity(ent); + } + return client.execute(request); + } + + /** + * Send a HTTP Head request to the specified URL + * + * @param url Target endpoint URL + * @param headers Any HTTP headers that should be added to the request + * @return Returned HTTP response + * @throws IOException If an error occurs while making the invocation + */ + public HttpResponse doHead(String url, final Map headers) throws IOException { + + HttpUriRequest request = new HttpHead(url); + setHeaders(headers, request); + return client.execute(request); + } + + /** + * Send a HTTP DELETE request to the specified URL + * + * @param url Target endpoint URL + * @param headers Any HTTP headers that should be added to the request + * @return Returned HTTP response + * @throws IOException If an error occurs while making the invocation + */ + public HttpResponse doDelete(String url, final Map headers) throws IOException { + + HttpUriRequest request = new HttpDelete(url); + setHeaders(headers, request); + this.lastRequest = lastRequest; + return client.execute(request); + } + + /** + * Send a HTTP PUT request to the specified URL + * + * @param url Target endpoint URL + * @param headers Any HTTP headers that should be added to the request + * @param payload Content payload that should be sent + * @param contentType Content-type of the request + * @return Returned HTTP response + * @throws IOException If an error occurs while making the invocation + */ + public HttpResponse doPut(String url, final Map headers, final String payload, String contentType) + throws IOException { + + HttpUriRequest request = new HttpPut(url); + setHeaders(headers, request); + HttpEntityEnclosingRequest entityEncReq = (HttpEntityEnclosingRequest) request; + final boolean zip = headers != null && "gzip".equals(headers.get(HttpHeaders.CONTENT_ENCODING)); + + EntityTemplate ent = new EntityTemplate(new ContentProducer() { + public void writeTo(OutputStream outputStream) throws IOException { + + OutputStream out = outputStream; + if (zip) { + out = new GZIPOutputStream(outputStream); + } + out.write(payload.getBytes()); + out.flush(); + out.close(); + } + }); + ent.setContentType(contentType); + if (zip) { + ent.setContentEncoding("gzip"); + } + entityEncReq.setEntity(ent); + this.lastRequest = lastRequest; + return client.execute(request); + } + + private void setHeaders(Map headers, HttpUriRequest request) { + + if (headers != null && headers.size() > 0) { + for (Map.Entry header : headers.entrySet()) { + request.setHeader(header.getKey(), header.getValue()); + } + } + } + + public HttpResponse executeLastRequestForEventualConsistentResponse(int successResponseCode, + List nonAcceptableCodes) throws IOException, InterruptedException { + + int counter = 1; + int responseCode = -1; + String lastResponseBody = null; + while (counter < EVENTUAL_SUCCESS_RESPONSE_TIMEOUT_IN_SECONDS) { + counter++; + Thread.sleep(1000); + HttpResponse httpResponse = getClient().execute(lastRequest); + responseCode = httpResponse.getStatusLine().getStatusCode(); + if (responseCode == successResponseCode || nonAcceptableCodes.contains(responseCode)) { + return httpResponse; + } else { + if (counter == EVENTUAL_SUCCESS_RESPONSE_TIMEOUT_IN_SECONDS) { + lastResponseBody = responseEntityBodyToString(httpResponse); + } + ((CloseableHttpResponse) httpResponse).close(); + } + } + throw new TimeoutException("Could not receive expected response within time. Last received code: " + + responseCode + ", last response body: " + lastResponseBody); + } + + private HttpClient getClient() { + + final SSLContext sslcontext; + try { + sslcontext = SSLContexts.custom() + .loadTrustMaterial(null, new TrustAllStrategy()) + .build(); + } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { + throw new RuntimeException(e); + } + final SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslcontext); + + return HttpClients.custom() + .setSSLSocketFactory(csf) + .evictExpiredConnections() + .build(); + } +} + +enum MediaType { + JSON("application/json"), + XML("application/xml"), + FORM("application/x-www-form-urlencoded"); + // Add more Content-Type values as needed + + private final String value; + + MediaType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/exceptions/TimeoutException.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/exceptions/TimeoutException.java new file mode 100644 index 000000000..3835962a6 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/exceptions/TimeoutException.java @@ -0,0 +1,8 @@ +package org.wso2.apk.integration.utils.exceptions; + +public class TimeoutException extends RuntimeException { + + public TimeoutException(String s) { + super(s); + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/definitions/basic_auth_api.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/definitions/basic_auth_api.json new file mode 100644 index 000000000..f6a997e53 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/definitions/basic_auth_api.json @@ -0,0 +1,225 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "EmployeeServiceAPI", + "version": "3.14" + }, + "servers": [ + { + "url": "http://backend:80/anything", + "description": "Server URL", + "variables": {} + } + ], + "paths": { + "/employee": { + "get": { + "tags": [ + "employee-controller" + ], + "operationId": "getEmployees", + "parameters": [ + { + "name": "id", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "default response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Employee" + } + } + } + } + } + } + }, + + "post": { + "tags": [ + "employee-controller" + ], + "operationId": "addEmployee", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Employee" + } + } + } + }, + "responses": { + "200": { + "description": "default response", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/Employee" + } + } + } + } + } + } + }, + "/get": { + "get": { + "tags": [ + "employee-controller" + ], + "operationId": "getEmployees", + "parameters": [ + { + "name": "id", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "default response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Employee" + } + } + } + } + } + } + } + }, + "/post": { + "post": { + "tags": [ + "employee-controller" + ], + "operationId": "getEmployees", + "parameters": [ + { + "name": "id", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "default response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Employee" + } + } + } + } + } + } + } + }, + "/employee/{employeeId}": { + "put": { + "tags": [ + "employee-controller" + ], + "operationId": "editEmployee", + "parameters": [ + { + "name": "employeeId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "default response", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/Employee" + } + } + } + } + } + }, + "delete": { + "tags": [ + "employee-controller" + ], + "operationId": "deleteEmployee", + "parameters": [ + { + "name": "employeeId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "default response", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/Employee" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Employee": { + "type": "object", + "properties": { + "empId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "designation": { + "type": "string" + }, + "salary": { + "type": "number", + "format": "double" + } + } + } + } + } +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/jwtcert/idp1.jks b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/jwtcert/idp1.jks new file mode 100644 index 000000000..8ce2101d8 Binary files /dev/null and b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/jwtcert/idp1.jks differ diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api1.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api1.json new file mode 100644 index 000000000..289b5f5d6 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api1.json @@ -0,0 +1,19 @@ +{ + "name":"SwaggerPetstore", + "version":"1.0.0", + "context":"/petstore", + "gatewayType":"wso2/apk", + "endpointConfig":{ + "endpoint_type":"http", + "sandbox_endpoints":{ + "url":"https://petstore3.swagger.io/api/v3" + }, + "production_endpoints": { + "url":"https://petstore3.swagger.io/api/v3" + } + }, + "policies": [ + "Gold", + "Unlimited" + ] +} \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/testng.xml b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/testng.xml new file mode 100644 index 000000000..feff098cf --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/testng.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Deployment.feature b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Deployment.feature new file mode 100644 index 000000000..45002e28f --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Deployment.feature @@ -0,0 +1,31 @@ +Feature: API Deployment + Scenario: Import an API + Given The system is ready + And I have a DCR application for Publisher + And I have a valid Publisher access token + When I use the Payload file "artifacts/payloads/api1.json" + And I use the OAS URL "https://petstore3.swagger.io/api/v3/openapi.json" + And make the import API Creation request + Then the response status code should be 201 + And the response body should contain "SwaggerPetstore" + And make the API Revision Deployment request + Then the response status code should be 201 + +# Scenario: Deploying an API +# Given The system is ready +# And I have a valid subscription +# When I use the APK Conf file "artifacts/apk-confs/cors_API.apk-conf" +# And the definition file "artifacts/definitions/cors_api.yaml" +# And make the API deployment request +# Then the response status code should be 200 +# And the response body should contain "cors-api-adff3dbc-2787-11ee-be56-0242ac120002" +# +# Scenario Outline: Undeploy an API +# Given The system is ready +# And I have a valid subscription +# When I undeploy the API whose ID is "" +# Then the response status code should be + +# Examples: +# | apiID | expectedStatusCode | +# | cors-api-adff3dbc-2787-11ee-be56-0242ac120002 | 202 |