From fd61ffba27b5bc39b85b618157f13aeff8acef7d Mon Sep 17 00:00:00 2001 From: "Roy,Sownak" Date: Fri, 9 Feb 2024 09:32:16 +0000 Subject: [PATCH] [corda] New charts as per release 1.0.0 Signed-off-by: Roy,Sownak --- .gitignore | 1 + Dockerfile | 4 + Dockerfile.jdk8 | 10 +- .../charts/besu-genesis/README.md | 2 +- .../charts/besu-genesis/values.yaml | 6 +- .../quorum/configuration/deploy-network.yaml | 2 +- .../delete/vault_secrets/tasks/main.yaml | 1 + platforms/r3-corda/charts/README.md | 142 ++-- .../charts/corda-certs-gen/Chart.yaml | 20 +- .../r3-corda/charts/corda-certs-gen/README.md | 180 ++--- .../corda-certs-gen/templates/_helpers.tpl | 34 +- .../corda-certs-gen/templates/configmap.yaml | 20 - .../templates/job-cleanup.yaml | 51 ++ .../charts/corda-certs-gen/templates/job.yaml | 578 +++++++--------- .../charts/corda-certs-gen/values.yaml | 123 ++-- .../charts/corda-doorman-tls/Chart.yaml | 11 - .../charts/corda-doorman-tls/README.md | 173 ----- .../templates/deployment.yaml | 361 ---------- .../corda-doorman-tls/templates/pvc.yaml | 28 - .../corda-doorman-tls/templates/service.yaml | 70 -- .../charts/corda-doorman-tls/values.yaml | 120 ---- .../r3-corda/charts/corda-doorman/Chart.yaml | 11 - .../r3-corda/charts/corda-doorman/README.md | 171 ----- .../corda-doorman/templates/deployment.yaml | 275 -------- .../charts/corda-doorman/templates/pvc.yaml | 28 - .../corda-doorman/templates/service.yaml | 42 -- .../r3-corda/charts/corda-doorman/values.yaml | 120 ---- .../charts/corda-h2-addUser/Chart.yaml | 11 - .../corda-h2-addUser/templates/job.yaml | 169 ----- .../charts/corda-h2-addUser/values.yaml | 184 ----- .../corda-h2-password-change/Chart.yaml | 11 - .../templates/job.yaml | 158 ----- .../corda-h2-password-change/values.yaml | 184 ----- .../r3-corda/charts/corda-h2/.helmignore | 21 - platforms/r3-corda/charts/corda-h2/Chart.yaml | 11 - platforms/r3-corda/charts/corda-h2/README.md | 174 ----- .../charts/corda-h2/templates/deployment.yaml | 71 -- .../charts/corda-h2/templates/pvc.yaml | 27 - .../charts/corda-h2/templates/service.yaml | 40 -- .../r3-corda/charts/corda-h2/values.yaml | 63 -- .../r3-corda/charts/corda-init/Chart.yaml | 25 + .../r3-corda/charts/corda-init/README.md | 96 +++ .../files/openssl.conf | 0 .../charts/corda-init/requirements.yaml | 11 + .../charts/corda-init/templates/_helpers.tpl | 29 + .../corda-init/templates/configmap.yaml | 53 ++ .../r3-corda/charts/corda-init/values.yaml | 35 + .../charts/corda-mongodb-tls/Chart.yaml | 11 - .../charts/corda-mongodb-tls/README.md | 158 ----- .../templates/deployment.yaml | 184 ----- .../corda-mongodb-tls/templates/pvc.yaml | 26 - .../corda-mongodb-tls/templates/service.yaml | 31 - .../charts/corda-mongodb-tls/values.yaml | 38 -- .../r3-corda/charts/corda-mongodb/Chart.yaml | 11 - .../r3-corda/charts/corda-mongodb/README.md | 158 ----- .../corda-mongodb/templates/deployment.yaml | 117 ---- .../charts/corda-mongodb/templates/pvc.yaml | 25 - .../corda-mongodb/templates/service.yaml | 30 - .../r3-corda/charts/corda-mongodb/values.yaml | 38 -- .../charts/corda-network-service/Chart.yaml | 25 + .../charts/corda-network-service/README.md | 146 ++++ .../corda-network-service/requirements.yaml | 14 + .../templates/_helpers.tpl | 29 + .../templates/hooks-pre-delete.yaml | 71 ++ .../templates/hooks-pre-install.yaml | 226 +++++++ .../templates/service.yaml | 171 +++++ .../templates/statefulset-doorman.yaml | 138 ++++ .../templates/statefulset-mongodb.yaml | 136 ++++ .../templates/statefulset-nms.yaml | 142 ++++ .../charts/corda-network-service/values.yaml | 82 +++ .../charts/corda-networkmap-tls/Chart.yaml | 11 - .../charts/corda-networkmap-tls/README.md | 178 ----- .../templates/deployment.yaml | 365 ---------- .../templates/service.yaml | 70 -- .../templates/volume.yaml | 24 - .../charts/corda-networkmap-tls/values.yaml | 90 --- .../charts/corda-networkmap/Chart.yaml | 11 - .../charts/corda-networkmap/README.md | 179 ----- .../templates/deployment.yaml | 312 --------- .../corda-networkmap/templates/service.yaml | 43 -- .../corda-networkmap/templates/volume.yaml | 42 -- .../charts/corda-networkmap/values.yaml | 87 --- .../Chart.yaml | 11 - .../corda-node-initial-registration/README.md | 231 ------- .../templates/_helpers.tpl | 5 - .../templates/job.yaml | 545 --------------- .../values.yaml | 232 ------- .../r3-corda/charts/corda-node/Chart.yaml | 20 +- .../r3-corda/charts/corda-node/README.md | 338 ++++------ .../charts/corda-node/requirements.yaml | 14 + .../charts/corda-node/templates/_helpers.tpl | 54 +- .../corda-node/templates/deployment.yaml | 539 --------------- .../templates/hooks-pre-delete.yaml | 71 ++ .../templates/hooks-pre-install.yaml | 165 +++++ .../charts/corda-node/templates/pvc.yaml | 29 - .../charts/corda-node/templates/service.yaml | 146 ++-- .../corda-node/templates/statefulset-db.yaml | 85 +++ .../templates/statefulset-node.yaml | 632 ++++++++++++++++++ .../r3-corda/charts/corda-node/values.yaml | 335 +++------- .../Chart.yaml | 11 - .../README.md | 220 ------ .../templates/_helpers.tpl | 5 - .../templates/job.yaml | 544 --------------- .../values.yaml | 204 ------ .../r3-corda/charts/corda-notary/Chart.yaml | 11 - .../r3-corda/charts/corda-notary/README.md | 249 ------- .../corda-notary/templates/_helpers.tpl | 5 - .../corda-notary/templates/deployment.yaml | 617 ----------------- .../charts/corda-notary/templates/pvc.yaml | 29 - .../corda-notary/templates/service.yaml | 93 --- .../r3-corda/charts/corda-notary/values.yaml | 247 ------- .../values/noproxy-and-novault/init.yaml | 9 + .../noproxy-and-novault/network-service.yaml | 37 + .../values/noproxy-and-novault/node.yaml | 33 + .../values/noproxy-and-novault/notary.yaml | 36 + .../values/proxy-and-vault/init-sec.yaml | 18 + .../charts/values/proxy-and-vault/init.yaml | 14 + .../proxy-and-vault/network-service.yaml | 44 ++ .../charts/values/proxy-and-vault/node.yaml | 39 ++ .../charts/values/proxy-and-vault/notary.yaml | 42 ++ .../k8_component/templates/create_mongodb.tpl | 4 +- 121 files changed, 3600 insertions(+), 9739 deletions(-) delete mode 100644 platforms/r3-corda/charts/corda-certs-gen/templates/configmap.yaml create mode 100644 platforms/r3-corda/charts/corda-certs-gen/templates/job-cleanup.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman-tls/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman-tls/README.md delete mode 100644 platforms/r3-corda/charts/corda-doorman-tls/templates/deployment.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman-tls/templates/pvc.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman-tls/templates/service.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman-tls/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman/README.md delete mode 100644 platforms/r3-corda/charts/corda-doorman/templates/deployment.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman/templates/pvc.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman/templates/service.yaml delete mode 100644 platforms/r3-corda/charts/corda-doorman/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2-addUser/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2-addUser/templates/job.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2-addUser/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2-password-change/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2-password-change/templates/job.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2-password-change/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2/.helmignore delete mode 100644 platforms/r3-corda/charts/corda-h2/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2/README.md delete mode 100644 platforms/r3-corda/charts/corda-h2/templates/deployment.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2/templates/pvc.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2/templates/service.yaml delete mode 100644 platforms/r3-corda/charts/corda-h2/values.yaml create mode 100644 platforms/r3-corda/charts/corda-init/Chart.yaml create mode 100644 platforms/r3-corda/charts/corda-init/README.md rename platforms/r3-corda/charts/{corda-certs-gen => corda-init}/files/openssl.conf (100%) create mode 100644 platforms/r3-corda/charts/corda-init/requirements.yaml create mode 100644 platforms/r3-corda/charts/corda-init/templates/_helpers.tpl create mode 100644 platforms/r3-corda/charts/corda-init/templates/configmap.yaml create mode 100644 platforms/r3-corda/charts/corda-init/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb-tls/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb-tls/README.md delete mode 100644 platforms/r3-corda/charts/corda-mongodb-tls/templates/deployment.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb-tls/templates/pvc.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb-tls/templates/service.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb-tls/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb/README.md delete mode 100644 platforms/r3-corda/charts/corda-mongodb/templates/deployment.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb/templates/pvc.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb/templates/service.yaml delete mode 100644 platforms/r3-corda/charts/corda-mongodb/values.yaml create mode 100644 platforms/r3-corda/charts/corda-network-service/Chart.yaml create mode 100644 platforms/r3-corda/charts/corda-network-service/README.md create mode 100644 platforms/r3-corda/charts/corda-network-service/requirements.yaml create mode 100644 platforms/r3-corda/charts/corda-network-service/templates/_helpers.tpl create mode 100644 platforms/r3-corda/charts/corda-network-service/templates/hooks-pre-delete.yaml create mode 100644 platforms/r3-corda/charts/corda-network-service/templates/hooks-pre-install.yaml create mode 100644 platforms/r3-corda/charts/corda-network-service/templates/service.yaml create mode 100644 platforms/r3-corda/charts/corda-network-service/templates/statefulset-doorman.yaml create mode 100644 platforms/r3-corda/charts/corda-network-service/templates/statefulset-mongodb.yaml create mode 100644 platforms/r3-corda/charts/corda-network-service/templates/statefulset-nms.yaml create mode 100644 platforms/r3-corda/charts/corda-network-service/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap-tls/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap-tls/README.md delete mode 100644 platforms/r3-corda/charts/corda-networkmap-tls/templates/deployment.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap-tls/templates/service.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap-tls/templates/volume.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap-tls/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap/README.md delete mode 100644 platforms/r3-corda/charts/corda-networkmap/templates/deployment.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap/templates/service.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap/templates/volume.yaml delete mode 100644 platforms/r3-corda/charts/corda-networkmap/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-node-initial-registration/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-node-initial-registration/README.md delete mode 100644 platforms/r3-corda/charts/corda-node-initial-registration/templates/_helpers.tpl delete mode 100644 platforms/r3-corda/charts/corda-node-initial-registration/templates/job.yaml delete mode 100644 platforms/r3-corda/charts/corda-node-initial-registration/values.yaml create mode 100644 platforms/r3-corda/charts/corda-node/requirements.yaml delete mode 100644 platforms/r3-corda/charts/corda-node/templates/deployment.yaml create mode 100644 platforms/r3-corda/charts/corda-node/templates/hooks-pre-delete.yaml create mode 100644 platforms/r3-corda/charts/corda-node/templates/hooks-pre-install.yaml delete mode 100644 platforms/r3-corda/charts/corda-node/templates/pvc.yaml create mode 100644 platforms/r3-corda/charts/corda-node/templates/statefulset-db.yaml create mode 100644 platforms/r3-corda/charts/corda-node/templates/statefulset-node.yaml delete mode 100644 platforms/r3-corda/charts/corda-notary-initial-registration/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-notary-initial-registration/README.md delete mode 100644 platforms/r3-corda/charts/corda-notary-initial-registration/templates/_helpers.tpl delete mode 100644 platforms/r3-corda/charts/corda-notary-initial-registration/templates/job.yaml delete mode 100644 platforms/r3-corda/charts/corda-notary-initial-registration/values.yaml delete mode 100644 platforms/r3-corda/charts/corda-notary/Chart.yaml delete mode 100644 platforms/r3-corda/charts/corda-notary/README.md delete mode 100644 platforms/r3-corda/charts/corda-notary/templates/_helpers.tpl delete mode 100644 platforms/r3-corda/charts/corda-notary/templates/deployment.yaml delete mode 100644 platforms/r3-corda/charts/corda-notary/templates/pvc.yaml delete mode 100644 platforms/r3-corda/charts/corda-notary/templates/service.yaml delete mode 100644 platforms/r3-corda/charts/corda-notary/values.yaml create mode 100644 platforms/r3-corda/charts/values/noproxy-and-novault/init.yaml create mode 100644 platforms/r3-corda/charts/values/noproxy-and-novault/network-service.yaml create mode 100644 platforms/r3-corda/charts/values/noproxy-and-novault/node.yaml create mode 100644 platforms/r3-corda/charts/values/noproxy-and-novault/notary.yaml create mode 100644 platforms/r3-corda/charts/values/proxy-and-vault/init-sec.yaml create mode 100644 platforms/r3-corda/charts/values/proxy-and-vault/init.yaml create mode 100644 platforms/r3-corda/charts/values/proxy-and-vault/network-service.yaml create mode 100644 platforms/r3-corda/charts/values/proxy-and-vault/node.yaml create mode 100644 platforms/r3-corda/charts/values/proxy-and-vault/notary.yaml diff --git a/.gitignore b/.gitignore index 7216c3812de..f11044ec844 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,5 @@ *_custom.tpl **/charts/*.tgz **/files/*.json +**/files/*.crt requirements.lock diff --git a/Dockerfile b/Dockerfile index efd13264b1e..5041ac0ab6b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,6 +50,10 @@ RUN rm /etc/apt/apt.conf.d/docker-clean RUN mkdir /etc/ansible/ RUN /bin/echo -e "[ansible_provisioners:children]\nlocal\n[local]\nlocalhost ansible_connection=local" > /etc/ansible/hosts +RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.27.0/bin/linux/amd64/kubectl +RUN chmod +x ./kubectl +RUN mv ./kubectl /usr/local/bin + # Install krew for bevel-operator-fabric RUN (set -x; cd "$(mktemp -d)" && \ OS="$(uname | tr '[:upper:]' '[:lower:]')" && \ diff --git a/Dockerfile.jdk8 b/Dockerfile.jdk8 index 15ff3426b98..0520a4797de 100644 --- a/Dockerfile.jdk8 +++ b/Dockerfile.jdk8 @@ -3,13 +3,11 @@ # # SPDX-License-Identifier: Apache-2.0 ############################################################################################## - # USAGE: # docker build . -t bevel-build # docker run -v $(pwd):/home/bevel/ bevel-build FROM ubuntu:20.04 - # Create working directory WORKDIR /home/ ENV OPENSHIFT_VERSION='0.13.1' @@ -37,13 +35,17 @@ RUN apt-get update && apt-get install -y \ apt-get clean && \ ln -s /usr/bin/python3 /usr/bin/python && \ rm -rf /var/lib/apt/lists/* -RUN npm install -g ajv-cli +RUN npm install -g ajv-cli RUN apt-get update && apt-get install -y python3-venv RUN rm /etc/apt/apt.conf.d/docker-clean RUN mkdir /etc/ansible/ RUN /bin/echo -e "[ansible_provisioners:children]\nlocal\n[local]\nlocalhost ansible_connection=local" > /etc/ansible/hosts +RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.27.0/bin/linux/amd64/kubectl +RUN chmod +x ./kubectl +RUN mv ./kubectl /usr/local/bin + # Copy the provisional script to build container COPY ./run.sh /home COPY ./reset.sh /home @@ -58,6 +60,4 @@ ENV PATH=/root/bin:/root/.local/bin/:$PATH #path to mount the repo VOLUME /home/bevel/ - - CMD ["/home/run.sh"] diff --git a/platforms/hyperledger-besu/charts/besu-genesis/README.md b/platforms/hyperledger-besu/charts/besu-genesis/README.md index 4d599b9030d..bb4f540b78b 100644 --- a/platforms/hyperledger-besu/charts/besu-genesis/README.md +++ b/platforms/hyperledger-besu/charts/besu-genesis/README.md @@ -74,7 +74,7 @@ These parameters are refered to as same in each parent or child chart | `image.pullSecret` | Provide the docker secret name in the namespace | `""` | | `image.pullPolicy` | Pull policy to be used for the Docker images | `IfNotPresent` | -### TLS +### Settings | Name | Description | Default Value | |--------|---------|-------------| diff --git a/platforms/hyperledger-besu/charts/besu-genesis/values.yaml b/platforms/hyperledger-besu/charts/besu-genesis/values.yaml index 352c2355ce5..1aa90bfc651 100644 --- a/platforms/hyperledger-besu/charts/besu-genesis/values.yaml +++ b/platforms/hyperledger-besu/charts/besu-genesis/values.yaml @@ -11,10 +11,10 @@ global: #Provide the service account name which will be created. serviceAccountName: vault-auth cluster: - provider: aws # choose from: minikube | aws - cloudNativeServices: false # 'false' is implemented + provider: aws # choose from: minikube | aws | azure | gcp + cloudNativeServices: false # only 'false' is implemented #Provide the kubernetes host url - #Eg. kubernetesUrl: https://10.3.8.5:6443 + #Eg. kubernetesUrl: https://10.3.8.5:8443 kubernetesUrl: vault: #Provide the type of vault diff --git a/platforms/quorum/configuration/deploy-network.yaml b/platforms/quorum/configuration/deploy-network.yaml index e0e6f9f37f1..84bbb4b5dce 100644 --- a/platforms/quorum/configuration/deploy-network.yaml +++ b/platforms/quorum/configuration/deploy-network.yaml @@ -79,7 +79,7 @@ name: create/certificates/ambassador vars: gitops: "{{ org.gitops }}" - component_auth: "quorum{{ org.name | lower }}" + component_auth: "{{ network.env.type }}{{ org.name | lower }}" component_ns: "{{ org.name | lower }}-quo" charts_dir: "{{ org.gitops.chart_source }}" component_name: "{{ org.name | lower }}-ambassador-certs" diff --git a/platforms/quorum/configuration/roles/delete/vault_secrets/tasks/main.yaml b/platforms/quorum/configuration/roles/delete/vault_secrets/tasks/main.yaml index d3cb8c8ab62..90eb1d90f9e 100644 --- a/platforms/quorum/configuration/roles/delete/vault_secrets/tasks/main.yaml +++ b/platforms/quorum/configuration/roles/delete/vault_secrets/tasks/main.yaml @@ -42,6 +42,7 @@ vault kv delete {{ item.vault.secret_path | default('secretsv2') }}/{{ org_name }}/crypto/{{ peer.name }}/quorum vault kv delete {{ item.vault.secret_path | default('secretsv2') }}/{{ org_name }}/crypto/{{ peer.name }}/certs vault kv delete {{ item.vault.secret_path | default('secretsv2') }}/{{ org_name }}/crypto/genesis + vault kv delete {{ item.vault.secret_path | default('secretsv2') }}/{{ org_name }}/smartContracts/General loop: "{{ services.peers }}" environment: VAULT_ADDR: "{{ item.vault.url }}" diff --git a/platforms/r3-corda/charts/README.md b/platforms/r3-corda/charts/README.md index c7c52b509aa..b0ffc5e77fa 100644 --- a/platforms/r3-corda/charts/README.md +++ b/platforms/r3-corda/charts/README.md @@ -6,51 +6,105 @@ # Charts for R3 Corda components ## About -This folder contains helm charts which are used by the ansible playbooks for the deployment of the R3-Corda components. Each chart folder contain a folder for templates, chart file and the corresponding value file. +This folder contains the helm charts which are used for the deployment of the R3 Corda components. Each helm chart that you can use has the following keys and you need to set them. The `global.cluster.provider` is used as a key for the various cloud features enabled. Also you only need to specify one cloud provider, **not** both if deploying to cloud. As of writing this doc, AWS is fully supported. -## Example Folder Structure ### +```yaml +global: + serviceAccountName: vault-auth + cluster: + provider: aws # choose from: minikube | aws + cloudNativeServices: false # future: set to true to use Cloud Native Services + kubernetesUrl: "https://yourkubernetes.com" # Provide the k8s URL, ignore if not using Hashicorp Vault + vault: + type: hashicorp # choose from hashicorp | kubernetes + network: corda # must be corda for these charts + # Following are necessary only when hashicorp vault is used. + address: http://vault.url:8200 + authPath: supplychain + secretEngine: secretsv2 + secretPrefix: "data/supplychain" + role: vault-role ``` -/corda-doorman -|-- templates -| |--_helpers.tpl -| |-- volumes.yaml -| |-- deployment.yaml -| |-- service.yaml -|-- Chart.yaml -|-- values.yaml + +## Usage + +### Pre-requisites + +- Kubernetes Cluster (either Managed cloud option like EKS or local like minikube) +- Accessible and unsealed Hahsicorp Vault (if using Vault) +- Configured Ambassador AES (if using Ambassador as proxy) +- Update the dependencies + ``` + helm dependency update corda-init + helm dependency update corda-network-service + helm dependency update corda-node + ``` + +### _Without Proxy or Vault_ + +```bash +helm install init ./corda-init --namespace supplychain-ns --create-namespace --values ./values/noproxy-and-novault/init.yaml + +# Install doorman and network-map services +helm install supplychain ./corda-network-service --namespace supplychain-ns --values ./values/noproxy-and-novault/network-service.yaml +# Install a notary service +helm install notary ./corda-node --namespace supplychain-ns --values ./values/noproxy-and-novault/notary.yaml + +``` +### To setup another node in a different namespace + +```bash +# Run init for new namespace +helm install init ./corda-init --namespace manufacturer-ns --create-namespace --values ./values/noproxy-and-novault/init.yaml +# Install a Corda node +helm install manufacturer ./corda-node --namespace manufacturer-ns --values ./values/noproxy-and-novault/node.yaml ``` -## Pre-requisites - - Helm to be installed and configured - -## Charts description ## - -### 1. doorman ### -- This folder contains chart templates and default values for doorman servers. -### 2. doorman-tls ### -- This folder contains chart templates and default values for doorman-tls servers. -### 3. h2 ### -- This folder contains chart templates and default values for creation of h2 database. -### 4. h2-adduser ### -- This folder contains chart templates and default values for adding new user into h2 database. -### 5. h2-password-change ### -- This folder contains chart templates and default values for changing the password for h2 database user. -### 6. mongodb ### -- This folder contains chart templates and default values for mongodb node -### 7. mongodb-tls ### -- This folder contains chart templates and default values for mongodb node with tls=on. -### 8. nms ### -- This folder contains chart templates and default values for nms -### 9. nms-tls ### -- This folder contains chart templates and default values for nms with tls=on. -### 10. node ### -- This folder contains chart templates and default values for node -### 11. node-initial-registration ### -- This folder contains chart templates and default values for registering node with notary -### 12. notary ### -- This folder contains chart templates and default values for notary. -### 13. notary-initial-registration ### -- This folder contains chart templates and default values for registering notary with nms. -### 14. storage ### -- This folder contains chart templates and default values for StorageClass +### _With Ambassador proxy and Vault_ +Replace the `global.vault.address`, `global.cluster.kubernetesUrl` and `global.proxy.externalUrlSuffix` in all the files in `./values/proxy-and-vault/` folder. Also update the `nodeConf.networkMapURL` and `nodeConf.doormanURL` as per your `global.proxy.externalUrlSuffix` of corda-network-service. + +```bash +kubectl create namespace supplychain-ns # if the namespace does not exist already +# Create the roottoken secret +kubectl -n supplychain-ns create secret generic roottoken --from-literal=token= + +helm install init ./corda-init --namespace supplychain-ns --values ./values/proxy-and-vault/init.yaml + +# Install doorman and network-map services +helm install supplychain ./corda-network-service --namespace supplychain-ns --values ./values/proxy-and-vault/network-service.yaml +# Install a notary service +helm install notary ./corda-node --namespace supplychain-ns --values ./values/proxy-and-vault/notary.yaml + +``` +### To setup another node in a different namespace + +Update the `global.proxy.externalUrlSuffix` and `nodeConf.legalName` in file `./values/proxy-and-vault/node.yaml` or pass via helm command line. +```bash +# Get the init and static nodes from existing member and place in corda-init/files +cd ./corda-init/files/ +kubectl --namespace supplychain-ns get secret nms-tls-certs -o jsonpath='{.data.tls\.crt}' > nms.crt +kubectl --namespace supplychain-ns get secret doorman-tls-certs -o jsonpath='{.data.tls\.crt}' > doorman.crt + +# Run secondary init +cd ../.. +kubectl create namespace manufacturer-ns # if the namespace does not exist already +# Create the roottoken secret +kubectl -n manufacturer-ns create secret generic roottoken --from-literal=token= + +helm install init ./corda-init --namespace manufacturer-ns --values ./values/proxy-and-vault/init-sec.yaml + +helm install manufacturer ./corda-node --namespace manufacturer-ns --values ./values/proxy-and-vault/node.yaml --set nodeConf.legalName="O=Manufacturer\,OU=Manufacturer\,L=47.38/8.54/Zurich\,C=CH" +``` + +### Clean-up + +To clean up, just uninstall the helm releases. +```bash +helm uninstall --namespace supplychain-ns notary +helm uninstall --namespace supplychain-ns supplychain +helm uninstall --namespace supplychain-ns init + +helm uninstall --namespace manufacturer-ns manufacturer +helm uninstall --namespace manufacturer-ns init + +``` \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-certs-gen/Chart.yaml b/platforms/r3-corda/charts/corda-certs-gen/Chart.yaml index 6bdce90e181..04535949bbb 100644 --- a/platforms/r3-corda/charts/corda-certs-gen/Chart.yaml +++ b/platforms/r3-corda/charts/corda-certs-gen/Chart.yaml @@ -5,7 +5,21 @@ ############################################################################################## apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Generates the ca-certificates." name: corda-certs-gen -version: 1.0.0 +description: "R3 Corda: Generates and stores TLS certificates for nodes and network services" +version: 1.0.1 +appVersion: latest +keywords: + - bevel + - hyperledger + - corda + - enterprise + - blockchain + - deployment + - accenture +home: https://hyperledger-bevel.readthedocs.io/en/latest/ +sources: + - https://github.com/hyperledger/bevel +maintainers: + - name: Hyperledger Bevel maintainers + email: bevel@lists.hyperledger.org diff --git a/platforms/r3-corda/charts/corda-certs-gen/README.md b/platforms/r3-corda/charts/corda-certs-gen/README.md index 22b8fa38804..c823cca1c9b 100644 --- a/platforms/r3-corda/charts/corda-certs-gen/README.md +++ b/platforms/r3-corda/charts/corda-certs-gen/README.md @@ -3,163 +3,83 @@ [//]: # (SPDX-License-Identifier: Apache-2.0) [//]: # (##############################################################################################) - -# corda-certs-gen deployment +# corda-certs-gen -- [corda-certs-gen Deployment Helm Chart](#corda-certs-gen-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) +This chart is a component of Hyperledger Bevel. The corda-certs-gen chart generates the TLS certificates needed for accessing Doorman, Network-Map and Corda nodes outside the cluster. If enabled, the certificates are then stored on the configured vault and also stored as Kubernetes secrets. See [Bevel documentation](https://hyperledger-bevel.readthedocs.io/en/latest/) for details. - -## corda-certs-gen Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-certs-gen) generates the certificates. +## TL;DR - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- Doorman network is setup and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - - -## Chart Structure ---- -This chart has following structue: - -``` - - ├── corda-certs-gen - │ ├── Chart.yaml - │ ├── templates - │ │ ├── job.yaml - │ │ ├── configmap.yaml - │ │ └── _helpers.tpl - │ └── values.yaml +```bash +helm repo add bevel https://hyperledger.github.io/bevel +helm install my-release bevel/corda-certs-gen ``` -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `job.yaml` : This Job is responsible for generating the root CA certificate, Doorman CA certificate, and MongoDB CA certificate for doorman. -- `configmap.yaml` : ConfigMap resource in Kubernetes with a specific name and namespace, along with labels for identification.And holds the openssl configuration file. -- `_helpers.tpl` : A template file used for defining custom labels in the Helm chart. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the metadata, image, service, Vault, etc. +## Prerequisitess +- Kubernetes 1.19+ +- Helm 3.2.0+ - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-certs-gen/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | doorman | - -### Metadata - -| Name | Description | Default Value | -| ----------------| ----------------------------------------------------------------------| ------------- | -| namespace | Provide the namespace for the Generate Certs Generator | notary-ns | -| labels | Provide any additional labels for the Generate Certs Generator | "" | - -### Image +If Hashicorp Vault is used, then +- HashiCorp Vault Server 1.13.1+ -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| certsContainerName | Provide the image for the certs container | "" | -| imagePullSecret | Provide the docker-registry secret created and stored in kubernetes cluster as a secret | "" | -| pullPolicy | Pull policy to be used for the Docker image | IfNotPresent | +## Installing the Chart -### Vault +To install the chart with the release name `my-release`: -| Name | Description | Default Value | -| ------------------------- | --------------------------------------------------------------------------| ------------- | -| address | Address/URL of the Vault server | "" | -| role | Role used for authentication with Vault | vault-role | -| authpath | Authentication path for Vault | cordadoorman | -| serviceAccountName | Provide the already created service account name autheticated to vault | vault-auth | -| certSecretPrefix | Provide the vault path where the certificates are stored | doorman/data | -| retries | Number of retries to check contents from vault | 10 | -| sleepTimeAfterError | Sleep time in seconds when error while registration | 15 | - -### Subjects - -| Name | Description | Default Value | -| ------------------------- | ---------------------------------- | ------------- | -| root_subject | Mention the subject for rootca | "" | -| mongorootca | Mention the subject for mongorootca| "" | -| doormanca | Mention the subject for doormanca | "" | -| networkmap | Mention the subject for networkmap | "" | - -### Volume - -| Name | Description | Default Value | -| -----------------| -----------------------| ------------- | -| baseDir | Base directory | /home/bevel | +```bash +helm repo add bevel https://hyperledger.github.io/bevel +helm install my-release bevel/corda-certs-gen +``` +The command deploys the chart on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. - -## Deployment ---- +> **Tip**: List all releases using `helm list` -To deploy the corda-certs-gen Helm chart, follow these steps: +## Uninstalling the Chart -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-certs-gen/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade, verify delete the chart: +To uninstall/delete the `my-release` deployment: -To install the chart: ```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-certs-gen +helm uninstall my-release ``` -To upgrade the chart: -```bash -helm upgrade ./corda-certs-gen -``` +The command removes all the Kubernetes components associated with the chart and deletes the release. -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. +## Parameters -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. +### Global parameters +These parameters are refered to as same in each parent or chold chart +| Name | Description | Default Value | +|--------|---------|-------------| +|`global.serviceAccountName` | The serviceaccount name that will be used for Vault Auth management| `vault-auth` | +| `global.vault.type` | Type of Vault to support other providers. Currently, only `hashicorp` is supported. | `hashicorp` | +| `global.vault.role` | Role used for authentication with Vault | `vault-role` | +| `global.vault.address`| URL of the Vault server. | `""` | +| `global.vault.authPath` | Authentication path for Vault | `supplychain` | +| `global.vault.network` | Network type which will determine the vault policy | `corda` | +| `global.vault.secretEngine` | Provide the value for vault secret engine name | `secretsv2` | +| `global.vault.secretPrefix` | Provide the value for vault secret prefix which must start with `data/` | `data/supplychain` | +| `global.proxy.externalUrlSuffix` | Provide the External URL suffix which will be used as CN to generate certificate | `test.blockchaincloudpoc.com` | + +### Image +| Name | Description| Default Value | +|------------|-----------|---------| +| `image.repository` | Docker repository which will be used for this job | `ghcr.io/hyperledger/bevel-alpine` | +| `image.tag` | Docker image tag which will be used for this job | `latest` | +| `image.pullSecret` | Provide the docker secret name | `""` | +| `image.pullPolicy` | The pull policy for the image | `IfNotPresent` | - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [corda-certs-gen Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-certs-gen), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). +### Settings +| Name | Description | Default Value | +| ------------| -------------- | --------------- | +| `settings.networkServices` | Set value to true when Doorman and NMS certificates are to be generated. | `false` | - ## License This chart is licensed under the Apache v2.0 license. -Copyright © 2023 Accenture +Copyright © 2024 Accenture ### Attribution diff --git a/platforms/r3-corda/charts/corda-certs-gen/templates/_helpers.tpl b/platforms/r3-corda/charts/corda-certs-gen/templates/_helpers.tpl index 7bf5f530a8e..0f08d8da5ad 100644 --- a/platforms/r3-corda/charts/corda-certs-gen/templates/_helpers.tpl +++ b/platforms/r3-corda/charts/corda-certs-gen/templates/_helpers.tpl @@ -1,5 +1,29 @@ -{{- define "labels.custom" }} - {{ range $key, $val := $.Values.metadata.labels }} - {{ $key }}: {{ $val }} - {{ end }} -{{- end }} \ No newline at end of file +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "corda-certs-gen.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 "corda-certs-gen.fullname" -}} +{{- $name := default .Chart.Name -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" $name .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "corda-certs-gen.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/platforms/r3-corda/charts/corda-certs-gen/templates/configmap.yaml b/platforms/r3-corda/charts/corda-certs-gen/templates/configmap.yaml deleted file mode 100644 index 19255f292bc..00000000000 --- a/platforms/r3-corda/charts/corda-certs-gen/templates/configmap.yaml +++ /dev/null @@ -1,20 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Values.nodeName }}-conf - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - {{- include "labels.custom" . | nindent 2 }} -data: - openssl.conf: |+ -{{ .Files.Get "files/openssl.conf" | indent 4 }} diff --git a/platforms/r3-corda/charts/corda-certs-gen/templates/job-cleanup.yaml b/platforms/r3-corda/charts/corda-certs-gen/templates/job-cleanup.yaml new file mode 100644 index 00000000000..66cea2ac9bd --- /dev/null +++ b/platforms/r3-corda/charts/corda-certs-gen/templates/job-cleanup.yaml @@ -0,0 +1,51 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "corda-certs-gen.name" . }}-cleanup + labels: + app.kubernetes.io/name: corda-certs-gen-job-cleanup + app.kubernetes.io/component: job-cleanup + app.kubernetes.io/part-of: {{ include "corda-certs-gen.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/managed-by: helm + namespace: {{ .Release.Namespace }} + annotations: + helm.sh/hook-weight: "0" + helm.sh/hook: "pre-delete" + helm.sh/hook-delete-policy: "hook-succeeded" +spec: + backoffLimit: 3 + completions: 1 + template: + metadata: + labels: + app.kubernetes.io/name: corda-certs-gen-job-cleanup + app.kubernetes.io/component: job-cleanup + app.kubernetes.io/part-of: {{ include "corda-certs-gen.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/managed-by: helm + spec: + serviceAccountName: {{ .Values.global.serviceAccountName }} + restartPolicy: "Never" + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + containers: + - name: delete-certs + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + securityContext: + runAsUser: 0 + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - sh + - -c + args: + - | + echo "Deleting tls-certs secret in k8s ..." + kubectl delete secret --namespace {{ .Release.Namespace }} {{ .Release.Name }}-tls-certs + {{- if .Values.settings.networkServices }} + kubectl delete secret --namespace {{ .Release.Namespace }} doorman-tls-certs + kubectl delete secret --namespace {{ .Release.Namespace }} nms-tls-certs + {{- end }} diff --git a/platforms/r3-corda/charts/corda-certs-gen/templates/job.yaml b/platforms/r3-corda/charts/corda-certs-gen/templates/job.yaml index 15ce252282d..74d962b2e03 100644 --- a/platforms/r3-corda/charts/corda-certs-gen/templates/job.yaml +++ b/platforms/r3-corda/charts/corda-certs-gen/templates/job.yaml @@ -7,350 +7,260 @@ apiVersion: batch/v1 kind: Job metadata: - name: {{ .Values.nodeName }}-generate-certs - namespace: {{ .Values.metadata.namespace }} + name: "{{ include "corda-certs-gen.name" . }}" + namespace: {{ .Release.Namespace }} + annotations: + helm.sh/hook-delete-policy: "before-hook-creation" labels: - app: {{ .Values.nodeName }}-generate-certs - app.kubernetes.io/name: {{ .Values.nodeName }}-generate-certs - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app: "{{ include "corda-certs-gen.name" . }}" + app.kubernetes.io/name: "{{ include "corda-certs-gen.name" . }}" app.kubernetes.io/managed-by: {{ .Release.Service }} app.kubernetes.io/instance: {{ .Release.Name }} - {{- include "labels.custom" . | nindent 2 }} spec: - backoffLimit: 6 - template: - metadata: - labels: - app: {{ .Values.nodeName }}-generate-certs - app.kubernetes.io/name: {{ .Values.nodeName }}-generate-certs - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - restartPolicy: "OnFailure" - serviceAccountName: {{ $.Values.vault.serviceAccountName }} - securityContext: - fsGroup: 1000 - initContainers: - - name: init-check-certificates - image: {{ .Values.image.initContainerName }} - imagePullPolicy: IfNotPresent - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authPath }} - - name: CERTS_SECRET_PREFIX - value: {{ .Values.vault.certSecretPrefix }} - - name: MOUNT_PATH - value: "/certcheck" - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code and curl_response - $curl_response" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - # Setting up the environment to get secrets/certificates from Vault - echo "Getting secrets/certificates from Vault server" - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "Logged into Vault" - mkdir -p ${MOUNT_PATH} - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/certs | jq -r 'if .errors then . else . end') - data_info="$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data["data"]')" - - if [ "$data_info" == "null" ] - then - echo "Certficates absent in vault. Ignore error warning" - touch ${MOUNT_PATH}/absent.txt - else - validateVaultResponse "${CERTS_SECRET_PREFIX}/certs" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - echo "Certificates present in vault" - touch ${MOUNT_PATH}/present.txt - fi - echo "Done checking for certificates in vault" - volumeMounts: - - name: certcheck - mountPath: /certcheck - - name: init-credentials - image: {{ .Values.image.initContainerName }} - imagePullPolicy: IfNotPresent - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authPath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: CERTS_SECRET_PREFIX - value: {{ .Values.vault.certSecretPrefix }} - - name: MOUNT_PATH - value: "/DATA" - - name: NODEINFO_MOUNT_PATH - value: "/notary-nodeinfo" - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code and curl_response - $curl_response" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - if [ -e /certcheck/present.txt ] - then - echo "Certificates already present in the vault. Skipping.." - exit 0 - fi - # Setting up the environment to get secrets from Vault - echo "Getting secrets from Vault Server" - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"vault-role","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - # Creating dirs for storing certificates - mkdir -p ${MOUNT_PATH}/keystore; + backoffLimit: 6 + template: + metadata: + labels: + app: "{{ include "corda-certs-gen.name" . }}" + app.kubernetes.io/name: "{{ include "corda-certs-gen.name" . }}" + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + restartPolicy: "OnFailure" + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + serviceAccountName: {{ .Values.global.serviceAccountName }} + securityContext: + fsGroup: 1000 + volumes: + - name: certificates + emptyDir: + medium: Memory + - name: scripts-volume + configMap: + name: bevel-vault-script + defaultMode: 0777 + initContainers: + {{- if (eq .Values.global.vault.type "hashicorp") }} + - name: init-check-certificates + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: VAULT_ADDR + value: "{{ $.Values.global.vault.address }}" + - name: VAULT_SECRET_ENGINE + value: "{{ $.Values.global.vault.secretEngine }}" + - name: VAULT_SECRET_PREFIX + value: "{{ $.Values.global.vault.secretPrefix }}" + - name: KUBERNETES_AUTH_PATH + value: "{{ $.Values.global.vault.authPath }}" + - name: VAULT_APP_ROLE + value: "{{ $.Values.global.vault.role }}" + - name: VAULT_TYPE + value: "{{ $.Values.global.vault.type }}" + command: ["sh", "-c"] + args: + - |- - OUTPUT_PATH=${MOUNT_PATH}/keystore; - # Fetching credentials for keystores - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/credentials/keystore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/credentials/keystore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - KEYSTORE_PASS=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["keystorepass"]') - echo "${KEYSTORE_PASS}"> ${OUTPUT_PATH}/keystorepass - - touch /DATA/done.txt - echo "Done" - volumeMounts: - - name: credentials - mountPath: /DATA - - name: certcheck - mountPath: /certcheck - containers: - - name: certs - image: "{{ required "certs[main]: missing value for .Values.image.certsContainerName" .Values.image.certsContainerName }}" - env: - - name: BASE_DIR - value: "{{ .Values.volume.baseDir }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["/bin/bash", "-c"] - args: - - |- - if [ -e /certcheck/present.txt ] - then - echo "Certificates already present in the vault. Skipping.." - exit 0 - fi - rm -r ${BASE_DIR}/DATA/done.txt - - # create directories - mkdir -p ${BASE_DIR}/DATA/rootca - mkdir -p ${BASE_DIR}/DATA/mongorootca - mkdir -p ${BASE_DIR}/DATA/mongodbca - mkdir -p ${BASE_DIR}/DATA/doormanca + # Source the bevel-vault.sh script to perform the Vault-CURD operations + . /scripts/bevel-vault.sh - KEYSTORE_PASS=$(cat ${BASE_DIR}/credentials/keystore/keystorepass) + # Get the Vault token + echo "Getting vault Token..." + vaultBevelFunc "init" + echo "Logged into Vault" - cd ${BASE_DIR}/DATA/rootca - set -x - keytool -genkey -keyalg RSA -alias key -dname "{{ .Values.subjects.rootca }}" -keystore keys.jks -storepass $KEYSTORE_PASS -keypass $KEYSTORE_PASS - openssl ecparam -name prime256v1 -genkey -noout -out cordarootca.key - openssl req -x509 -config ${BASE_DIR}/openssl.conf -new -nodes -key cordarootca.key -days 1024 -out cordarootca.pem -extensions v3_ca -subj '/{{ .Values.subjects.rootca | replace "," "/" }}' - openssl pkcs12 -export -name cert -inkey cordarootca.key -in cordarootca.pem -out cordarootcacert.pkcs12 -cacerts -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} - openssl pkcs12 -export -name key -inkey cordarootca.key -in cordarootca.pem -out cordarootcakey.pkcs12 -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} - eval "yes | keytool -importkeystore -srckeystore cordarootcacert.pkcs12 -srcstoretype PKCS12 -srcstorepass $KEYSTORE_PASS -destkeystore keys.jks -deststorepass $KEYSTORE_PASS" - eval "yes | keytool -importkeystore -srckeystore cordarootcakey.pkcs12 -srcstoretype PKCS12 -srcstorepass $KEYSTORE_PASS -destkeystore keys.jks -deststorepass $KEYSTORE_PASS" + OUTPUT_PATH=/certificates/check_certs + mkdir -p ${OUTPUT_PATH} + # Obtain the ambassador TLS certificates from Vault if exists + vault_secret_key="${VAULT_SECRET_ENGINE}/${VAULT_SECRET_PREFIX}/{{ .Release.Name }}-tlscerts" + echo "Checking certs in vault at path: ${vault_secret_key}" + vaultBevelFunc "readJson" ${vault_secret_key} - cd ${BASE_DIR}/DATA/doormanca - keytool -genkey -keyalg RSA -alias key -dname "{{ .Values.subjects.doormanca }}" -keystore keys.jks -storepass $KEYSTORE_PASS -keypass $KEYSTORE_PASS - openssl ecparam -name prime256v1 -genkey -noout -out cordadoormanca.key - openssl req -new -nodes -key cordadoormanca.key -days 1000 -out cordadoormanca.csr -subj '/{{ .Values.subjects.doormanca | replace "," "/" }}' - openssl x509 -req -days 1000 -in cordadoormanca.csr -CA ../rootca/cordarootca.pem -CAkey ../rootca/cordarootca.key -out cordadoormanca.pem -CAcreateserial \ - -CAserial serial -extfile ${BASE_DIR}/openssl.conf -extensions doorman - openssl pkcs12 -export -name cert -inkey cordadoormanca.key -in cordadoormanca.pem -out cordadoormancacert.pkcs12 -cacerts -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} - openssl pkcs12 -export -name key -inkey cordadoormanca.key -in cordadoormanca.pem -out cordadoormancakey.pkcs12 -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} - eval "yes | keytool -importkeystore -srckeystore cordadoormancacert.pkcs12 -srcstoretype PKCS12 -srcstorepass $KEYSTORE_PASS -destkeystore keys.jks -deststorepass $KEYSTORE_PASS - eval "yes | keytool -importkeystore -srckeystore cordadoormancakey.pkcs12 -srcstoretype PKCS12 -srcstorepass $KEYSTORE_PASS -destkeystore keys.jks -deststorepass $KEYSTORE_PASS - - cd ${BASE_DIR}/DATA/mongorootca - openssl genrsa -out mongoCA.key 3072 - openssl req -x509 -config ${BASE_DIR}/openssl.conf -new -extensions v3_ca -key mongoCA.key -days 365 -out mongoCA.crt -subj '{{ .Values.subjects.mongorootca }}' - - cd ${BASE_DIR}/DATA/mongodbca - openssl req -new -nodes -newkey rsa:4096 -keyout mongodb.key -out mongodb.csr -subj '{{ .Values.subjects.mongorootca }}-{{ .Values.nodeName }}' - openssl x509 -CA ../mongorootca/mongoCA.crt -CAkey ../mongorootca/mongoCA.key -CAcreateserial -CAserial serial -req -days 365 -in mongodb.csr -out mongodb.crt - cat mongodb.key mongodb.crt > mongodb.pem + # Get the ambassador TLS data info from Vault + cert=$(echo ${VAULT_SECRET} | jq -r '.["ambassadorcrt"]') - #creating a dummy file to perform check if last line is executed or not. - touch ${BASE_DIR}/DATA/done.txt - volumeMounts: - - name: certcheck - mountPath: /certcheck - - name: credentials - mountPath: {{ .Values.volume.baseDir }}/credentials - - name: certs-keys - mountPath: {{ .Values.volume.baseDir }}/DATA - - name: certs-etc - mountPath: {{ .Values.volume.baseDir }}/etc - - name: openssl-config - mountPath: {{ .Values.volume.baseDir }}/openssl.conf - subPath: openssl.conf - - name: store-certs - image: {{ .Values.image.initContainerName }} - imagePullPolicy: IfNotPresent - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authPath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: CERTS_SECRET_PREFIX - value: {{ .Values.vault.certSecretPrefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - } - - if [ -e /certcheck/present.txt ] - then - echo "Certificates already present in the vault. Skipping.." - exit 0 - fi - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - cd ${BASE_DIR}/DATA - # putting certificates - COUNTER=1 - while [ "$COUNTER" -lt {{ $.Values.vault.retries }} ] - do - if [ -e done.txt ] - then - cd ${BASE_DIR}/DATA - echo "found certificates, performing vault put" - # Use -w0 to get single line base64 -w0 - DOORMAN_CA=$(cat ./doormanca/keys.jks | base64 -w0) - ROOT_CA=$(cat ./rootca/keys.jks | base64 -w0) - CA_CERTS=$(cat ./rootca/cordarootca.pem | base64 -w0) - KEYSTORE=$(cat ./rootca/cordarootca.key | base64 -w0) - MONGO_KEY=$(cat ./mongodbca/mongodb.pem | base64 -w0) - MONGO_CERT=$(cat ./mongorootca/mongoCA.crt | base64 -w0) + # If the cert is null, empty, or contains a parse error, then the certificates do not exist in Vault + if [ "$cert" == "null" ] || [[ "$cert" = "parse error"* ]] || [ "$cert" = "" ] + then + # Create a file to indicate that the ambassador TLS certificates are absent + echo "Certficates absent in vault. Ignore error warning" + touch ${OUTPUT_PATH}/absent.txt + else + echo "Certificates present in vault" + touch ${OUTPUT_PATH}/present.txt + AMBASSADORTLS_PATH=/certificates/ambassadortls + mkdir -p ${AMBASSADORTLS_PATH} + cert=$(echo ${VAULT_SECRET} | jq -r '.["ambassadorcrt"]' | base64 -d ) + key=$(echo ${VAULT_SECRET} | jq -r '.["ambassadorkey"]' | base64 -d ) + echo "${cert}" > ${AMBASSADORTLS_PATH}/ambassador.crt + echo "${key}" > ${AMBASSADORTLS_PATH}/ambassador.key + + {{- if .Values.settings.networkServices }} + cert=$(echo ${VAULT_SECRET} | jq -r '.["doormancrt"]' | base64 -d ) + key=$(echo ${VAULT_SECRET} | jq -r '.["doormankey"]' | base64 -d ) + echo "${cert}" > ${AMBASSADORTLS_PATH}/doorman.crt + echo "${key}" > ${AMBASSADORTLS_PATH}/doorman.key + cert=$(echo ${VAULT_SECRET} | jq -r '.["nmscrt"]' | base64 -d ) + key=$(echo ${VAULT_SECRET} | jq -r '.["nmskey"]' | base64 -d ) + echo "${cert}" > ${AMBASSADORTLS_PATH}/nms.crt + echo "${key}" > ${AMBASSADORTLS_PATH}/nms.key + {{- end }} + + fi + echo "Done checking for certificates in vault" + + volumeMounts: + - name: certificates + mountPath: /certificates + - name: scripts-volume + mountPath: /scripts/bevel-vault.sh + subPath: bevel-vault.sh + {{- end }} + containers: + - name: generate-certs + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + {{- if (eq .Values.global.vault.type "hashicorp") }} + - name: VAULT_ADDR + value: "{{ $.Values.global.vault.address }}" + - name: VAULT_SECRET_ENGINE + value: "{{ $.Values.global.vault.secretEngine }}" + - name: VAULT_SECRET_PREFIX + value: "{{ $.Values.global.vault.secretPrefix }}" + - name: KUBERNETES_AUTH_PATH + value: "{{ $.Values.global.vault.authPath }}" + - name: VAULT_APP_ROLE + value: "{{ $.Values.global.vault.role }}" + - name: VAULT_TYPE + value: "{{ $.Values.global.vault.type }}" + {{- end }} + - name: EXTERNAL_URL + value: "{{ .Release.Name }}.{{ .Values.global.proxy.externalUrlSuffix }}" + command: ["sh", "-c"] + args: + - |- +{{- if (eq .Values.global.vault.type "hashicorp") }} + # Source the bevel-vault.sh script to perform the Vault-CURD operations + . /scripts/bevel-vault.sh + # Get the Vault token + echo "Getting vault Token..." + vaultBevelFunc "init" + echo "Logged into Vault" + function safeWriteSecret { + key=$1 + fpath=$2 + # Use -w0 to get single line base64 -w0 + TLS_CERT=$(cat ${fpath}/ambassador.crt | base64 -w0) + TLS_KEY=$(cat ${fpath}/ambassador.key | base64 -w0) +{{- if .Values.settings.networkServices }} + DOORMAN_CERT=$(cat ${fpath}/doorman.crt | base64 -w0) + DOORMAN_KEY=$(cat ${fpath}/doorman.key | base64 -w0) + NMS_CERT=$(cat ${fpath}/nms.crt | base64 -w0) + NMS_KEY=$(cat ${fpath}/nms.key | base64 -w0) - echo "{\"data\": { - \"{{ .Values.nodeName }}.jks\": \"${DOORMAN_CA}\", - \"rootcakey\": \"${ROOT_CA}\", - \"cacerts\": \"${CA_CERTS}\", - \"keystore\": \"${KEYSTORE}\", - \"mongodb-{{ .Values.nodeName }}.pem\": \"${MONGO_KEY}\", - \"mongoCA.crt\": \"${MONGO_CERT}\" - }}" > payload.json - - echo "before curl" - curl \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - --request POST \ - --data @payload.json \ - ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/certs - - echo "after POST" + echo " + { + \"data\": + { + \"ambassadorcrt\": \"${TLS_CERT}\", + \"ambassadorkey\": \"${TLS_KEY}\", + \"doormancrt\": \"${DOORMAN_CERT}\", + \"doormankey\": \"${DOORMAN_KEY}\", + \"nmscrt\": \"${NMS_CERT}\", + \"nmskey\": \"${NMS_KEY}\" + } + }" > payload.json +{{- else }} + echo " + { + \"data\": + { + \"ambassadorcrt\": \"${TLS_CERT}\", + \"ambassadorkey\": \"${TLS_KEY}\" + } + }" > payload.json +{{- end }} + # Copy the TLS certificates to the Vault + vaultBevelFunc 'write' "${VAULT_SECRET_ENGINE}/${VAULT_SECRET_PREFIX}/${key}-tlscerts" 'payload.json' + } +{{- else }} + function safeWriteSecret { + echo "Secrets are created. Add code specific to cloud provider vault here" + } +{{- end }} + # Set the directories path + CERTS_CHECKS_PATH=/certificates/check_certs + AMBASSADORTLS_PATH=/certificates/ambassadortls + + # if ambassadortls_absent file does not exist, create the certificates + if [ -e ${CERTS_CHECKS_PATH}/present.txt ] + then + echo "Certificates present." + else + # create directories + mkdir -p ${AMBASSADORTLS_PATH} + + cd ${AMBASSADORTLS_PATH} + echo "[req] + distinguished_name = dn + [dn] + [EXT] + keyUsage=digitalSignature + extendedKeyUsage=serverAuth + subjectAltName = @alt_names + [alt_names] + DNS.1 = {{ .Release.Name }}.{{ .Values.global.proxy.externalUrlSuffix }} + DNS.2 = {{ .Release.Name }}api.{{ .Values.global.proxy.externalUrlSuffix }} + DNS.3 = {{ .Release.Name }}web.{{ .Values.global.proxy.externalUrlSuffix }} + " > openssl.conf - # get certs from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/certs | jq -r 'if .errors then . else . end') - NODE_KEYS=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "{{ .Values.nodeName }}.jks" ]' 2>&1) - CORDA_SSL_ROOT_KEYS=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "rootcakey" ]' 2>&1) - CORDA_CA_CERTS=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "cacerts" ]' 2>&1) - ROOT_KEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "keystore" ]' 2>&1) - MONGODB_CERT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "mongoCA.crt" ]' 2>&1) - MONGODB_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "mongodb-{{ .Values.nodeName }}.pem" ]' 2>&1) + openssl req -x509 -out ambassador.crt -keyout ambassador.key -newkey rsa:2048 -nodes -sha256 \ + -subj "/CN=${EXTERNAL_URL}" -extensions EXT -config openssl.conf + + {{- if .Values.settings.networkServices }} + echo "Create certificates for Network Services" + DOORMAN_URL="{{ .Release.Name }}-doorman.{{ .Values.global.proxy.externalUrlSuffix }}" + openssl req -x509 -out doorman.crt -keyout doorman.key -newkey rsa:2048 -nodes -sha256 \ + -subj "/CN=${DOORMAN_URL}" -addext "subjectAltName = DNS:${DOORMAN_URL}" -extensions EXT -config openssl.conf + NMS_URL="{{ .Release.Name }}-nms.{{ .Values.global.proxy.externalUrlSuffix }}" + openssl req -x509 -out nms.crt -keyout nms.key -newkey rsa:2048 -nodes -sha256 \ + -subj "/CN=${NMS_URL}" -addext "subjectAltName = DNS:${NMS_URL}" -extensions EXT -config openssl.conf - if [ "$NODE_KEYS" == "null" ] || [ "$CORDA_SSL_ROOT_KEYS" == "null" ] || [ "$CORDA_CA_CERTS" == "null" ] || [ "$ROOT_KEYSTORE" == "null" ] || [ "$MONGODB_CERT" == "null" ] || [ "$MONGODB_KEY" == "null" ] || [[ "$NODE_KEYS" == "parse error"* ]] || [[ "$CORDA_SSL_ROOT_KEYS" == "parse error"* ]] || [[ "$CORDA_CA_CERTS" == "parse error"* ]] || [[ "$ROOT_KEYSTORE" == "parse error"* ]] || [[ "$MONGODB_CERT" == "parse error"* ]] || [[ "$MONGODB_KEY" == "parse error"* ]] - then - echo "certificates write or read fail" - sleep {{ $.Values.vault.sleepTimeAfterError }} - if [ "$COUNTER" -ge {{ $.Values.vault.retries }} ] - then - echo "Retry attempted $COUNTER times, certificates have not been saved" - exit 1 - fi - fi - break - COUNTER=`expr "$COUNTER" + 1` - fi - done + {{- end }} + echo "Done creating certificates, now store as secrets in k8s" + safeWriteSecret {{ .Release.Name }} ${AMBASSADORTLS_PATH} - if [ "$COUNTER" -gt {{ $.Values.vault.retries }} ] - then - echo "Retry attempted $COUNTER times, no files found. Giving up!" - exit 1 - break - fi - echo "completed" - volumeMounts: - - name: certcheck - mountPath: /certcheck - - name: certs-keys - mountPath: {{ .Values.volume.baseDir }}/DATA - readOnly: false - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: certcheck - emptyDir: - medium: Memory - - name: credentials - emptyDir: - medium: Memory - - name: certs-keys - emptyDir: - medium: Memory - - name: certs-etc - emptyDir: - medium: Memory - - name: openssl-config - configMap: - name: {{ .Values.nodeName }}-conf + fi; + # Create tls secret with the certificates + kubectl get secret --namespace {{ .Release.Namespace }} {{ .Release.Name }}-tls-certs + if [ $? -ne 0 ]; then + kubectl create secret tls --namespace {{ .Release.Namespace }} {{ .Release.Name }}-tls-certs \ + --cert=${AMBASSADORTLS_PATH}/ambassador.crt \ + --key=${AMBASSADORTLS_PATH}/ambassador.key + fi; + + {{- if .Values.settings.networkServices }} + kubectl get secret --namespace {{ .Release.Namespace }} doorman-tls-certs + if [ $? -ne 0 ]; then + kubectl create secret tls --namespace {{ .Release.Namespace }} doorman-tls-certs \ + --cert=${AMBASSADORTLS_PATH}/doorman.crt \ + --key=${AMBASSADORTLS_PATH}/doorman.key + fi; + kubectl get secret --namespace {{ .Release.Namespace }} nms-tls-certs + if [ $? -ne 0 ]; then + kubectl create secret tls --namespace {{ .Release.Namespace }} nms-tls-certs \ + --cert=${AMBASSADORTLS_PATH}/nms.crt \ + --key=${AMBASSADORTLS_PATH}/nms.key + fi; + + {{- end }} + volumeMounts: + - name: certificates + mountPath: /certificates + - name: scripts-volume + mountPath: /scripts/bevel-vault.sh + subPath: bevel-vault.sh diff --git a/platforms/r3-corda/charts/corda-certs-gen/values.yaml b/platforms/r3-corda/charts/corda-certs-gen/values.yaml index 1783ec6bcf3..7ca8691f994 100644 --- a/platforms/r3-corda/charts/corda-certs-gen/values.yaml +++ b/platforms/r3-corda/charts/corda-certs-gen/values.yaml @@ -4,98 +4,53 @@ # SPDX-License-Identifier: Apache-2.0 ############################################################################################## -# Default values for Certs Generator chart. # This is a YAML-formatted file. # Declare variables to be passed into your templates. - -############################################################# -# Basic Configuration # -############################################################# -# Provide the name of the node -# Eg. nodeName: cert-generation -nodeName: doorman - -# This section contains the Corda metadata. -metadata: - # Provide the namespace for the Corda Certs Generator. - # Eg. namespace: cenm - namespace: notary-ns - # Provide any additional labels for the Corda Certs Generator. - labels: +# The following are for overriding global values +global: + #Provide the service account name which will be created. + #Eg. serviceAccountName: vault-auth + serviceAccountName: vault-auth + vault: + #Provide the type of vault + #Eg. type: hashicorp + type: hashicorp + #Provide the vault role used. + #Eg. role: vault-role + role: vault-role + #Provide the vault server address + #Eg. address: http://54.226.163.39:8200 + address: + #Provide the vault authPath configured to be used. + #Eg. authPath: supplychain + authPath: supplychain + #Provide the network type + network: corda + #Provide the secret engine. + #Eg. secretEngine: secretsv2 + secretEngine: secretsv2 + #Provide the vault path where the tls certificates will be stored + #Eg. secretPrefix: data/warehouse-bes/crypto/warehouse/tls MUST use data/ + secretPrefix: "data/supplychain" + proxy: + # Provide external URL for cert generation + externalUrlSuffix: test.blockchaincloudpoc.com # Provide information regarding the Docker images used. image: - # Provide the alpine utils image, which is used for all init-containers of deployments/jobs. - # NOTE: The alpine image used is the base alpine image with CURL installed. - # Eg. initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/alpine-utils:1.0 - # Provide the image for the certs container. - # Eg. certsContainerName: ghcr.io/hyperledger/bevel-doorman:latest - certsContainerName: ghcr.io/hyperledger/bevel-build:jdk8-latest + #Provide the image repository for all containers + #Eg. repository: ghcr.io/hyperledger/bevel-alpine + repository: ghcr.io/hyperledger/bevel-alpine + tag: latest # Provide the docker-registry secret created and stored in kubernetes cluster as a secret. # Eg. imagePullSecret: regcred - imagePullSecret: + pullSecret: # Pull policy to be used for the Docker image # Eg. pullPolicy: Always pullPolicy: IfNotPresent - -############################################################# -# HashiCorp Vault Configuration # -############################################################# -# NOTE: Make sure that the vault is already unsealed, intialized and configured to -# use Kubernetes service account token based authentication. -# For more info, see https://www.vaultproject.io/docs/auth/kubernetes - -vault: - # Provide the vault address - # Eg. address: http://vault.example.com:8200 - address: - # Provide the vault role used. - # Eg. role: vault-role - role: vault-role - # Provide the authPath configured to be used. - # Eg. authPath: cordaentcenm - authPath: cordadoorman - # Provide the service account name autheticated to vault. - # NOTE: Make sure that the service account is already created and autheticated to use the vault. - # Eg. serviceAccountName: vault-auth - serviceAccountName: vault-auth - # Provide the vault path where the certificates are stored - # Eg. certSecretPrefix: secret/cenm-org-name - certSecretPrefix: doorman/data - - # The amount of times to retry fetching from/writing to Vault before giving up. - # Eg. retries: 10 - retries: 10 - # The amount of time in seconds to wait after an error occurs when fetching from/writing to Vault. - # Eg. sleepTimeAfterError: 15 - sleepTimeAfterError: 15 - - -############################################################# -# SUBJECT Details # -############################################################# -# This section details the X509 subjects - -subjects: - # Mention the subject for rootca - # Eg. rootca: "CN=DLT Root CA,OU=DLT,O=DLT,L=London,C=GB" - rootca: "CN=DLT Root CA,OU=DLT,O=DLT,L=New York,C=US" - # Mention the subject for mongorootca - # Eg. mongorootca: "CN=Test Subordinate CA Certificate, OU=HQ, O=HoldCo LLC, L=New York, C=US" - mongorootca: "/C=US/ST=New York/L=New York/O=Lite/OU=DBA/CN=mongoDB" - # Mention the subject for doormanca - # Eg. doormanca: "CN=Test Identity Manager Service Certificate, OU=HQ, O=HoldCo LLC, L=New York, C=US" - doormanca: "CN=Corda Doorman CA,OU=DOORMAN,O=DOORMAN,L=New York,C=US" - # Mention the subject for networkmap - # Eg. networkmap: "CN=Test Network Map Service Certificate, OU=HQ, O=HoldCo LLC, L=New York, C=US" - networkmap: - - -############################################################# -# Settings # -############################################################# -volume: - # Eg. baseDir: /opt/corda - baseDir: /home/bevel +# Settings for certificate generation +settings: + #Set value to true when useing network_services like doorman and nms + #Eg. networkServices: true + networkServices: false diff --git a/platforms/r3-corda/charts/corda-doorman-tls/Chart.yaml b/platforms/r3-corda/charts/corda-doorman-tls/Chart.yaml deleted file mode 100644 index b3af17b4d56..00000000000 --- a/platforms/r3-corda/charts/corda-doorman-tls/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Deploys the doorman with TLS connection enabled." -name: corda-doorman-tls -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-doorman-tls/README.md b/platforms/r3-corda/charts/corda-doorman-tls/README.md deleted file mode 100644 index 23ae572ed97..00000000000 --- a/platforms/r3-corda/charts/corda-doorman-tls/README.md +++ /dev/null @@ -1,173 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# Doorman Deployment - -- [Doorman-tls Deployment Helm Chart](#Doorman-tls-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - -## Doorman-tls Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-doorman-tls) deploys the doorman with TLS connection enabled, which helps establish trust and secure communication within the network by acting as a gatekeeper for network participants. - - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- Mongodb for doorman-tls database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - - -## Chart Structure ---- -This chart has following structue: - -``` - - ├── doorman-tls - │ ├── Chart.yaml - │ ├── templates - │ │ ├── deployment.yaml - │ │ ├── pvc.yaml - │ │ └── service.yaml - │ └── values.yaml -``` - -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `deployment.yaml` : This file is a configuration file for deployement in Kubernetes.It creates a deployment file with a specified number of replicas and defines various settings for the deployment.Including volume mounts, environment variables, and initialization tasks using init containers. -- `pvc.yaml` : A PersistentVolumeClaim (PVC) is a request for storage by a user. -- `service.yaml` : This file defines a Kubernetes Service with multiple ports for protocols and targets, and supports Ambassador proxy annotations for specific configurations when using the "ambassador" proxy provider. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the metadata, image, service, Vault, etc. - - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-doorman-tls/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | network-map | - -### Metadata - -| Name | Description | Default Value | -| ----------------| --------------------------------------------------------------------| ------------- | -| namespace | Provide the namespace for the doorman-tls Generator | default | -| labels | Provide any additional labels for the doorman-tls Generator | "" | - -### Image - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| containerName | Provide the containerName of image | "" | -| imagePullSecret | Provide the image pull secret of image | regcred | -| mountPath | Provide enviroment variable for container image | /opt/doorman | -| env | These env are used by the Doorman application to connect to the MongoDB database | "" | - - -### Vault - -| Name | Description | Default Value | -| ------------------------- | --------------------------------------------------------------------------| ------------- | -| address | Address/URL of the Vault server | "" | -| role | Role used for authentication with Vault | vault-role | -| authpath | Authentication path for Vault | cordanms | -| secretprefix | Provide the kubernetes auth backed configured in vault | "" | -| imagesecretname | specify the name of the Kubernetes secret | "" | -| serviceaccountname | To authenticate with the Vault server and retrieve the secrets |vault-auth-issuer| - - -### Healthcheck - - Tasks performed in this container is used for database health check. - If db is up and running, starts the corda doorman-tls main container. - - - -## Deployment ---- - -To deploy the Doorman-tls Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-doorman-tls/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade,verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-doorman-tls -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-doorman-tls -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [Doorman-tls Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-doorman-tls), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-doorman-tls/templates/deployment.yaml b/platforms/r3-corda/charts/corda-doorman-tls/templates/deployment.yaml deleted file mode 100644 index bba1a965301..00000000000 --- a/platforms/r3-corda/charts/corda-doorman-tls/templates/deployment.yaml +++ /dev/null @@ -1,361 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Deployment -# Creates the replicated container and manages lifecycle -# TLS certs mounted -# Persistent Volume mounted -# Service points to this deployment (uses labels!) -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.nodeName }} - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.deployment.annotations }} - annotations: -{{ toYaml .Values.deployment.annotations | indent 8 }} - {{- end }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - template: - metadata: - labels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: {{ .Values.nodeName }} - image: {{ .Values.image.containerName }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - - # add permissions to dir - chmod 777 -R {{ .Values.image.mountPath.basePath }}/; - #setting up the required variable required for jar - {{- range $.Values.image.env }} - export {{ .name }}="{{ .value }}" - {{- end }} - export DOORMAN_TLS_CERT_PATH="{{ .Values.image.mountPath.basePath }}-tls/certs/doorman.crt" - export DOORMAN_TLS_KEY_PATH="{{ .Values.image.mountPath.basePath }}-tls/certs/doorman.key" - export DB_PASSWORD=`cat /opt/creds/db_root_password` - cat /opt/creds/db_root_password - export DOORMAN_MONGO_CONNECTION_STRING="mongodb://${DB_USERNAME}:${DB_PASSWORD}@${DB_URL}:${DB_PORT}/${DATABASE}?ssl=true&sslInvalidHostNameAllowed=true&streamType=netty" - export DOORMAN_AUTH_PASSWORD=`cat /opt/creds/user_cred` - - # import self signed tls certificate of mongodb, since java only trusts certificate signed by well known CA - yes | keytool -importcert -file {{ .Values.image.mountPath.basePath }}-tls/certs/mongoCA.crt -storepass changeit -alias mongoca -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - # command to run jar - java -jar {{ .Values.image.mountPath.basePath }}/doorman.jar 2>&1 - ports: - - containerPort: {{ .Values.service.targetPort }} - volumeMounts: - - name: {{ .Values.nodeName }}-servicedata - mountPath: "{{ .Values.image.mountPath.basePath }}/db/" - readOnly: false - - name: certs - mountPath: "{{ .Values.image.mountPath.basePath }}/db/certs" - readOnly: false - - name: tls-certs - mountPath: "{{ .Values.image.mountPath.basePath }}-tls/certs" - - name: creds - mountPath: "/opt/creds" - readOnly: false - initContainers: - - name: init-certificates - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}/db/certs/ - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - OUTPUT_PATH=${MOUNT_PATH} - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/{{ .Values.vault.certsecretprefix }} | jq -r 'if .errors then . else . end') - - validateVaultResponse "{{ .Values.vault.certsecretprefix }}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - - ROOTCA_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["rootcakey"]') - mkdir -p ${OUTPUT_PATH}/root; - echo "${ROOTCA_KEY}" | base64 -d > ${OUTPUT_PATH}/root/keys.jks - - DOORMAN_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["doorman.jks"]') - mkdir -p ${OUTPUT_PATH}/doorman; - echo "${DOORMAN_KEY}" | base64 -d > ${OUTPUT_PATH}/doorman/keys.jks - - chmod 777 -R {{ .Values.image.mountPath.basePath }}/db - volumeMounts: - - name: certs - mountPath: "{{ .Values.image.mountPath.basePath }}/db/certs/" - readOnly: false - - name: init-certificates-tls - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}-tls/certs/ - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - # setting up env to get secrets from vault - echo "Getting secrets from Vault Server" - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${MOUNT_PATH} - - if [ "{{ .Values.image.tlsCertificate }}" == true ] - then - # get doorman tls cert and key from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/{{ .Values.vault.tlscertsecretprefix }} | jq -r 'if .errors then . else . end') - validateVaultResponse "{{ .Values.vault.tlscertsecretprefix }}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - DOORMAN_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["tlscacerts"]') - DOORMAN_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["tlskey"]') - echo "${DOORMAN_CRT}" | base64 -d > {{ .Values.image.mountPath.basePath }}-tls/certs/doorman.crt - echo "${DOORMAN_KEY}" | base64 -d > {{ .Values.image.mountPath.basePath }}-tls/certs/doorman.key - fi - - # get mongo tls cert from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/{{ .Values.vault.dbcertsecretprefix }} | jq -r 'if .errors then . else . end') - validateVaultResponse "{{ .Values.vault.dbcertsecretprefix }}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - CA_CERT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["mongoCA.crt"]') - echo "${CA_CERT}" | base64 -d > ${OUTPUT_PATH}/mongoCA.crt - - # add permissions to dir - chmod 777 -R {{ .Values.image.mountPath.basePath }}-tls/certs/ - volumeMounts: - - name: tls-certs - mountPath: "{{ .Values.image.mountPath.basePath }}-tls/certs/" - readOnly: false - - name: init-creds - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: /opt/creds - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: DB_CRED_SECRET_PREFIX - value: {{ .Values.vault.dbcredsecretprefix }} - - name: USER_SECRET_PREFIX - value: {{ .Values.vault.secretdoormanpass }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - OUTPUT_PATH=${MOUNT_PATH} - LOOKUP_PWD_RESPONSE_DB_PASS=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_CRED_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - - validateVaultResponse "${DB_CRED_SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE_DB_PASS}" "LOOKUPSECRETRESPONSE" - - MONGODB_PASSWORD=$(echo ${LOOKUP_PWD_RESPONSE_DB_PASS} | jq -r '.data.data["mongodbPassword"]') - echo "${MONGODB_PASSWORD}" >> ${MOUNT_PATH}/db_root_password - cat ${MOUNT_PATH}/db_root_password - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${USER_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "${USER_SECRET_PREFIX}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - - USER_PASSWORD=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["{{ .Values.image.authusername }}"]') - echo "${USER_PASSWORD}" >> ${MOUNT_PATH}/user_cred - - volumeMounts: - - name: creds - mountPath: "/opt/creds" - readOnly: false - - name: changepermissions - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}/db/certs - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - chmod 777 -R {{ .Values.image.mountPath.basePath }}/; - volumeMounts: - - name: {{ .Values.nodeName }}-servicedata - mountPath: "{{ .Values.image.mountPath.basePath }}/db" - readOnly: false - - name: db-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - while [ "$COUNTER" -le {{ $.Values.healthcheck.readinessthreshold }} ] - do - DB_NODE={{ .Values.healthcheck.dburl }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.healthcheck.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - if [ "$COUNTER" -gt {{ $.Values.healthcheck.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: {{ .Values.nodeName }}-servicedata - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}-pvc - - name: certs - emptyDir: - medium: Memory - - name: creds - emptyDir: - medium: Memory - - name: tls-certs - emptyDir: - medium: Memory - \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-doorman-tls/templates/pvc.yaml b/platforms/r3-corda/charts/corda-doorman-tls/templates/pvc.yaml deleted file mode 100644 index 94433d6faab..00000000000 --- a/platforms/r3-corda/charts/corda-doorman-tls/templates/pvc.yaml +++ /dev/null @@ -1,28 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.nodeName }}-pvc - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.pvc.annotations }} - annotations: -{{ toYaml .Values.pvc.annotations | indent 8 }} - {{- end }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }}-pvc - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - storageClassName: {{ .Values.storage.name }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.storage.memory }} diff --git a/platforms/r3-corda/charts/corda-doorman-tls/templates/service.yaml b/platforms/r3-corda/charts/corda-doorman-tls/templates/service.yaml deleted file mode 100644 index 5f117bd6f93..00000000000 --- a/platforms/r3-corda/charts/corda-doorman-tls/templates/service.yaml +++ /dev/null @@ -1,70 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.nodeName }} - namespace: {{ $.Values.metadata.namespace }} - annotations: - labels: - run: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - selector: - app: {{ .Values.nodeName }} - type: {{ .Values.service.type }} - ports: - - protocol: TCP - port: {{ .Values.service.port }} - targetPort: {{ .Values.service.targetPort }} - {{- if .Values.service.nodePort }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} -{{ if $.Values.ambassador }} ---- -apiVersion: getambassador.io/v3alpha1 -kind: Host -metadata: - name: {{ .Values.nodeName }}-host -spec: - hostname: {{ .Values.nodeName }}.{{ .Values.ambassador.external_url_suffix }} - acmeProvider: - authority: none - requestPolicy: - insecure: - action: Route - tlsSecret: - name: {{ .Values.nodeName }}-ambassador-certs - namespace: {{ .Values.metadata.namespace }} ---- -apiVersion: getambassador.io/v3alpha1 -kind: Mapping -metadata: - name: {{ .Values.nodeName }}-mapping - namespace: {{ .Values.metadata.namespace }} -spec: - host: {{ .Values.nodeName }}.{{ .Values.ambassador.external_url_suffix }} - prefix: / - service: https://{{ .Values.nodeName }}.{{ .Values.metadata.namespace }}:{{ .Values.service.port }} - tls: {{ .Values.nodeName }}-tlscontext ---- -apiVersion: getambassador.io/v3alpha1 -kind: TLSContext -metadata: - name: {{ .Values.nodeName }}-tlscontext - namespace: {{ .Values.metadata.namespace }} -spec: - hosts: - - {{ .Values.nodeName }}.{{ .Values.ambassador.external_url_suffix }} - secret: {{ .Values.nodeName }}-ambassador-certs.{{ .Values.metadata.namespace }} - secret_namespacing: true - min_tls_version: v1.2 -{{- end }} - diff --git a/platforms/r3-corda/charts/corda-doorman-tls/values.yaml b/platforms/r3-corda/charts/corda-doorman-tls/values.yaml deleted file mode 100644 index 252ccbda31c..00000000000 --- a/platforms/r3-corda/charts/corda-doorman-tls/values.yaml +++ /dev/null @@ -1,120 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Default values for nmschart. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -#Provide the Name for node to be deployed -#Eg. nodeName: network-map -nodeName: network-map - -metadata: - #Provide the namespace for organization's peer - #Eg. namespace: default - namespace: default - -image: - #Provide the name of image for init container - #Eg. initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - #Provide the containerName of image - #Eg. containerName: ghcr.io/hyperledger/bevel-doorman-linuxkit:latest - containerName: ghcr.io/hyperledger/bevel-doorman-linuxkit:latest - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: "" - #Provide enviroment variable for container image - mountPath: - #Provide the path for base dir - #Eg. basePath: /opt/workdir - basePath: /opt/doorman - env: - #Provide rootcaname for the doorman - #Eg. rootcaname: CN=Corda Root CA, OU=FRA, O=FRA, L=London, ST=London, C=BR - rootcaname: - #Provide tlscertpath for the doorman - #Eg. tlscertpath: /opt/cordite/db/certs/tls/nms.crt - tlscertpath: - #Provide tlscertpath for the doorman - #Eg. tlscertpath: /opt/cordite/db/certs/tls/nms.key - tlskeypath: - #Provide whether TLS is enabled or not - #Eg. tls: false - tls: false - #Provide whether to enable Corda doorman protocol - #Eg. doorman: true - doorman: true - #Provide whether to enable Cordite certman protocol so that nodes can authenticate using a signed TLS cert - #Eg. certman: true - certman: true - #Provide database directory for this service - #Eg. database: db - database: db - #Provide MongoDB connection string. If set to embed will start its own mongo instance - #Eg. dataSourceUrl: db - dataSourceUrl: db - -service: - #Provide the type of service - #Eg. type: NodePort - type: NodePort - #Provide the node port for node service to be accessible outside - #Eg. nodePort: 30050 - nodePort: - #Provide the targetPort for node service to be accessible - #Eg. targetPort: 8080 - targetPort: - #Provide the port for node service to be accessible - #Eg. port: 8080 - port: - -deployment: - # annotations: - # key: "value" - annotations: {} - -storage: - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - -pvc: - # annotations: - # key: "value" - annotations: {} - -vault: - #Provide the vault server address - #Eg. address: http://34.228.219.208:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: vault-role - #Eg. authpath: cordanms - authpath: cordanms - #Provide the kubernetes auth backed configured in vault - #Eg. secretprefix: - secretprefix: - #Eg. imagesecretname: - imagesecretname: - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: - -mountPath: - #Provide the path for base dir - #Eg. basePath: /opt/workdir - basePath: - -healthcheck: - dburl: - -ambassador: - #Provides the suffix to be used in external URL - #Eg. external_url_suffix: org1.blockchaincloudpoc.com - external_url_suffix: - - diff --git a/platforms/r3-corda/charts/corda-doorman/Chart.yaml b/platforms/r3-corda/charts/corda-doorman/Chart.yaml deleted file mode 100644 index 2f2170e5033..00000000000 --- a/platforms/r3-corda/charts/corda-doorman/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Deploys the doorman service." -name: corda-doorman -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-doorman/README.md b/platforms/r3-corda/charts/corda-doorman/README.md deleted file mode 100644 index e3a68c796fc..00000000000 --- a/platforms/r3-corda/charts/corda-doorman/README.md +++ /dev/null @@ -1,171 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# Doorman Deployment - -- [Doorman Deployment Helm Chart](#Doorman-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - -## Doorman Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-doorman) deploys the doorman service, which helps establish trust and secure communication within the network by acting as a gatekeeper for network participants. - - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- Mongodb for doorman up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - - -## Chart Structure ---- -This chart has following structue: - -``` - - ├── doorman - │ ├── Chart.yaml - │ ├── templates - │ │ ├── deployment.yaml - │ │ ├── pvc.yaml - │ │ └── service.yaml - │ └── values.yaml -``` - -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `deployment.yaml` : A Deployment controller provides declarative updates for Pods and ReplicaSets. -- `pvc.yaml` : A PersistentVolumeClaim (PVC) is a request for storage by a user. -- `service.yaml` : This file defines a Kubernetes Service with multiple ports for protocols and targets, and supports Ambassador proxy annotations for specific configurations when using the "ambassador" proxy provider. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the metadata, image, service, Vault, etc. - - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-doorman/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | network-map | - -### Metadata - -| Name | Description | Default Value | -| ----------------| ----------------------------------------------------------------| ------------- | -| namespace | Provide the namespace for the doorman Generator | default | -| labels | Provide any additional labels for the doorman Generator | "" | - -### Image - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| containerName | Provide the containerName of image | "" | -| imagePullSecret | Provide the image pull secret of image | regcred | -| mountPath | Provide enviroment variable for container image | /opt/doorman | -| env |These env are used by the Doorman application to connect to the MongoDB database | "" | - - -### Vault - -| Name | Description | Default Value | -| ------------------------- | --------------------------------------------------------------------------| ------------- | -| address | Address/URL of the Vault server | "" | -| role | Role used for authentication with Vault | vault-role | -| authpath | Authentication path for Vault | cordanms | -| secretprefix | Provide the kubernetes auth backed configured in vault | "" | -| imagesecretname | specify the name of the Kubernetes secret | "" | -| serviceaccountname | To authenticate with the Vault server and retrieve the secrets |vault-auth-issuer| - -### Healthcheck - - Tasks performed in this container is used for database health check. - If db is up and running, starts the corda doorman main container. - - - -## Deployment ---- - -To deploy the Doorman Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-doorman/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade, verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-doorman -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-doorman -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [Doorman Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-doorman), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-doorman/templates/deployment.yaml b/platforms/r3-corda/charts/corda-doorman/templates/deployment.yaml deleted file mode 100644 index cdcca981aea..00000000000 --- a/platforms/r3-corda/charts/corda-doorman/templates/deployment.yaml +++ /dev/null @@ -1,275 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Deployment -# Creates the replicated container and manages lifecycle -# TLS certs mounted -# Persistent Volume mounted -# Service points to this deployment (uses labels!) -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.nodeName }} - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.deployment.annotations }} - annotations: -{{ toYaml .Values.deployment.annotations | indent 8 }} - {{- end }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - template: - metadata: - labels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: {{ .Values.nodeName }} - image: {{ .Values.image.containerName }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - {{- range $.Values.image.env }} - export {{ .name }}="{{ .value }}" - {{- end }} - export DB_PASSWORD=`cat /opt/creds/db_root_password` - cat /opt/creds/db_root_password - export DOORMAN_MONGO_CONNECTION_STRING="mongodb://${DB_USERNAME}:${DB_PASSWORD}@${DB_URL}:${DB_PORT}/${DATABASE}" - export DOORMAN_AUTH_PASSWORD=`cat /opt/creds/user_cred` - java -jar {{ .Values.image.mountPath.basePath }}/doorman.jar 2>&1 - ports: - - containerPort: {{ .Values.service.targetPort }} - volumeMounts: - - name: {{ .Values.nodeName }}-servicedata - mountPath: "{{ .Values.image.mountPath.basePath }}/db/" - readOnly: false - - name: certs - mountPath: "{{ .Values.image.mountPath.basePath }}/db/certs" - readOnly: false - - name: creds - mountPath: "/opt/creds" - readOnly: false - initContainers: - - name: init-certificates - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}/db/certs/ - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - OUTPUT_PATH=${MOUNT_PATH} - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/{{ .Values.vault.certsecretprefix }} | jq -r 'if .errors then . else . end') - - validateVaultResponse "{{ .Values.vault.certsecretprefix }}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - - ROOTCA_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["rootcakey"]') - mkdir -p ${OUTPUT_PATH}/root; - echo "${ROOTCA_KEY}" | base64 -d > ${OUTPUT_PATH}/root/keys.jks - - DOORMAN_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["doorman.jks"]') - mkdir -p ${OUTPUT_PATH}/doorman; - echo "${DOORMAN_KEY}" | base64 -d > ${OUTPUT_PATH}/doorman/keys.jks - chmod 777 -R {{ .Values.image.mountPath.basePath }}/db - volumeMounts: - - name: certs - mountPath: "{{ .Values.image.mountPath.basePath }}/db/certs/" - readOnly: false - - name: init-creds - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: /opt/creds - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: DB_CRED_SECRET_PREFIX - value: {{ .Values.vault.dbcredsecretprefix }} - - name: USER_SECRET_PREFIX - value: {{ .Values.vault.secretdoormanpass }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - OUTPUT_PATH=${MOUNT_PATH} - LOOKUP_PWD_RESPONSE_DB_PASS=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_CRED_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - - validateVaultResponse "${DB_CRED_SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE_DB_PASS}" "LOOKUPSECRETRESPONSE" - - MONGODB_PASSWORD=$(echo ${LOOKUP_PWD_RESPONSE_DB_PASS} | jq -r '.data.data["mongodbPassword"]') - echo "${MONGODB_PASSWORD}" >> ${MOUNT_PATH}/db_root_password - cat ${MOUNT_PATH}/db_root_password - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${USER_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "${USER_SECRET_PREFIX}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - - USER_PASSWORD=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["{{ .Values.image.authusername }}"]') - echo "${USER_PASSWORD}" >> ${MOUNT_PATH}/user_cred - - volumeMounts: - - name: creds - mountPath: "/opt/creds" - readOnly: false - - name: changepermissions - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}/db/certs - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - chmod 777 -R {{ .Values.image.mountPath.basePath }}/; - volumeMounts: - - name: {{ .Values.nodeName }}-servicedata - mountPath: "{{ .Values.image.mountPath.basePath }}/db" - readOnly: false - - name: db-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - while [ "$COUNTER" -le {{ $.Values.healthcheck.readinessthreshold }} ] - do - DB_NODE={{ .Values.healthcheck.dburl }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.healthcheck.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - if [ "$COUNTER" -gt {{ $.Values.healthcheck.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: {{ .Values.nodeName }}-servicedata - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}-pvc - - name: certs - emptyDir: - medium: Memory - - name: creds - emptyDir: - medium: Memory diff --git a/platforms/r3-corda/charts/corda-doorman/templates/pvc.yaml b/platforms/r3-corda/charts/corda-doorman/templates/pvc.yaml deleted file mode 100644 index 94433d6faab..00000000000 --- a/platforms/r3-corda/charts/corda-doorman/templates/pvc.yaml +++ /dev/null @@ -1,28 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.nodeName }}-pvc - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.pvc.annotations }} - annotations: -{{ toYaml .Values.pvc.annotations | indent 8 }} - {{- end }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }}-pvc - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - storageClassName: {{ .Values.storage.name }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.storage.memory }} diff --git a/platforms/r3-corda/charts/corda-doorman/templates/service.yaml b/platforms/r3-corda/charts/corda-doorman/templates/service.yaml deleted file mode 100644 index a7f8737155b..00000000000 --- a/platforms/r3-corda/charts/corda-doorman/templates/service.yaml +++ /dev/null @@ -1,42 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.nodeName }} - namespace: {{ .Values.metadata.namespace }} - annotations: - labels: - run: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - selector: - app: {{ .Values.nodeName }} - type: {{ .Values.service.type }} - ports: - - protocol: TCP - port: {{ .Values.service.port }} - targetPort: {{ .Values.service.targetPort }} - {{- if .Values.service.nodePort }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} -{{ if $.Values.ambassador }} ---- -apiVersion: getambassador.io/v3alpha1 -kind: Mapping -metadata: - name: {{ .Values.nodeName }}-mapping - namespace: {{ .Values.metadata.namespace }} -spec: - hostname: {{ .Values.nodeName }}.{{ .Values.ambassador.external_url_suffix }} - prefix: / - service: http://{{ .Values.nodeName }}.{{ .Values.metadata.namespace }}:{{ .Values.service.port }} -{{ end }} - diff --git a/platforms/r3-corda/charts/corda-doorman/values.yaml b/platforms/r3-corda/charts/corda-doorman/values.yaml deleted file mode 100644 index 50cdaa23685..00000000000 --- a/platforms/r3-corda/charts/corda-doorman/values.yaml +++ /dev/null @@ -1,120 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Default values for nmschart. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -#Provide the Name for node to be deployed -#Eg. nodeName: network-map -nodeName: network-map - -metadata: - #Provide the namespace for organization's peer - #Eg. namespace: default - namespace: default - -image: - #Provide the name of image for init container - #Eg. initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - #Provide the containerName of image - #Eg. containerName: ghcr.io/hyperledger/bevel-doorman-linuxkit:latest - containerName: ghcr.io/hyperledger/bevel-doorman-linuxkit:latest - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: "" - #Provide enviroment variable for container image - mountPath: - #Provide the path for base dir - #Eg. basePath: /opt/workdir - basePath: /opt/doorman - env: - #Provide rootcaname for the doorman - #Eg. rootcaname: CN=Corda Root CA, OU=FRA, O=FRA, L=London, ST=London, C=BR - rootcaname: - #Provide tlscertpath for the doorman - #Eg. tlscertpath: /opt/cordite/db/certs/tls/nms.crt - tlscertpath: - #Provide tlscertpath for the doorman - #Eg. tlscertpath: /opt/cordite/db/certs/tls/nms.key - tlskeypath: - #Provide whether TLS is enabled or not - #Eg. tls: false - tls: false - #Provide whether to enable Corda doorman protocol - #Eg. doorman: true - doorman: true - #Provide whether to enable Cordite certman protocol so that nodes can authenticate using a signed TLS cert - #Eg. certman: true - certman: true - #Provide database directory for this service - #Eg. database: db - database: db - #Provide MongoDB connection string. If set to embed will start its own mongo instance - #Eg. dataSourceUrl: db - dataSourceUrl: db - -service: - #Provide the type of service - #Eg. type: NodePort - type: NodePort - #Provide the node port for node service to be accessible outside - #Eg. nodePort: 30050 - nodePort: - #Provide the targetPort for node service to be accessible - #Eg. targetPort: 8080 - targetPort: - #Provide the port for node service to be accessible - #Eg. port: 8080 - port: - -deployment: - # annotations: - # key: "value" - annotations: {} - -storage: - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - -pvc: - # annotations: - # key: "value" - annotations: {} - -vault: - #Provide the vault server address - #Eg. address: http://34.228.219.208:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: vault-role - #Eg. authpath: cordanms - authpath: cordanms - #Provide the kubernetes auth backed configured in vault - #Eg. secretprefix: - secretprefix: - #Eg. imagesecretname: - imagesecretname: - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: vault-auth-issuer - -mountPath: - #Provide the path for base dir - #Eg. basePath: /opt/workdir - basePath: - -healthcheck: - dburl: - -ambassador: - #Provides the suffix to be used in external URL - #Eg. external_url_suffix: org1.blockchaincloudpoc.com - external_url_suffix: - - diff --git a/platforms/r3-corda/charts/corda-h2-addUser/Chart.yaml b/platforms/r3-corda/charts/corda-h2-addUser/Chart.yaml deleted file mode 100644 index 7e4915c3b56..00000000000 --- a/platforms/r3-corda/charts/corda-h2-addUser/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: A Helm chart for registering the notary with the nms -name: corda-h2-add-user -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-h2-addUser/templates/job.yaml b/platforms/r3-corda/charts/corda-h2-addUser/templates/job.yaml deleted file mode 100644 index 438353d70f3..00000000000 --- a/platforms/r3-corda/charts/corda-h2-addUser/templates/job.yaml +++ /dev/null @@ -1,169 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: batch/v1 -kind: Job -metadata: - name: h2-add-user-{{ .Values.nodeName }} - labels: - app: h2-add-user-{{ .Values.nodeName }} - app.kubernetes.io/name: h2-add-user-{{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - backoffLimit: 6 - ttlSecondsAfterFinished: 300 - template: - metadata: - labels: - app: h2-add-user-{{ .Values.nodeName }} - app.kubernetes.io/name: h2-add-user-{{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - restartPolicy: "OnFailure" - serviceAccountName: {{ .Values.vault.serviceaccountname }} - containers: - - name: h2-add-user - image: {{ .Values.image.containerName }} - imagePullPolicy: Always - env: - - name: MOUNT_PATH - value: /opt/h2 - - name: SECRET_PREFIX - value: {{ .Values.vault.dbsecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - export SA_PASSWORD=`cat /opt/db/creds/db_cred` - export JDBC_URL={{ .Values.jdbcUrl }} - - {{- range .Values.users }} - USER_PASSWORD=`cat /opt/db/creds/{{ .name }}-password` - echo "Adding User : {{ .name }}" - cat << EOF > ${MOUNT_PATH}/newuser.sql - CREATE USER {{ .name }} PASSWORD '${USER_PASSWORD} admin '; - EOF - - chmod 777 ${MOUNT_PATH}/newuser.sql - H2JARPATH=${MOUNT_PATH}/bin/h2*.jar - H2SCRIPTCLASSPATH=org.h2.tools.RunScript - - java -cp ${H2JARPATH} ${H2SCRIPTCLASSPATH} -url ${JDBC_URL} -user sa -password "${SA_PASSWORD}" -script ${MOUNT_PATH}/newuser.sql - echo "New User Added" - {{- end }} - volumeMounts: - - name: {{ .Values.nodeName }}volume - mountPath: "/opt/h2-data" - - name: creds - mountPath: "/opt/db/creds" - readOnly: false - initContainers: - - name: init-credential - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: /opt/db/creds - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: DB_SECRET_PREFIX - value: {{ .Values.vault.dbsecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "${DB_SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE}" "LOOKUPSECRETRESPONSE" - SA_PASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["sa"]') - echo "${SA_PASSWORD}" >> ${MOUNT_PATH}/db_cred - {{- range .Values.users }} - USER_PASS=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["{{ .name }}"]') - echo "${USER_PASS}" >> ${MOUNT_PATH}/{{ .name }}-password - {{- end }} - volumeMounts: - - name: creds - mountPath: "/opt/db/creds" - readOnly: false - - name: db-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - while [ "$COUNTER" -le {{ $.Values.db.readinessthreshold }} ] - do - DB_NODE={{ .Values.dbUrl }}:{{ .Values.dbPort }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.db.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.db.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - if [ "$COUNTER" -gt {{ $.Values.db.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: {{ .Values.nodeName }}volume - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}db-pvc - - name: creds - emptyDir: - medium: Memory \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-h2-addUser/values.yaml b/platforms/r3-corda/charts/corda-h2-addUser/values.yaml deleted file mode 100644 index 927b499e6e2..00000000000 --- a/platforms/r3-corda/charts/corda-h2-addUser/values.yaml +++ /dev/null @@ -1,184 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# This is a YAML-formatted file. -# This should be produced by build - -#Provide the nodeName for node -#Eg. nodeName: bank1 -nodeName: - -metadata: - namespace: - -image: - #Provide the containerName of image - #Eg. containerName: hyperledgerlabs/h2:2018 - containerName: - #Provide the name of image for init container - #Eg. name: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: - -nodeConf: - #Provide the p2pUrl for node - #Eg. p2pUrl: rp-elb-corda-kube-check-cluster1-144808561.us-east-1.elb.amazonaws.com - p2p: - url: - port: - rpcSettings: - useSsl: - standAloneBroker: - address: - adminAddress: - ssl: - certificatesDirectory: - sslKeystorePath: - trustStoreFilePath: - #Provide the legalName for node - #Eg. legalName: "O=Bank1,L=London,C=GB,CN=Bank1" - legalName: - messagingServerAddress: - jvmArgs: - systemProperties: - sshd: - port: - exportJMXTo: - transactionCacheSizeMegaBytes: - attachmentContentCacheSizeMegaBytes: - notary: - validating: - detectPublicIp: - extraAdvertisedServiceIds: - database: - serverNameTablePrefix: - exportHibernateJMXStatistics: - runMigration: - #Provide the h2Url for node - #Eg. h2Url: bank1h2 - dbUrl: - #Provide the h2Port for node - #Eg. h2Port: 9101 - dbPort: - dataSourceClassName: - dataSourceUrl: - jarPath: - #Provide the nms for node - #Eg. nms: "http://rp-elb-fra-corda-kube-cluster7-2016021309.us-west-1.elb.amazonaws.com:30050" - networkMapURL: - doormanURL: - compatibilityZoneURL: - webAddress: - #Provide the jar Version for corda jar and finanace jar - #Eg. jarVersion: 3.3-corda - jarVersion: - #Provide the devMode for corda node - #Eg. devMode: true - devMode: - #Provide the useHTTPS for corda node - #Eg. useHTTPS: false - useHTTPS: - env: - - name: - value: - -credentials: - #Provide the dataSourceUser for corda node - #Eg. dataSourceUser: sa - dataSourceUser: - #Provide the rpcUser for corda node - #Eg. rpcUser: bank1operations - rpcUser: - - name: - permissions: - -volume: - mountPath: - -resources: - #Provide the limit memory for node - #Eg. limits: "1Gi" - limits: - #Provide the requests memory for node - #Eg. requests: "1Gi" - requests: - -storage: - #Provide the memory for node - #Eg. memory: 4Gi - provisioner: - memory: - type: - -service: - #Provide the type of service - #Eg. type: NodePort or LoadBalancer etc - type: - p2p: - #Provide the p2p port for node - #Eg. port: 10007 - port: - #Provide the p2p node port for node - #Eg. port: 30007 - nodePort: - #Provide the p2p targetPort for node - #Eg. targetPort: 30007 - targetPort: - rpc: - #Provide the rpc port for node - #Eg. port: 10008 - port: - #Provide the p2p targetPort for node - #Eg. targetPort: 10003 - targetPort: - #Provide the p2p node port for node - #Eg. nodePort: 30007 - nodePort: - rpcadmin: - #Provide the rpcadmin port for node - #Eg. port: 10108 - port: - #Provide the p2p targetPort for node - #Eg. targetPort: 10005 - targetPort: - #Provide the p2p node port for node - #Eg. nodePort: 30007 - nodePort: -jobservice: - type: - p2p: - nodePort: - rpc: - nodePort: - rpcadmin: - nodePort: - -vault: - #Provide the vault server address - #Eg. address: http://54.226.163.39:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: - #Provide the authpath - #Eg. authpath: cordabank1 - authpath: - #Provide the serviceaccountname - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: - #Provide the secretprefix - #Eg. secretprefix: issuer - secretprefix: - -db: - #Provide the interval in seconds you want to iterate till db to be ready - #Eg. readinesscheckinterval: 5 - readinesscheckinterval: - #Provide the threshold till you want to check if specified db up and running - #Eg. readinessthreshold: 2 - readinessthreshold: diff --git a/platforms/r3-corda/charts/corda-h2-password-change/Chart.yaml b/platforms/r3-corda/charts/corda-h2-password-change/Chart.yaml deleted file mode 100644 index 79c7fbb28df..00000000000 --- a/platforms/r3-corda/charts/corda-h2-password-change/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: A Helm chart for registering the notary with the nms -name: corda-h2-pass-change -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-h2-password-change/templates/job.yaml b/platforms/r3-corda/charts/corda-h2-password-change/templates/job.yaml deleted file mode 100644 index 54be140e38d..00000000000 --- a/platforms/r3-corda/charts/corda-h2-password-change/templates/job.yaml +++ /dev/null @@ -1,158 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: batch/v1 -kind: Job -metadata: - name: h2-pass-change-{{ .Values.nodeName }} - labels: - app: h2-pass-change-{{ .Values.nodeName }} - app.kubernetes.io/name: h2-pass-change-{{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - backoffLimit: 6 - ttlSecondsAfterFinished: 300 - template: - metadata: - labels: - app: h2-pass-change-{{ .Values.nodeName }} - app.kubernetes.io/name: h2-pass-change-{{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - restartPolicy: "OnFailure" - serviceAccountName: {{ .Values.vault.serviceaccountname }} - containers: - - name: h2-pass-change - image: {{ .Values.image.containerName }} - imagePullPolicy: Always - env: - - name: MOUNT_PATH - value: /opt/h2 - - name: SECRET_PREFIX - value: {{ .Values.vault.dbsecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - export SA_PASSWORD=`cat /opt/db/creds/db_cred` - cat << EOF > ${MOUNT_PATH}/changepass.sql - ALTER USER SA SET PASSWORD '${SA_PASSWORD}'; - EOF - - chmod 777 ${MOUNT_PATH}/changepass.sql - H2JARPATH=${MOUNT_PATH}/bin/h2*.jar - H2SCRIPTCLASSPATH=org.h2.tools.RunScript - - java -cp ${H2JARPATH} ${H2SCRIPTCLASSPATH} -url {{ .Values.jdbcUrl }} -user sa -script ${MOUNT_PATH}/changepass.sql - echo "Password for SA changed" - volumeMounts: - - name: {{ .Values.nodeName }}volume - mountPath: "/opt/h2-data" - - name: creds - mountPath: "/opt/db/creds" - readOnly: false - initContainers: - - name: init-credential - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: /opt/db/creds - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: DB_SECRET_PREFIX - value: {{ .Values.vault.dbsecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "${DB_SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE}" "LOOKUPSECRETRESPONSE" - SA_PASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["sa"]') - echo "${SA_PASSWORD}" >> ${MOUNT_PATH}/db_cred - volumeMounts: - - name: creds - mountPath: "/opt/db/creds" - readOnly: false - - name: db-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - while [ "$COUNTER" -le {{ $.Values.db.readinessthreshold }} ] - do - DB_NODE={{ .Values.dbUrl }}:{{ .Values.dbPort }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.db.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.db.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - if [ "$COUNTER" -gt {{ $.Values.db.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: {{ .Values.nodeName }}volume - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}db-pvc - - name: creds - emptyDir: - medium: Memory \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-h2-password-change/values.yaml b/platforms/r3-corda/charts/corda-h2-password-change/values.yaml deleted file mode 100644 index 927b499e6e2..00000000000 --- a/platforms/r3-corda/charts/corda-h2-password-change/values.yaml +++ /dev/null @@ -1,184 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# This is a YAML-formatted file. -# This should be produced by build - -#Provide the nodeName for node -#Eg. nodeName: bank1 -nodeName: - -metadata: - namespace: - -image: - #Provide the containerName of image - #Eg. containerName: hyperledgerlabs/h2:2018 - containerName: - #Provide the name of image for init container - #Eg. name: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: - -nodeConf: - #Provide the p2pUrl for node - #Eg. p2pUrl: rp-elb-corda-kube-check-cluster1-144808561.us-east-1.elb.amazonaws.com - p2p: - url: - port: - rpcSettings: - useSsl: - standAloneBroker: - address: - adminAddress: - ssl: - certificatesDirectory: - sslKeystorePath: - trustStoreFilePath: - #Provide the legalName for node - #Eg. legalName: "O=Bank1,L=London,C=GB,CN=Bank1" - legalName: - messagingServerAddress: - jvmArgs: - systemProperties: - sshd: - port: - exportJMXTo: - transactionCacheSizeMegaBytes: - attachmentContentCacheSizeMegaBytes: - notary: - validating: - detectPublicIp: - extraAdvertisedServiceIds: - database: - serverNameTablePrefix: - exportHibernateJMXStatistics: - runMigration: - #Provide the h2Url for node - #Eg. h2Url: bank1h2 - dbUrl: - #Provide the h2Port for node - #Eg. h2Port: 9101 - dbPort: - dataSourceClassName: - dataSourceUrl: - jarPath: - #Provide the nms for node - #Eg. nms: "http://rp-elb-fra-corda-kube-cluster7-2016021309.us-west-1.elb.amazonaws.com:30050" - networkMapURL: - doormanURL: - compatibilityZoneURL: - webAddress: - #Provide the jar Version for corda jar and finanace jar - #Eg. jarVersion: 3.3-corda - jarVersion: - #Provide the devMode for corda node - #Eg. devMode: true - devMode: - #Provide the useHTTPS for corda node - #Eg. useHTTPS: false - useHTTPS: - env: - - name: - value: - -credentials: - #Provide the dataSourceUser for corda node - #Eg. dataSourceUser: sa - dataSourceUser: - #Provide the rpcUser for corda node - #Eg. rpcUser: bank1operations - rpcUser: - - name: - permissions: - -volume: - mountPath: - -resources: - #Provide the limit memory for node - #Eg. limits: "1Gi" - limits: - #Provide the requests memory for node - #Eg. requests: "1Gi" - requests: - -storage: - #Provide the memory for node - #Eg. memory: 4Gi - provisioner: - memory: - type: - -service: - #Provide the type of service - #Eg. type: NodePort or LoadBalancer etc - type: - p2p: - #Provide the p2p port for node - #Eg. port: 10007 - port: - #Provide the p2p node port for node - #Eg. port: 30007 - nodePort: - #Provide the p2p targetPort for node - #Eg. targetPort: 30007 - targetPort: - rpc: - #Provide the rpc port for node - #Eg. port: 10008 - port: - #Provide the p2p targetPort for node - #Eg. targetPort: 10003 - targetPort: - #Provide the p2p node port for node - #Eg. nodePort: 30007 - nodePort: - rpcadmin: - #Provide the rpcadmin port for node - #Eg. port: 10108 - port: - #Provide the p2p targetPort for node - #Eg. targetPort: 10005 - targetPort: - #Provide the p2p node port for node - #Eg. nodePort: 30007 - nodePort: -jobservice: - type: - p2p: - nodePort: - rpc: - nodePort: - rpcadmin: - nodePort: - -vault: - #Provide the vault server address - #Eg. address: http://54.226.163.39:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: - #Provide the authpath - #Eg. authpath: cordabank1 - authpath: - #Provide the serviceaccountname - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: - #Provide the secretprefix - #Eg. secretprefix: issuer - secretprefix: - -db: - #Provide the interval in seconds you want to iterate till db to be ready - #Eg. readinesscheckinterval: 5 - readinesscheckinterval: - #Provide the threshold till you want to check if specified db up and running - #Eg. readinessthreshold: 2 - readinessthreshold: diff --git a/platforms/r3-corda/charts/corda-h2/.helmignore b/platforms/r3-corda/charts/corda-h2/.helmignore deleted file mode 100644 index f0c13194444..00000000000 --- a/platforms/r3-corda/charts/corda-h2/.helmignore +++ /dev/null @@ -1,21 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj diff --git a/platforms/r3-corda/charts/corda-h2/Chart.yaml b/platforms/r3-corda/charts/corda-h2/Chart.yaml deleted file mode 100644 index 6403de42645..00000000000 --- a/platforms/r3-corda/charts/corda-h2/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Deploys H2 DB." -name: corda-h2 -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-h2/README.md b/platforms/r3-corda/charts/corda-h2/README.md deleted file mode 100644 index 4338167988d..00000000000 --- a/platforms/r3-corda/charts/corda-h2/README.md +++ /dev/null @@ -1,174 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# H2 Deployment - -- [h2 Deployment Helm Chart](#h2-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - -## h2 Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-h2) deploys Kubernetes deployment resource for h2 database. - - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- Node's database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - - -## Chart Structure ---- -This chart has following structue: - -``` - - ├── h2 - │ ├── Chart.yaml - │ ├── templates - │ │ ├── deployment.yaml - │ │ ├── pvc.yaml - │ │ └── service.yaml - │ └── values.yaml -``` -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `deployment.yaml` : This file is a configuration file for deployement in Kubernetes.It creates a deployment file with a specified number of replicas and defines various settings for the deployment.Including volume mounts, environment variables, and ports for the container. -- `pvc.yaml` : A PersistentVolumeClaim (PVC) is a request for storage by a user. -- `service.yaml` : This file defines a Kubernetes Service with multiple ports for protocols and targets, and supports Ambassador proxy annotations for specific configurations when using the "ambassador" proxy provider. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the image, resources, storage, service, etc. - - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-h2/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | "" | - -### Image - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| containerName | Provide the containerName of image | "" | -| imagePullSecret | Provide the image pull secret of image | regcred | - -### Resources - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------ | --------------- | -| limits | Provide the limit memory for node | "1Gi" | -| requests | Provide the requests memory for node | "1Gi" | - -### storage - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| Memory | Provide the memory for node | "4Gi" | -| MountPath | The path where the volume will be mounted | "" | - -### Service - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| type | Provide the type of service | NodePort | -| tcp port | Provide the tcp port for node | 9101 | -| nodePort | Provide the tcp node port for node | 32001 | -| targetPort | Provide the tcp targetPort for node | 1521 | - -## WEB - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| nodePort | Provide the web node port for node | 32080 | -| targetPort | Provide the tcp targetPort for node | 81 | -| port | Provide the tcp node port for node | 8080 | - - - - -## Deployment ---- - -To deploy the h2 Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-h2/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade, verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-h2 -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-h2 -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [h2 Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-h2), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-h2/templates/deployment.yaml b/platforms/r3-corda/charts/corda-h2/templates/deployment.yaml deleted file mode 100644 index bbf7c6826a2..00000000000 --- a/platforms/r3-corda/charts/corda-h2/templates/deployment.yaml +++ /dev/null @@ -1,71 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.nodeName }}db - {{- if .Values.deployment.annotations }} - annotations: -{{ toYaml .Values.deployment.annotations | indent 8 }} - {{- end }} - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }}db - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - replicas: 1 - selector: - matchLabels: - app: {{ .Values.nodeName }}db - app.kubernetes.io/name: {{ .Values.nodeName }}db - app.kubernetes.io/instance: {{ .Release.Name }} - strategy: - type: Recreate - rollingUpdate: null - template: - metadata: - labels: - app: {{ .Values.nodeName }}db - app.kubernetes.io/name: {{ .Values.nodeName }}db - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - hostname: {{ .Values.nodeName }}db - securityContext: - fsGroup: 1000 - containers: - - name: {{ .Values.nodeName }}db - image: {{ .Values.image.containerName }} - resources: - limits: - memory: {{ .Values.resources.limits }} - requests: - memory: {{ .Values.resources.requests }} - ports: - - containerPort: 1521 - name: p2p - - containerPort: 81 - name: web - env: - - name: JAVA_OPTIONS - value: -Xmx512m - volumeMounts: - - name: db - mountPath: {{ .Values.storage.mountPath }} - readOnly: false - livenessProbe: - tcpSocket: - port: 1521 - initialDelaySeconds: 15 - periodSeconds: 20 - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: db - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}db-pvc diff --git a/platforms/r3-corda/charts/corda-h2/templates/pvc.yaml b/platforms/r3-corda/charts/corda-h2/templates/pvc.yaml deleted file mode 100644 index d35838beab0..00000000000 --- a/platforms/r3-corda/charts/corda-h2/templates/pvc.yaml +++ /dev/null @@ -1,27 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.nodeName }}db-pvc - {{- if .Values.pvc.annotations }} - annotations: -{{ toYaml .Values.pvc.annotations | indent 8 }} - {{- end }} - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }}db-pvc - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - storageClassName: {{ .Values.storage.name }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.storage.memory }} \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-h2/templates/service.yaml b/platforms/r3-corda/charts/corda-h2/templates/service.yaml deleted file mode 100644 index 80fda163eac..00000000000 --- a/platforms/r3-corda/charts/corda-h2/templates/service.yaml +++ /dev/null @@ -1,40 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.nodeName }}db - {{- if .Values.service.annotations }} - annotations: -{{ toYaml .Values.service.annotations | indent 8 }} - {{- end }} - namespace: {{ .Values.metadata.namespace }} - labels: - run: {{ .Values.nodeName }}db - app.kubernetes.io/name: {{ $.Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - type: {{ .Values.service.type }} - selector: - app: {{ .Values.nodeName }}db - ports: - - name: tcp - protocol: TCP - port: {{ .Values.service.tcp.port }} - targetPort: {{ .Values.service.tcp.targetPort}} - {{- if .Values.service.tcp.nodePort }} - nodePort: {{ .Values.service.tcp.nodePort}} - {{- end }} - - name: web - protocol: TCP - port: {{ .Values.service.web.port }} - targetPort: {{ .Values.service.web.targetPort }} - {{- if .Values.service.web.nodePort }} - nodePort: {{ .Values.service.web.nodePort}} - {{- end }} diff --git a/platforms/r3-corda/charts/corda-h2/values.yaml b/platforms/r3-corda/charts/corda-h2/values.yaml deleted file mode 100644 index 5b064de652e..00000000000 --- a/platforms/r3-corda/charts/corda-h2/values.yaml +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Default values for nodechart. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -#Provide the Name for node to be deployed -#Eg. nodeName: bank1 -nodeName: - -image: - #Provide the name of image for container - #Eg. containerName: hyperledgerlabs/h2:2018 - containerName: hyperledgerlabs/h2:2018 - #Provide the name of image for init container - #Eg. name: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: "" - -resources: - #Provide the limit memory for node - #Eg. limits: "1Gi" - limits: "1Gi" - #Provide the requests memory for node - #Eg. requests: "1Gi" - requests: "1Gi" - -storage: - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - mountPath: - -service: - #Provide the type of service - #Eg. type: NodePort - type: NodePort - tcp: - #Provide the tcp port for node - #Eg. port: 9101 - port: 9101 - #Provide the tcp node port for node - #Eg. port: 32001 - nodePort: - #Provide the tcp targetPort for node - #Eg. targetPort: 1521 - targetPort: 1521 - web: - #Provide the web node port for node - #Eg. port: 32080 - nodePort: - #Provide the tcp targetPort for node - #Eg. targetPort: 81 - targetPort: 81 - #Provide the tcp node port for node - #Eg. port: 8080 - port: 8080 diff --git a/platforms/r3-corda/charts/corda-init/Chart.yaml b/platforms/r3-corda/charts/corda-init/Chart.yaml new file mode 100644 index 00000000000..775fec7b694 --- /dev/null +++ b/platforms/r3-corda/charts/corda-init/Chart.yaml @@ -0,0 +1,25 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## + +apiVersion: v1 +name: corda-init +description: "R3 Corda: Initializes Corda network." +version: 1.0.0 +appVersion: "latest" +keywords: + - bevel + - corda + - hyperledger + - enterprise + - blockchain + - deployment + - accenture +home: https://hyperledger-bevel.readthedocs.io/en/latest/ +sources: + - https://github.com/hyperledger/bevel +maintainers: + - name: Hyperledger Bevel maintainers + email: bevel@lists.hyperledger.org diff --git a/platforms/r3-corda/charts/corda-init/README.md b/platforms/r3-corda/charts/corda-init/README.md new file mode 100644 index 00000000000..2fcadafa7a8 --- /dev/null +++ b/platforms/r3-corda/charts/corda-init/README.md @@ -0,0 +1,96 @@ +[//]: # (##############################################################################################) +[//]: # (Copyright Accenture. All Rights Reserved.) +[//]: # (SPDX-License-Identifier: Apache-2.0) +[//]: # (##############################################################################################) + +# corda-init + +This chart is a component of Hyperledger Bevel. The corda-init chart initializes a Kubernetes namespace for Corda network. See [Bevel documentation](https://hyperledger-bevel.readthedocs.io/en/latest/) for details. + +## TL;DR + +```bash +helm repo add bevel https://hyperledger.github.io/bevel +helm install init bevel/corda-init +``` + +## Prerequisitess + +- Kubernetes 1.19+ +- Helm 3.2.0+ + +If Hashicorp Vault is used, then +- HashiCorp Vault Server 1.13.1+ + +> **Important**: Also check the dependent charts. + +## Installing the Chart + +To install the chart with the release name `init`: + +```bash +helm repo add bevel https://hyperledger.github.io/bevel +helm install init bevel/corda-init +``` + +The command deploys the chart on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `init` deployment: + +```bash +helm uninstall init +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Parameters + +### Global parameters +These parameters are refered to as same in each parent or child chart +| Name | Description | Default Value | +|--------|---------|-------------| +|`global.serviceAccountName` | The serviceaccount name that will be created for Vault Auth and k8S Secret management| `vault-auth` | +| `global.cluster.provider` | Kubernetes cluster provider like AWS EKS or minikube. Currently ony `aws` and `minikube` is tested | `aws` | +| `global.cluster.cloudNativeServices` | only `false` is implemented, `true` to use Cloud Native Services (SecretsManager and IAM for AWS; KeyVault & Managed Identities for Azure) is for future | `false` | +| `global.cluster.kubernetesUrl` | URL of the Kubernetes Cluster | `""` | +| `global.vault.type` | Type of Vault to support other providers. Currently, only `hashicorp` and `kubernetes` is supported. | `hashicorp` | +| `global.vault.role` | Role used for authentication with Vault | `vault-role` | +| `global.vault.network` | Network type that is being deployed | `corda` | +| `global.vault.address`| URL of the Vault server. | `""` | +| `global.vault.authPath` | Authentication path for Vault | `supplychain` | +| `global.vault.secretEngine` | The value for vault secret engine name | `secretsv2` | +| `global.vault.secretPrefix` | The value for vault secret prefix which must start with `data/` | `data/supplychain` | + +### Settings + +| Name | Description | Default Value | +|--------|---------|-------------| +| `settings.secondaryInit` | Flag to doorman and nms certs from `files` for additional nodes, true only when tls: true | `false` | + +## License + +This chart is licensed under the Apache v2.0 license. + +Copyright © 2024 Accenture + +### Attribution + +This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: + +``` +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. +``` diff --git a/platforms/r3-corda/charts/corda-certs-gen/files/openssl.conf b/platforms/r3-corda/charts/corda-init/files/openssl.conf similarity index 100% rename from platforms/r3-corda/charts/corda-certs-gen/files/openssl.conf rename to platforms/r3-corda/charts/corda-init/files/openssl.conf diff --git a/platforms/r3-corda/charts/corda-init/requirements.yaml b/platforms/r3-corda/charts/corda-init/requirements.yaml new file mode 100644 index 00000000000..b1195396c5f --- /dev/null +++ b/platforms/r3-corda/charts/corda-init/requirements.yaml @@ -0,0 +1,11 @@ +dependencies: + - name: bevel-vault-mgmt + repository: "file://../../../shared/charts/bevel-vault-mgmt" + tags: + - bevel + version: ~1.0.0 + - name: bevel-scripts + repository: "file://../../../shared/charts/bevel-scripts" + tags: + - bevel + version: ~1.0.0 diff --git a/platforms/r3-corda/charts/corda-init/templates/_helpers.tpl b/platforms/r3-corda/charts/corda-init/templates/_helpers.tpl new file mode 100644 index 00000000000..0dea3f2bbea --- /dev/null +++ b/platforms/r3-corda/charts/corda-init/templates/_helpers.tpl @@ -0,0 +1,29 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "corda-init.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 "corda-init.fullname" -}} +{{- $name := default .Chart.Name -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" $name .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "corda-init.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/platforms/r3-corda/charts/corda-init/templates/configmap.yaml b/platforms/r3-corda/charts/corda-init/templates/configmap.yaml new file mode 100644 index 00000000000..a1b3a7bfc69 --- /dev/null +++ b/platforms/r3-corda/charts/corda-init/templates/configmap.yaml @@ -0,0 +1,53 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: openssl-conf + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: "openssl-config" + app.kubernetes.io/part-of: {{ include "corda-init.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +data: + openssl.conf: |+ +{{ .Files.Get "files/openssl.conf" | indent 4 }} +{{- if .Values.settings.secondaryInit }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: doorman-tls-certs + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: "doorman-tls-certs" + app.kubernetes.io/part-of: {{ include "corda-init.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +data: + tls.crt: |+ +{{ .Files.Get "files/doorman.crt" | indent 4 }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: nms-tls-certs + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: "nms-tls-certs" + app.kubernetes.io/part-of: {{ include "corda-init.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +data: + tls.crt: |+ +{{ .Files.Get "files/nms.crt" | indent 4 }} +{{- end }} diff --git a/platforms/r3-corda/charts/corda-init/values.yaml b/platforms/r3-corda/charts/corda-init/values.yaml new file mode 100644 index 00000000000..9e9cebe0d29 --- /dev/null +++ b/platforms/r3-corda/charts/corda-init/values.yaml @@ -0,0 +1,35 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +global: + #Provide the service account name which will be created. + serviceAccountName: vault-auth + cluster: + provider: aws # choose from: minikube | aws | azure | gcp + cloudNativeServices: false # only 'false' is implemented + #Provide the kubernetes host url + #Eg. kubernetesUrl: https://10.3.8.5:8443 + kubernetesUrl: + vault: + #Provide the type of vault + type: hashicorp + #Provide the vault role used. + role: vault-role + #Provide the network type + network: corda + #Provide the vault server address + address: + #Provide the vault authPath configured to be used. + authPath: supplychain + #Provide the secret engine. + secretEngine: secretsv2 + #Provide the vault path where the secrets will be stored + secretPrefix: "data/supplychain" + +settings: + # Flag to copy doorman and nms certs, true only when tls: true + secondaryInit: false diff --git a/platforms/r3-corda/charts/corda-mongodb-tls/Chart.yaml b/platforms/r3-corda/charts/corda-mongodb-tls/Chart.yaml deleted file mode 100644 index c6b47e9be54..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb-tls/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Deploys mongodb with tls enabled, used for doorman and networkmap." -name: corda-mongodb-tls -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-mongodb-tls/README.md b/platforms/r3-corda/charts/corda-mongodb-tls/README.md deleted file mode 100644 index df0ad44e0d8..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb-tls/README.md +++ /dev/null @@ -1,158 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# Mongodb-tls Deployment - -- [Mongodb-tls Deployment Helm Chart](#Mongodb-tls-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - -## Mongodb-tls Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-mongodb-tls) deploys MongoDB with tls enabled. - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- Mongodb database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - -## Chart Structure ---- -This chart has following structue: - -``` - - ├── mongodb-tls - │ ├── Chart.yaml - │ ├── templates - │ │ ├── deployment.yaml - │ │ ├── pvc.yaml - │ │ └── service.yaml - │ └── values.yaml -``` - -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `deployment.yaml` : This deployment file can deploy a MongoDB database in a Kubernetes cluster, manages a MongoDB replica set and it configures environment variables for the MongoDB root username and password. And also its includes ports, volume mounts and initialization tasks using init containers. -- `pvc.yaml` : A PersistentVolumeClaim (PVC) is a request for storage by a user. -- `service.yaml` : This file defines a Kubernetes Service with multiple ports for protocols and targets, and supports Ambassador proxy annotations for specific configurations when using the "ambassador" proxy provider. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the image, storage and service. - - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-mongodb-tls/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | mongodb-doorman | - -### Image - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| containerName | Provide the containerName of image | "" | - -### storage - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| Memory | Provide the memory for node | "4Gi" | -| MountPath | The path where the volume will be mounted | "" | - -### Service - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| type | Provide the type of service | "NodePort" | -| tcp port | Provide the tcp port for node | "9101" | -| nodePort | Provide the tcp node port for node | "32001" | -| targetPort | Provide the tcp targetPort for node | "27017" | - - - -## Deployment ---- - -To deploy the Mongodb-tls Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-mongodb-tls/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade, verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-mongodb-tls -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-mongodb-tls -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [Mongodb-tls Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-mongodb-tls), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-mongodb-tls/templates/deployment.yaml b/platforms/r3-corda/charts/corda-mongodb-tls/templates/deployment.yaml deleted file mode 100644 index 81079a5c330..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb-tls/templates/deployment.yaml +++ /dev/null @@ -1,184 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.nodeName }} - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.deployment.annotations }} - annotations: -{{ toYaml .Values.deployment.annotations | indent 8 }} - {{- end }} - labels: - appdb: {{ .Values.nodeName }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - appdb: {{ .Values.nodeName }} - template: - metadata: - labels: - appdb: {{ .Values.nodeName }} - spec: - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: {{ .Values.nodeName }} - image: {{ .Values.image.containerName }} - env: - - name: MONGO_INITDB_ROOT_USERNAME_FILE - value: /run/secrets/db_root_username - - name: MONGO_INITDB_ROOT_PASSWORD_FILE - value: /run/secrets/db_root_password - command: - - /bin/sh - - -c - - > - if [ -f /data/db/admin-user.lock ]; then - #file /data/db/admin-user.lock created and checked to ensure mongod is fully up for adding new db user in postStart hook. - echo "KUBERNETES LOG $HOSTNAME- Starting Mongo Daemon" - - # ensure wiredTigerCacheSize is set within the size of the containers memory limit, Setting up with tag --sslAllowConnectionsWithoutCertificates only client validates the server to ensure that it receives data from the intended server. - if [ "$HOSTNAME" = "{{ $.Values.nodeName }}" ]; then - #for Mongodb single server. - echo "check 1" - mongod --wiredTigerCacheSizeGB 0.25 --bind_ip 0.0.0.0 --sslMode requireSSL --sslPEMKeyFile /etc/ssl/{{ $.Values.nodeName }}.pem --sslCAFile /etc/ssl/mongoCA.crt --sslAllowConnectionsWithoutCertificates --sslAllowInvalidHostnames --auth; - fi; - else - echo "KUBERNETES LOG $HOSTNAME- Starting Mongo Daemon with setup setting (authMode)" - mongod --auth; - fi; - lifecycle: - postStart: - exec: - command: - - /bin/sh - - -c - - > - if [ ! -f /data/db/admin-user.lock ]; then - echo "KUBERNETES LOG $HOSTNAME no Admin-user.lock file found yet" - # user name and password for creation of new db user. - DB_PASSWORD=`cat /run/secrets/db_root_password` - DB_USERNAME=`cat /run/secrets/db_root_username` - # sleep 20 to 'ensure' mongod is accepting connections for creating db user. - sleep 20; - touch /data/db/admin-user.lock - # Adding database user with password in admin database, checking for host name to create new db user. - if [ "$HOSTNAME" = "{{ .Values.nodeName }}" ]; then - echo "KUBERNETES LOG $HOSTNAME- creating admin user doorman" - # Adding database user in admin db using mongo shell command. - mongo --eval "db = db.getSiblingDB('admin'); db.createUser({ user: '${DB_USERNAME}', pwd: '${DB_PASSWORD}', roles: [{ role: 'root', db: 'admin' }]});" >> /data/db/config.log - fi; - echo "KUBERNETES LOG $HOSTNAME-shutting mongod down for final restart" - mongod --shutdown; - fi; - ports: - - containerPort: {{ .Values.service.tcp.targetPort }} - volumeMounts: - - name: {{ .Values.storage.volname }} - mountPath: {{ .Values.storage.mountPath }} - - name: creds - mountPath: "/run/secrets" - readOnly: false - - name: certs - mountPath: "/etc/ssl" - readOnly: false - initContainers: - - name: init-credential - image : {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: /run/secrets - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - - name: CERT_SECRET_PREFIX - value: {{.Values.vault.certsecretprefix}} - - name: MONGODB_USERNAME - value: {{.Values.mongodb.username}} - command: ["/bin/sh","-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - echo "Getting secrets from Vault Server" - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${MOUNT_PATH} - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${SECRET_PREFIX} | jq -r 'if .errors then . else . end') - - validateVaultResponse "${SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE}" "LOOKUPSECRETRESPONSE" - - - MONGODB_PASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["mongodbPassword"]') - - echo "${MONGODB_PASSWORD}" >> ${MOUNT_PATH}/db_root_password - echo "${MONGODB_USERNAME}" >> ${MOUNT_PATH}/db_root_username - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERT_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - - # Validating vault response for mongodb certificates. - validateVaultResponse "${CERT_SECRET_PREFIX}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - - # Getting certificates of server from vault and storing into /etc/ssl. - SERVER_CERT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["{{ $.Values.nodeName }}.pem"]') - echo "${SERVER_CERT}" | base64 -d > /etc/ssl/{{ $.Values.nodeName }}.pem - - # Getting certificate authority cert from vault which is required for client validation and storing into /etc/ssl. - CA_CERT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["mongoCA.crt"]') - echo "${CA_CERT}" | base64 -d > /etc/ssl/mongoCA.crt - volumeMounts: - - name: creds - mountPath: "/run/secrets" - readOnly: false - - name: certs - mountPath: "/etc/ssl" - readOnly: false - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: {{ .Values.storage.volname }} - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}-pvc - - name: creds - emptyDir: - medium: Memory - - name: certs - emptyDir: - medium: Memory - \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-mongodb-tls/templates/pvc.yaml b/platforms/r3-corda/charts/corda-mongodb-tls/templates/pvc.yaml deleted file mode 100644 index 37d95dcfd6b..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb-tls/templates/pvc.yaml +++ /dev/null @@ -1,26 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.nodeName }}-pvc - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.pvc.annotations }} - annotations: -{{ toYaml .Values.pvc.annotations | indent 8 }} - {{- end }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }}-pvc - app: {{ .Values.nodeName }}-pv -spec: - storageClassName: {{ .Values.storage.name }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.storage.memory }} - \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-mongodb-tls/templates/service.yaml b/platforms/r3-corda/charts/corda-mongodb-tls/templates/service.yaml deleted file mode 100644 index b3a105db29e..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb-tls/templates/service.yaml +++ /dev/null @@ -1,31 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.nodeName }} - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.service.annotations }} - annotations: -{{ toYaml .Values.service.annotations | indent 8 }} - {{- end }} - labels: - run: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app: {{ .Values.nodeName }} -spec: - type: {{ .Values.service.type }} - ports: - - protocol: TCP - port: {{ .Values.service.tcp.port }} - targetPort: {{ .Values.service.tcp.targetPort }} - {{- if .Values.service.tcp.nodePort }} - nodePort: {{ .Values.service.tcp.nodePort}} - {{- end }} - selector: - appdb: {{ .Values.nodeName }} - diff --git a/platforms/r3-corda/charts/corda-mongodb-tls/values.yaml b/platforms/r3-corda/charts/corda-mongodb-tls/values.yaml deleted file mode 100644 index 239b7e61235..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb-tls/values.yaml +++ /dev/null @@ -1,38 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Default values for nodechart. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -#Provide the Name for node to be deployed -#Eg. nodeName: mongodb-doorman -nodeName: mongodb-doorman -replicas: -image: - #Provide the name of image for container - #Eg. containerName: hyperledgerlabs/h2:2018 - containerName: hyperledgerlabs/h2:2018 -storage: - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - name: - mountPath: -service: - #Provide the type of service - #Eg. type: NodePort - type: NodePort - tcp: - #Provide the tcp port for node - #Eg. port: 9101 - port: 9101 - #Provide the tcp node port for node - #Eg. port: 32001 - nodePort: - #Provide the tcp node port for node - #Eg. targetPort: 27017 - targetPort: 27017 diff --git a/platforms/r3-corda/charts/corda-mongodb/Chart.yaml b/platforms/r3-corda/charts/corda-mongodb/Chart.yaml deleted file mode 100644 index ff49aabd3f2..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Deploys MongoDB, used for doorman and networkmap." -name: corda-mongodb -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-mongodb/README.md b/platforms/r3-corda/charts/corda-mongodb/README.md deleted file mode 100644 index e0db2a97c02..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb/README.md +++ /dev/null @@ -1,158 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# Mongodb Deployment - -- [Mongodb Deployment Helm Chart](#Mongodb-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - -## Mongodb Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-mongodb) deploys Mongodb. - - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- Mongodb database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - -## Chart Structure ---- -This chart has following structue: - -``` - - ├── mongodb - │ ├── Chart.yaml - │ ├── templates - │ │ ├── deployment.yaml - │ │ ├── pvc.yaml - │ │ └── service.yaml - │ └── values.yaml -``` - -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `deployment.yaml` : This Deployment manages a MongoDB replica set of a Pod template, including volume mounts, environment variables, and ports for the container. -- `pvc.yaml` : A PersistentVolumeClaim (PVC) is a request for storage by a user. -- `service.yaml` : This file defines a Kubernetes Service with multiple ports for protocols and targets, and supports Ambassador proxy annotations for specific configurations when using the "ambassador" proxy provider. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the image, storage and service. - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-mongodb/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | mongodb | - -### Image - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| containerName | Provide the containerName of image | "" | - -### storage - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| Memory | Provide the memory for node | "4Gi" | -| MountPath | The path where the volume will be mounted | "" | - -### Service - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| type | Provide the type of service | "NodePort" | -| tcp port | Provide the tcp port for node | "9101" | -| nodePort | Provide the tcp node port for node | "32001" | -| targetPort | Provide the tcp targetPort for node | "27017" | - - - -## Deployment ---- - -To deploy the Mongodb Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-mongodb/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade, verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-mongodb -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-mongodb -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [Mongodb Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-mongodb), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-mongodb/templates/deployment.yaml b/platforms/r3-corda/charts/corda-mongodb/templates/deployment.yaml deleted file mode 100644 index 56560a46b66..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb/templates/deployment.yaml +++ /dev/null @@ -1,117 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.nodeName }} - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.deployment.annotations }} - annotations: -{{ toYaml .Values.deployment.annotations | indent 8 }} - {{- end }} - labels: - appdb: {{ .Values.nodeName }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - appdb: {{ .Values.nodeName }} - template: - metadata: - labels: - appdb: {{ .Values.nodeName }} - spec: - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: {{ .Values.nodeName }} - image: {{ .Values.image.containerName }} - env: - - name: MONGO_INITDB_ROOT_USERNAME_FILE - value: /run/secrets/db_root_username - - name: MONGO_INITDB_ROOT_PASSWORD_FILE - value: /run/secrets/db_root_password - ports: - - containerPort: {{ .Values.service.tcp.targetPort }} - volumeMounts: - - name: {{ .Values.storage.volname }} - mountPath: {{ .Values.storage.mountPath }} - - name: creds - mountPath: "/run/secrets" - readOnly: false - initContainers: - - name: init-credential - image : {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: /run/secrets - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - - name: MONGODB_USERNAME - value: {{.Values.mongodb.username}} - command: ["/bin/sh","-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - echo "Getting secrets from Vault Server" - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${MOUNT_PATH} - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${SECRET_PREFIX} | jq -r 'if .errors then . else . end') - - validateVaultResponse "${SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE}" "LOOKUPSECRETRESPONSE" - - MONGODB_PASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["mongodbPassword"]') - - echo "${MONGODB_PASSWORD}" >> ${MOUNT_PATH}/db_root_password - echo "${MONGODB_USERNAME}" >> ${MOUNT_PATH}/db_root_username - - volumeMounts: - - name: creds - mountPath: "/run/secrets" - readOnly: false - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: {{ .Values.storage.volname }} - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}-pvc - - name: creds - emptyDir: - medium: Memory \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-mongodb/templates/pvc.yaml b/platforms/r3-corda/charts/corda-mongodb/templates/pvc.yaml deleted file mode 100644 index d19ff565673..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb/templates/pvc.yaml +++ /dev/null @@ -1,25 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.nodeName }}-pvc - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.pvc.annotations }} - annotations: -{{ toYaml .Values.pvc.annotations | indent 8 }} - {{- end }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }}-pvc - app: {{ .Values.nodeName }}-pv -spec: - storageClassName: {{ .Values.storage.name }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.storage.memory }} diff --git a/platforms/r3-corda/charts/corda-mongodb/templates/service.yaml b/platforms/r3-corda/charts/corda-mongodb/templates/service.yaml deleted file mode 100644 index a5d5a4381e9..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb/templates/service.yaml +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.nodeName }} - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.service.annotations }} - annotations: -{{ toYaml .Values.service.annotations | indent 8 }} - {{- end }} - labels: - run: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app: {{ .Values.nodeName }} -spec: - type: {{ .Values.service.type }} - ports: - - protocol: TCP - port: {{ .Values.service.tcp.port }} - targetPort: {{ .Values.service.tcp.targetPort }} - {{- if .Values.service.tcp.nodePort }} - nodePort: {{ .Values.service.tcp.nodePort}} - {{- end }} - selector: - appdb: {{ .Values.nodeName }} diff --git a/platforms/r3-corda/charts/corda-mongodb/values.yaml b/platforms/r3-corda/charts/corda-mongodb/values.yaml deleted file mode 100644 index af3c1a90d01..00000000000 --- a/platforms/r3-corda/charts/corda-mongodb/values.yaml +++ /dev/null @@ -1,38 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Default values for nodechart. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -#Provide the Name for node to be deployed -#Eg. nodeName: mongodb-doorman -nodeName: mongodb -replicas: -image: - #Provide the name of image for container - #Eg. containerName: hyperledgerlabs/h2:2018 - containerName: hyperledgerlabs/h2:2018 -storage: - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - name: - mountPath: -service: - #Provide the type of service - #Eg. type: NodePort - type: NodePort - tcp: - #Provide the tcp port for node - #Eg. port: 9101 - port: 9101 - #Provide the tcp node port for node - #Eg. port: 32001 - nodePort: - #Provide the tcp node port for node - #Eg. targetPort: 27017 - targetPort: 27017 diff --git a/platforms/r3-corda/charts/corda-network-service/Chart.yaml b/platforms/r3-corda/charts/corda-network-service/Chart.yaml new file mode 100644 index 00000000000..d9de3a66787 --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/Chart.yaml @@ -0,0 +1,25 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## + +apiVersion: v1 +name: corda-network-service +description: "R3 Corda Network Service: Doorman, Networkmap and MongoDB." +version: 1.0.0 +appVersion: "latest" +keywords: + - bevel + - corda + - hyperledger + - enterprise + - blockchain + - deployment + - accenture +home: https://hyperledger-bevel.readthedocs.io/en/latest/ +sources: + - https://github.com/hyperledger/bevel +maintainers: + - name: Hyperledger Bevel maintainers + email: bevel@lists.hyperledger.org diff --git a/platforms/r3-corda/charts/corda-network-service/README.md b/platforms/r3-corda/charts/corda-network-service/README.md new file mode 100644 index 00000000000..ba71835d640 --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/README.md @@ -0,0 +1,146 @@ +[//]: # (##############################################################################################) +[//]: # (Copyright Accenture. All Rights Reserved.) +[//]: # (SPDX-License-Identifier: Apache-2.0) +[//]: # (##############################################################################################) + +# corda-network-service + +This chart is a component of Hyperledger Bevel. The corda-network-service chart deploys a R3 Corda Doorman, Networkmap and associated MongoDB database. If enabled, the keys are then stored on the configured vault and stored as Kubernetes secrets. See [Bevel documentation](https://hyperledger-bevel.readthedocs.io/en/latest/) for details. + +## TL;DR + +```bash +helm repo add bevel https://hyperledger.github.io/bevel +helm install network-service bevel/corda-network-service +``` + +## Prerequisitess + +- Kubernetes 1.19+ +- Helm 3.2.0+ + +If Hashicorp Vault is used, then +- HashiCorp Vault Server 1.13.1+ + +> **Important**: Ensure the `corda-init` chart has been installed before installing this. Also check the dependent charts. + +## Installing the Chart + +To install the chart with the release name `network-service`: + +```bash +helm repo add bevel https://hyperledger.github.io/bevel +helm install network-service bevel/corda-network-service +``` + +The command deploys the chart on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `network-service` deployment: + +```bash +helm uninstall network-service +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Parameters + +### Global parameters +These parameters are refered to as same in each parent or child chart +| Name | Description | Default Value | +|--------|---------|-------------| +|`global.serviceAccountName` | The serviceaccount name that will be used for Vault Auth management| `vault-auth` | +| `global.cluster.provider` | Kubernetes cluster provider like AWS EKS or minikube. Currently ony `aws` and `minikube` is tested | `aws` | +| `global.cluster.cloudNativeServices` | only `false` is implemented, `true` to use Cloud Native Services (SecretsManager and IAM for AWS; KeyVault & Managed Identities for Azure) is for future | `false` | +| `global.vault.type` | Type of Vault to support other providers. Currently, only `hashicorp` is supported. | `hashicorp` | +| `global.vault.role` | Role used for authentication with Vault | `vault-role` | +| `global.vault.address`| URL of the Vault server. | `""` | +| `global.vault.authPath` | Authentication path for Vault | `supplychain` | +| `global.vault.secretEngine` | The value for vault secret engine name | `secretsv2` | +| `global.vault.secretPrefix` | The value for vault secret prefix which must start with `data/` | `data/supplychain` | +| `global.proxy.provider` | The proxy or Ingress provider. Can be `none` or `ambassador` | `ambassador` | +| `global.proxy.externalUrlSuffix` | The External URL suffix at which the Corda P2P service will be available | `test.blockchaincloudpoc.com` | + +### Storage + +| Name | Description | Default Value | +|--------|---------|-------------| +| `storage.size` | Size of the Volume needed for NMS and Doorman node | `1Gi` | +| `storage.dbSize` | Size of the Volume needed for MongoDB | `1Gi` | +| `storage.allowedTopologies.enabled` | Check [bevel-storageclass](../../../shared/charts/bevel-storageclass/README.md) for details | `false` | + +### TLS +This is where you can override the values for the [corda-certs-gen subchart](../corda-certs-gen/README.md). + +| Name | Description | Default Value | +|--------|---------|-------------| +| `tls.enabled` | Use TLS for all communcations | `false` | +| `tls.settings.networkServices` | Enable TLS certificate generation for Doorman and NMS | `true` | + +### Image +| Name | Description | Default Value | +| -------------| ---------- | --------- | +| `image.pullSecret` | Provide the docker secret name in the namespace | `""` | +| `image.pullPolicy` | Pull policy to be used for the Docker images | `IfNotPresent` | +| `image.mongo.repository` | MongoDB image repository | `mongo`| +| `image.mongo.tag` | MongoDB image tag as per version of MongoDB | `3.6.6`| +| `image.hooks.repository` | Corda hooks image repository | `ghcr.io/hyperledger/bevel-build` | +| `image.hooks.tag` | Corda hooks image tag | `jdk8-stable` | +| `image.doorman` | Corda Doorman image repository and tag | `ghcr.io/hyperledger/bevel-doorman-linuxkit:latest` | +| `image.nms` | Corda Network Map image repository and tag | `ghcr.io/hyperledger/bevel-networkmap-linuxkit:latest` | + +### Common Settings +| Name | Description | Default Value | +| -------------| ---------- | --------- | +| `settings.removeKeysOnDelete` | Flag to delete the secrets on uninstall | `true` | +| `settings.rootSubject` | X.509 Subject for the Corda Root CA | `"CN=DLT Root CA,OU=DLT,O=DLT,L=New York,C=US"` | +| `settings.mongoSubject` | X.509 Subject for the MongoDB CA | `"C=US,ST=New York,L=New York,O=Lite,OU=DBA,CN=mongoDB"`| +| `settings.dbPort` | MongoDB Port | `27017`| + +### Doorman + +| Name | Description | Default Value | +| -------------| ---------- | --------- | +| `doorman.subject` | X.509 Subject for the Doorman | `"CN=Corda Doorman CA,OU=DOORMAN,O=DOORMAN,L=New York,C=US"` | +| `doorman.username` | Username of Doorman DB | `doorman` | +| `doorman.authPassword` | Password of `sa` user to access doorman admin api | `admin`| +| `doorman.dbPassword` | Password for Doorman DB | `newdbnm`| +| `doorman.port` | Port for Doorman Service | `8080`| + +### NMS + +| Name | Description | Default Value | +| -------------| ---------- | --------- | +| `nms.subject` | X.509 Subject for the NetworkMap | `"CN=Network Map,OU=FRA,O=FRA,L=Berlin,C=DE"` | +| `nms.username` | Username of NetworkMap DB | `networkmap` | +| `nms.authPassword` | Password of `sa` user to access NetworkMap admin api | `admin`| +| `nms.dbPassword` | Password for NetworkMap DB | `newdbnm`| +| `nms.port` | Port for NetworkMap Service | `8080`| + +## License + +This chart is licensed under the Apache v2.0 license. + +Copyright © 2024 Accenture + +### Attribution + +This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: + +``` +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. +``` diff --git a/platforms/r3-corda/charts/corda-network-service/requirements.yaml b/platforms/r3-corda/charts/corda-network-service/requirements.yaml new file mode 100644 index 00000000000..35059a61d0d --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/requirements.yaml @@ -0,0 +1,14 @@ +dependencies: + - name: bevel-storageclass + alias: storage + repository: "file://../../../shared/charts/bevel-storageclass" + tags: + - storage + version: ~1.0.0 + - name: corda-certs-gen + alias: tls + repository: "file://../corda-certs-gen" + tags: + - bevel + version: ~1.0.0 + condition: tls.enabled diff --git a/platforms/r3-corda/charts/corda-network-service/templates/_helpers.tpl b/platforms/r3-corda/charts/corda-network-service/templates/_helpers.tpl new file mode 100644 index 00000000000..d9aa91552d3 --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/templates/_helpers.tpl @@ -0,0 +1,29 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "corda-network-service.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 "corda-network-service.fullname" -}} +{{- $name := default .Chart.Name -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" $name .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "corda-network-service.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/platforms/r3-corda/charts/corda-network-service/templates/hooks-pre-delete.yaml b/platforms/r3-corda/charts/corda-network-service/templates/hooks-pre-delete.yaml new file mode 100644 index 00000000000..3cd67972e03 --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/templates/hooks-pre-delete.yaml @@ -0,0 +1,71 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "corda-network-service.fullname" . }}-pre-delete-hook + namespace: {{ .Release.Namespace }} + annotations: + helm.sh/hook: pre-delete + helm.sh/hook-weight: "0" + helm.sh/hook-delete-policy: "hook-succeeded" + labels: + app.kubernetes.io/name: pre-delete-hook + app.kubernetes.io/component: cleanup + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm +spec: + backoffLimit: 3 + completions: 1 + template: + metadata: + labels: + app.kubernetes.io/name: pre-delete-hook + app.kubernetes.io/component: cleanup + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm + spec: + serviceAccountName: {{ .Values.global.serviceAccountName }} + restartPolicy: "Never" + containers: + - name: {{ template "corda-network-service.fullname" . }}-cleanup + image: "{{ .Values.image.hooks.repository }}:{{ .Values.image.hooks.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /bin/bash + - -c + args: + - | + + echo "{{ template "corda-network-service.fullname" . }} pre-delete-hook ..." + +{{- if and (ne .Values.global.cluster.provider "minikube") (.Values.global.cluster.cloudNativeServices) }} + # placeholder for cloudNative deleteSecret function +{{- else }} + + function deleteSecret { + key=$1 + kubectl delete secret ${key} --namespace {{ .Release.Namespace }} + } + +{{- end }} + +{{- if .Values.settings.removeKeysOnDelete }} + +{{- if and (ne .Values.global.cluster.provider "minikube") (.Values.global.cluster.cloudNativeServices) }} + deleteSecret {{.Release.Name }}-nmskeystore + deleteSecret {{.Release.Name }}-doormankeystore + deleteSecret {{.Release.Name }}-rootcakeystore + deleteSecret {{.Release.Name }}-rootcacert + deleteSecret {{.Release.Name }}-rootcakey + deleteSecret {{.Release.Name }}-dbcert + deleteSecret {{.Release.Name }}-dbcacert +{{- else }} + deleteSecret {{.Release.Name }}-certs +{{- end }} + +{{- end }} + echo "Completed" diff --git a/platforms/r3-corda/charts/corda-network-service/templates/hooks-pre-install.yaml b/platforms/r3-corda/charts/corda-network-service/templates/hooks-pre-install.yaml new file mode 100644 index 00000000000..23dfa85a33c --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/templates/hooks-pre-install.yaml @@ -0,0 +1,226 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "corda-network-service.fullname" . }}-pre-install-hook + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-weight": "0" + "helm.sh/hook-delete-policy": "before-hook-creation" + labels: + app.kubernetes.io/name: pre-install-hook + app.kubernetes.io/component: certgen + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm +spec: + backoffLimit: 1 + completions: 1 + template: + metadata: + labels: + app.kubernetes.io/name: pre-install-hook + app.kubernetes.io/component: certgen + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm + spec: + serviceAccountName: {{ .Values.global.serviceAccountName }} + restartPolicy: "OnFailure" + containers: + - name: corda-certgen + image: {{ .Values.image.hooks.repository }}:{{ .Values.image.hooks.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + runAsUser: 0 + volumeMounts: + - name: generated-config + mountPath: /home + - name: scripts-volume + mountPath: /scripts/bevel-vault.sh + subPath: bevel-vault.sh + - name: openssl-conf + mountPath: /home/openssl.conf + subPath: openssl.conf + {{- if (eq .Values.global.vault.type "hashicorp") }} + env: + - name: VAULT_ADDR + value: "{{ .Values.global.vault.address }}" + - name: VAULT_SECRET_ENGINE + value: "{{ .Values.global.vault.secretEngine }}" + - name: VAULT_SECRET_PREFIX + value: "{{ .Values.global.vault.secretPrefix }}" + - name: KUBERNETES_AUTH_PATH + value: "{{ .Values.global.vault.authPath }}" + - name: VAULT_APP_ROLE + value: "{{ .Values.global.vault.role }}" + - name: VAULT_TYPE + value: "{{ .Values.global.vault.type }}" + {{- end }} + command: + - /bin/bash + - -c + args: + - | +{{- if (eq .Values.global.vault.type "hashicorp") }} + . /scripts/bevel-vault.sh + echo "Getting vault Token..." + vaultBevelFunc "init" + #Read if secret exists in Vault + vaultBevelFunc 'readJson' "${VAULT_SECRET_ENGINE}/${VAULT_SECRET_PREFIX}/{{ .Release.Name }}-certs" + function safeWriteSecret { + key=$1 + fpath=$2 + if [ "$SECRETS_AVAILABLE" == "yes" ] + then + # Get secret from Vault and create the k8s secret if it does not exist + kubectl get secret ${key}-certs --namespace {{ .Release.Namespace }} -o json > /dev/null 2>&1 + if [ $? -ne 0 ]; then + NMS_KEYS=$(echo ${VAULT_SECRET} | jq -r '.["nmskeystore_base64"]') + DOORMAN_KEYS=$(echo ${VAULT_SECRET} | jq -r '.["doormankeystore_base64"]') + ROOT_CA=$(echo ${VAULT_SECRET} | jq -r '.["rootcakeystore_base64"]') + CA_CERTS=$(echo ${VAULT_SECRET} | jq -r '.["rootcacert_base64"]' | base64 -d) + CA_KEY=$(echo ${VAULT_SECRET} | jq -r '.["rootcakey_base64"]' | base64 -d) + MONGO_CERT=$(echo ${VAULT_SECRET} | jq -r '.["dbcert_base64"]') + MONGO_CACERT=$(echo ${VAULT_SECRET} | jq -r '.["dbcacert_base64"]') + echo $NMS_KEYS | base64 -d > /tmp/nmsKeys.jks + echo $DOORMAN_KEYS | base64 -d > /tmp/doormankeys.jks + echo $ROOT_CA | base64 -d > /tmp/rootkeys.jks + echo $CA_CERTS > /tmp/rootca.pem + echo $CA_KEY > /tmp/rootca.key + echo $MONGO_CERT > /tmp/mongodb.pem + echo $MONGO_CACERT > /tmp/mongoca.pem + kubectl create secret generic ${key}-certs --namespace {{ .Release.Namespace }} \ + --from-file=nmskeystore=/tmp/nmsKeys.jks --from-file=doormankeystore=/tmp/doormankeys.jks \ + --from-file=rootcakeystore=/tmp/rootkeys.jks \ + --from-file=rootcacert=/tmp/rootca.pem --from-file=rootcakey=/tmp/rootca.key \ + --from-file=mongodb.pem=/tmp/mongodb.pem --from-file=mongoCA.crt=/tmp/mongoca.pem + fi + else + # Save Certs to Vault + # Use -w0 to get single line base64 -w0 + NMS_KEYS=$(cat ${fpath}/nms/keys.jks | base64 -w0) + DOORMAN_KEYS=$(cat ${fpath}/doorman/keys.jks | base64 -w0) + ROOT_CA=$(cat ${fpath}/rootca/keys.jks | base64 -w0) + CA_CERTS=$(cat ${fpath}/rootca/cordarootca.pem | base64 -w0) + CA_KEY=$(cat ${fpath}/rootca/cordarootca.key | base64 -w0) + MONGO_CERT=$(cat ${fpath}/mongodb/mongodb.pem | base64 -w0) + MONGO_CACERT=$(cat ${fpath}/mongodb/mongoCA.crt | base64 -w0) + # create a JSON file for the data related to node crypto + echo " + { + \"data\": + { + \"nmskeystore_base64\": \"${NMS_KEYS}\", + \"doormankeystore_base64\": \"${DOORMAN_KEYS}\", + \"rootcakeystore_base64\": \"${ROOT_CA}\", + \"rootcacert_base64\": \"${CA_CERTS}\", + \"rootcakey_base64\": \"${CA_KEY}\", + \"dbcert_base64\": \"${MONGO_CERT}\", + \"dbcacert_base64\": \"${MONGO_CACERT}\" + } + }" > payload.json + vaultBevelFunc 'write' "${VAULT_SECRET_ENGINE}/${VAULT_SECRET_PREFIX}/${key}-certs" 'payload.json' + rm payload.json + # Also create the k8s secret + kubectl create secret generic ${key}-certs --namespace {{ .Release.Namespace }} \ + --from-file=nmskeystore=${fpath}/nms/keys.jks --from-file=doormankeystore=${fpath}/doorman/keys.jks \ + --from-file=rootcakeystore=${fpath}/rootca/keys.jks \ + --from-file=rootcacert=${fpath}/rootca/cordarootca.pem --from-file=rootcakey=${fpath}/rootca/cordarootca.key \ + --from-literal=mongodb.pem=${MONGO_CERT} --from-literal=mongoCA.crt=${MONGO_CACERT} + fi + } +{{- else }} + function safeWriteSecret { + key=$1 + fpath=$2 + kubectl get secret ${key}-certs --namespace {{ .Release.Namespace }} -o json > /dev/null 2>&1 + if [ $? -ne 0 ]; then + kubectl create secret generic ${key}-certs --namespace {{ .Release.Namespace }} \ + --from-file=nmskeystore=${fpath}/nms/keys.jks --from-file=doormankeystore=${fpath}/doorman/keys.jks \ + --from-file=rootcakeystore=${fpath}/rootca/keys.jks \ + --from-file=rootcacert=${fpath}/rootca/cordarootca.pem --from-file=rootcakey=${fpath}/rootca/cordarootca.key \ + --from-file=mongodb.pem=<(base64 -w0 ${fpath}/mongodb/mongodb.pem) --from-file=mongoCA.crt=<(base64 -w0 ${fpath}/mongodb/mongoCA.crt) + fi + } +{{- end }} + if [ "$SECRETS_AVAILABLE" == "yes" ] + then + echo "Certificates found for {{ .Release.Name }} ..." + else + echo "Creating certificates for {{ .Release.Name }} ..." + ROOTCA_PATH=/home/certificates/rootca + DBCA_PATH=/home/certificates/mongodb + DOORMAN_CERTS=/home/certificates/doorman + NMS_CERTS=/home/certificates/nms + mkdir -p ${ROOTCA_PATH} + mkdir -p ${DBCA_PATH} + mkdir -p ${DOORMAN_CERTS} + mkdir -p ${NMS_CERTS} + # Do not change keystore_pass as it is hardcoded as default in doorman/networkmap app + KEYSTORE_PASS='changeme' + + cd ${ROOTCA_PATH} + keytool -genkey -keyalg RSA -alias key -dname "{{ .Values.settings.rootSubject }}" -keystore keys.jks -storepass $KEYSTORE_PASS -keypass $KEYSTORE_PASS + openssl ecparam -name prime256v1 -genkey -noout -out cordarootca.key + openssl req -x509 -config /home/openssl.conf -new -nodes -key cordarootca.key -days 1024 -out cordarootca.pem -extensions v3_ca -subj '/{{ .Values.settings.rootSubject | replace "," "/" }}' + openssl pkcs12 -export -name cert -inkey cordarootca.key -in cordarootca.pem -out cordarootcacert.pkcs12 -cacerts -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} + openssl pkcs12 -export -name key -inkey cordarootca.key -in cordarootca.pem -out cordarootcakey.pkcs12 -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} + eval "yes | keytool -importkeystore -srckeystore cordarootcacert.pkcs12 -srcstoretype PKCS12 -srcstorepass $KEYSTORE_PASS -destkeystore keys.jks -deststorepass $KEYSTORE_PASS" + eval "yes | keytool -importkeystore -srckeystore cordarootcakey.pkcs12 -srcstoretype PKCS12 -srcstorepass $KEYSTORE_PASS -destkeystore keys.jks -deststorepass $KEYSTORE_PASS" + + cd ${DBCA_PATH} + openssl genrsa -out mongoCA.key 3072 + openssl req -x509 -config /home/openssl.conf -new -extensions v3_ca -key mongoCA.key -days 365 -out mongoCA.crt -subj '/{{ .Values.settings.mongoSubject | replace "," "/" }}' + openssl req -new -nodes -newkey rsa:4096 -keyout mongodb.key -out mongodb.csr -subj '/{{ .Values.settings.mongoSubject | replace "," "/" }}' + openssl x509 -CA mongoCA.crt -CAkey mongoCA.key -CAcreateserial -CAserial serial -req -days 365 -in mongodb.csr -out mongodb.crt + cat mongodb.key mongodb.crt > mongodb.pem + + cd ${DOORMAN_CERTS} + keytool -genkey -keyalg RSA -alias key -dname "{{ .Values.doorman.subject }}" -keystore keys.jks -storepass $KEYSTORE_PASS -keypass $KEYSTORE_PASS + openssl ecparam -name prime256v1 -genkey -noout -out cordadoormanca.key + openssl req -new -nodes -key cordadoormanca.key -out cordadoormanca.csr -subj '/{{ .Values.doorman.subject | replace "," "/" }}' + openssl x509 -req -days 1000 -in cordadoormanca.csr -CA ${ROOTCA_PATH}/cordarootca.pem -CAkey ${ROOTCA_PATH}/cordarootca.key -out cordadoormanca.pem -CAcreateserial \ + -CAserial serial -extfile /home/openssl.conf -extensions doorman + openssl pkcs12 -export -name cert -inkey cordadoormanca.key -in cordadoormanca.pem -out cordadoormancacert.pkcs12 -cacerts -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} + openssl pkcs12 -export -name key -inkey cordadoormanca.key -in cordadoormanca.pem -out cordadoormancakey.pkcs12 -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} + eval "yes | keytool -importkeystore -srckeystore cordadoormancacert.pkcs12 -srcstoretype PKCS12 -srcstorepass $KEYSTORE_PASS -destkeystore keys.jks -deststorepass $KEYSTORE_PASS" + eval "yes | keytool -importkeystore -srckeystore cordadoormancakey.pkcs12 -srcstoretype PKCS12 -srcstorepass $KEYSTORE_PASS -destkeystore keys.jks -deststorepass $KEYSTORE_PASS" + + cd ${NMS_CERTS} + keytool -genkey -keyalg RSA -alias key -dname "{{ .Values.nms.subject }}" -keystore keys.jks -storepass $KEYSTORE_PASS -keypass $KEYSTORE_PASS + openssl ecparam -name prime256v1 -genkey -noout -out cordanetworkmap.key + openssl req -new -nodes -key cordanetworkmap.key -out cordanetworkmap.csr -subj '/{{ .Values.nms.subject | replace "," "/" }}' + openssl x509 -req -days 1000 -in cordanetworkmap.csr -CA ${ROOTCA_PATH}/cordarootca.pem -CAkey ${ROOTCA_PATH}/cordarootca.key -out cordanetworkmap.pem -CAcreateserial \ + -CAserial serial -extfile /home/openssl.conf -extensions networkMap + openssl pkcs12 -export -name cert -inkey cordanetworkmap.key -in cordanetworkmap.pem -out cordanetworkmapcacert.pkcs12 -cacerts -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} + openssl pkcs12 -export -name key -inkey cordanetworkmap.key -in cordanetworkmap.pem -out cordanetworkmapcakey.pkcs12 -passin pass:${KEYSTORE_PASS} -passout pass:${KEYSTORE_PASS} + eval "yes | keytool -importkeystore -srckeystore cordanetworkmapcacert.pkcs12 -srcstoretype PKCS12 -srcstorepass ${KEYSTORE_PASS} -destkeystore keys.jks -deststorepass ${KEYSTORE_PASS}" + eval "yes | keytool -importkeystore -srckeystore cordanetworkmapcakey.pkcs12 -srcstoretype PKCS12 -srcstorepass ${KEYSTORE_PASS} -destkeystore keys.jks -deststorepass ${KEYSTORE_PASS}" + fi; + echo "Creating {{ .Release.Name }}-certs secrets in k8s ..." +{{- if and (ne .Values.global.cluster.provider "minikube") (.Values.global.cluster.cloudNativeServices) }} + safeWriteSecret {{ .Release.Name }}-nmskeystore $NMS_CERTS/keys.jks + safeWriteSecret {{ .Release.Name }}-doormankeystore $DOORMAN_CERTS/keys.jks + safeWriteSecret {{ .Release.Name }}-rootcakeystore $ROOTCA_PATH/keys.jks + safeWriteSecret {{ .Release.Name }}-rootcacert $ROOTCA_PATH/cordarootca.pem + safeWriteSecret {{ .Release.Name }}-rootcakey $ROOTCA_PATH/cordarootca.key + safeWriteSecret {{ .Release.Name }}-dbcert $DBCA_PATH/mongodb.pem + safeWriteSecret {{ .Release.Name }}-dbcacert $DBCA_PATH/mongoCA.crt +{{- else }} + safeWriteSecret {{ .Release.Name }} /home/certificates +{{- end }} + echo "Completed ..." + volumes: + - name: generated-config + emptyDir: {} + - name: scripts-volume + configMap: + name: bevel-vault-script + defaultMode: 0777 + - name: openssl-conf + configMap: + name: openssl-conf diff --git a/platforms/r3-corda/charts/corda-network-service/templates/service.yaml b/platforms/r3-corda/charts/corda-network-service/templates/service.yaml new file mode 100644 index 00000000000..0bcb8459b0e --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/templates/service.yaml @@ -0,0 +1,171 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-mongodb + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: mongodb-service + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: mongodb-statefulset + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + ports: + - name: mongo-db + protocol: TCP + port: {{ .Values.settings.dbPort }} + targetPort: {{ .Values.settings.dbPort }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-doorman + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: doorman-service + app.kubernetes.io/component: doorman + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: doorman-statefulset + app.kubernetes.io/component: doorman + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + ports: + - name: doorman + protocol: TCP + port: {{ .Values.doorman.port }} + targetPort: {{ .Values.doorman.port }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-nms + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: networkmap-service + app.kubernetes.io/component: nms + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +spec: + type: ClusterIP + selector: + app.kubernetes.io/component: nms + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + ports: + - name: nms + protocol: TCP + port: {{ .Values.nms.port }} + targetPort: {{ .Values.nms.port }} +{{- if eq .Values.global.proxy.provider "ambassador" }} +{{- if .Values.tls.enabled }} +--- +## Host for doorman +apiVersion: getambassador.io/v3alpha1 +kind: Host +metadata: + name: {{ .Release.Name }}-doorman +spec: + hostname: {{ .Release.Name }}-doorman.{{ .Values.global.proxy.externalUrlSuffix }} + acmeProvider: + authority: none + requestPolicy: + insecure: + action: Reject + tlsSecret: + name: doorman-tls-certs + namespace: {{ .Release.Namespace }} +--- +## Host for nms +apiVersion: getambassador.io/v3alpha1 +kind: Host +metadata: + name: {{ .Release.Name }}-nms +spec: + hostname: {{ .Release.Name }}-nms.{{ .Values.global.proxy.externalUrlSuffix }} + acmeProvider: + authority: none + requestPolicy: + insecure: + action: Reject + tlsSecret: + name: nms-tls-certs + namespace: {{ .Release.Namespace }} +{{- end }} +--- +## Mapping for doorman port +apiVersion: getambassador.io/v3alpha1 +kind: Mapping +metadata: + name: {{ .Release.Name }}-mapping + namespace: {{ .Release.Namespace }} +spec: + host: {{ .Release.Name }}-doorman.{{ .Values.global.proxy.externalUrlSuffix }} + prefix: / + service: {{ .Release.Name }}-doorman.{{ .Release.Namespace }}:{{ .Values.doorman.port }} +{{- if .Values.tls.enabled }} + tls: {{ .Release.Name }}-doorman-tlscontext +--- +apiVersion: getambassador.io/v3alpha1 +kind: TLSContext +metadata: + name: {{ .Release.Name }}-doorman-tlscontext + namespace: {{ .Release.Namespace }} +spec: + hosts: + - {{ .Release.Name }}-doorman.{{ .Values.global.proxy.externalUrlSuffix }} + secret: doorman-tls-certs.{{ .Release.Namespace }} + secret_namespacing: true + min_tls_version: v1.2 +{{- end }} +--- +## Mapping for nms port +apiVersion: getambassador.io/v3alpha1 +kind: Mapping +metadata: + name: {{ .Release.Name }}-nms-mapping + namespace: {{ .Release.Namespace }} +spec: + host: {{ .Release.Name }}-nms.{{ .Values.global.proxy.externalUrlSuffix }} + prefix: / + service: {{ .Release.Name }}-nms.{{ .Release.Namespace }}:{{ .Values.nms.port }} +{{- if .Values.tls.enabled }} + tls: {{ .Release.Name }}-nms-tlscontext +--- +apiVersion: getambassador.io/v3alpha1 +kind: TLSContext +metadata: + name: {{ .Release.Name }}-nms-tlscontext + namespace: {{ .Release.Namespace }} +spec: + hosts: + - {{ .Release.Name }}-nms.{{ .Values.global.proxy.externalUrlSuffix }} + secret: nms-tls-certs.{{ .Release.Namespace }} + secret_namespacing: true + min_tls_version: v1.2 +{{- end }} +{{- end }} diff --git a/platforms/r3-corda/charts/corda-network-service/templates/statefulset-doorman.yaml b/platforms/r3-corda/charts/corda-network-service/templates/statefulset-doorman.yaml new file mode 100644 index 00000000000..a69217e6e3b --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/templates/statefulset-doorman.yaml @@ -0,0 +1,138 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "corda-network-service.fullname" . }}-doorman + namespace: {{ .Release.Namespace }} + labels: + app: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/name: doorman-statefulset + app.kubernetes.io/component: doorman + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +spec: + replicas: 1 + podManagementPolicy: OrderedReady + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/name: doorman-statefulset + app.kubernetes.io/component: doorman + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + serviceName: {{ include "corda-network-service.fullname" . }} + volumeClaimTemplates: + - metadata: + name: data + spec: + storageClassName: storage-{{ .Release.Name }} + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: {{ .Values.storage.size }} + template: + metadata: + labels: + app: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/name: doorman-statefulset + app.kubernetes.io/component: doorman + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + spec: + serviceAccountName: {{ .Values.global.serviceAccountName }} + hostname: {{ .Release.Name }} + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + securityContext: + fsGroup: 1000 + containers: + - name: doorman + image: {{ .Values.image.doorman }} + imagePullPolicy: IfNotPresent + env: + - name: DOORMAN_PORT + value: "{{ .Values.doorman.port }}" + - name: DOORMAN_ROOT_CA_NAME + value: {{ .Values.doorman.subject }} + - name: DOORMAN_TLS + value: "{{ .Values.tls.enabled }}" + - name: DOORMAN_DB + value: /opt/doorman/db + - name: DOORMAN_AUTH_USERNAME + value: sa + - name: DB_URL + value: {{ .Release.Name }}-mongodb + - name: DB_PORT + value: "{{ .Values.settings.dbPort }}" + - name: DATABASE + value: admin + - name: DB_USERNAME + value: {{ .Values.doorman.username }} + command: ["sh", "-c"] + args: + - |- + #!/usr/bin/env sh + + export DB_PASSWORD={{ .Values.doorman.dbPassword }} + export DOORMAN_AUTH_PASSWORD={{ .Values.doorman.authPassword }} + # Copy from read-only to read-write dirs + mkdir -p /opt/doorman/db/certs/root + mkdir -p /opt/doorman/db/certs/doorman + + cp /certs/rootcakeystore /opt/doorman/db/certs/root/keys.jks + cp /certs/doormankeystore /opt/doorman/db/certs/doorman/keys.jks + + if [ "$DOORMAN_TLS" = "true" ]; then + cat /certs/mongoCA.crt | base64 -d > /opt/doorman/mongoCA.crt + export DOORMAN_MONGO_CONNECTION_STRING="mongodb://${DB_USERNAME}:${DB_PASSWORD}@${DB_URL}:${DB_PORT}/${DATABASE}?ssl=true&sslInvalidHostNameAllowed=true&streamType=netty" + + # tls certs are mounted via tls secrets + export DOORMAN_TLS_CERT_PATH="/secret/tls.crt" + export DOORMAN_TLS_KEY_PATH="/secret/tls.key" + + # import self signed tls certificate of mongodb, since java only trusts certificate signed by well known CA + yes | keytool -importcert -file /opt/doorman/mongoCA.crt -storepass changeit -alias mongoca -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts + else + export DOORMAN_MONGO_CONNECTION_STRING="mongodb://${DB_USERNAME}:${DB_PASSWORD}@${DB_URL}:${DB_PORT}/${DATABASE}" + fi; + # command to run jar + java -jar /opt/doorman/doorman.jar 2>&1 + ports: + - containerPort: {{ .Values.doorman.port }} + volumeMounts: + - name: data + mountPath: "/opt/doorman/db" + readOnly: false + - name: network-certs + mountPath: "/certs" +{{- if .Values.tls.enabled }} + - name: doorman-certs + mountPath: "/secret" +{{- end }} + volumes: + - name: scripts-volume + configMap: + name: bevel-vault-script + defaultMode: 0777 + - name: network-certs + secret: + secretName: {{ .Release.Name }}-certs +{{- if .Values.tls.enabled }} + - name: doorman-certs + secret: + secretName: doorman-tls-certs +{{- end }} diff --git a/platforms/r3-corda/charts/corda-network-service/templates/statefulset-mongodb.yaml b/platforms/r3-corda/charts/corda-network-service/templates/statefulset-mongodb.yaml new file mode 100644 index 00000000000..1639d3298e9 --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/templates/statefulset-mongodb.yaml @@ -0,0 +1,136 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "corda-network-service.fullname" . }}-db + namespace: {{ .Release.Namespace }} + labels: + app: {{ include "corda-network-service.fullname" . }}-db + app.kubernetes.io/name: mongodb-statefulset + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +spec: + replicas: 1 + podManagementPolicy: OrderedReady + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app: {{ include "corda-network-service.fullname" . }}-db + app.kubernetes.io/name: mongodb-statefulset + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + serviceName: {{ include "corda-network-service.fullname" . }}-db + volumeClaimTemplates: + - metadata: + name: data-mongodb + spec: + storageClassName: storage-{{ .Release.Name }} + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: {{ .Values.storage.dbSize }} + template: + metadata: + labels: + app: {{ include "corda-network-service.fullname" . }}-db + app.kubernetes.io/name: mongodb-statefulset + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + spec: + serviceAccountName: {{ .Values.global.serviceAccountName }} + hostname: {{ .Release.Name }} + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + securityContext: + fsGroup: 1000 + containers: + - name: mongodb + image: {{ .Values.image.mongo.repository }}:{{ .Values.image.mongo.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: MONGO_INITDB_ROOT_USERNAME + value: {{ .Values.doorman.username }} + - name: MONGO_INITDB_ROOT_PASSWORD + value: {{ .Values.doorman.dbPassword }} + # The complete command and lifecycle section is for TLS enabled + {{- if .Values.tls.enabled }} + command: + - /bin/sh + - -c + - > + if [ -f /data/db/admin-user.lock ]; then + #file /data/db/admin-user.lock created and checked to ensure mongod is fully up for adding new db user in postStart hook. + echo "KUBERNETES LOG $HOSTNAME- Starting Mongo Daemon" + cat /certs/mongoCA.crt | base64 -d > /data/db/mongoCA.crt + cat /certs/mongodb.pem | base64 -d > /data/db/mongodb.pem + # ensure wiredTigerCacheSize is set within the size of the containers memory limit, Setting up with tag --sslAllowConnectionsWithoutCertificates only client validates the server to ensure that it receives data from the intended server. + if [ "$HOSTNAME" = "{{ template "corda-network-service.fullname" . }}-db-0" ]; then + #for Mongodb single server. + echo "check 1" + mongod --wiredTigerCacheSizeGB 0.25 --bind_ip 0.0.0.0 --sslMode requireSSL --sslPEMKeyFile /data/db/mongodb.pem --sslCAFile /data/db/mongoCA.crt --sslAllowConnectionsWithoutCertificates --sslAllowInvalidHostnames --auth; + fi; + else + echo "KUBERNETES LOG $HOSTNAME- Starting Mongo Daemon with setup setting (authMode)" + mongod --auth; + fi; + lifecycle: + postStart: + exec: + command: + - /bin/sh + - -c + - > + if [ ! -f /data/db/admin-user.lock ]; then + echo "KUBERNETES LOG $HOSTNAME no Admin-user.lock file found yet" + # user name and password for creation of new db user. + DB_PASSWORD={{ .Values.doorman.dbPassword }} + DB_USERNAME={{ .Values.doorman.username }} + # sleep 20 to 'ensure' mongod is accepting connections for creating db user. + sleep 20; + touch /data/db/admin-user.lock + # Adding database user with password in admin database, checking for host name to create new db user. + if [ "$HOSTNAME" = "{{ template "corda-network-service.fullname" . }}-db-0" ]; then + echo "KUBERNETES LOG $HOSTNAME- creating admin user" + # Adding database user in admin db using mongo shell command. + mongo --eval "db = db.getSiblingDB('admin'); db.createUser({ user: '${DB_USERNAME}', pwd: '${DB_PASSWORD}', roles: [{ role: 'root', db: 'admin' }]});" >> /data/db/config.log + fi; + echo "KUBERNETES LOG $HOSTNAME-shutting mongod down for final restart" + mongod --shutdown; + fi; + {{- end }} + ports: + - containerPort: {{ .Values.settings.dbPort }} + volumeMounts: + - name: data-mongodb + mountPath: "/data/db" +{{- if .Values.tls.enabled }} + - name: network-certs + mountPath: "/certs" + readOnly: false +{{- end }} + volumes: + - name: scripts-volume + configMap: + name: bevel-vault-script + defaultMode: 0777 +{{- if .Values.tls.enabled }} + - name: network-certs + secret: + secretName: {{ .Release.Name }}-certs +{{- end }} diff --git a/platforms/r3-corda/charts/corda-network-service/templates/statefulset-nms.yaml b/platforms/r3-corda/charts/corda-network-service/templates/statefulset-nms.yaml new file mode 100644 index 00000000000..7e23c9e0d29 --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/templates/statefulset-nms.yaml @@ -0,0 +1,142 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "corda-network-service.fullname" . }}-nms + namespace: {{ .Release.Namespace }} + labels: + app: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/name: nms-statefulset + app.kubernetes.io/component: nms + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +spec: + replicas: 1 + podManagementPolicy: OrderedReady + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/name: nms-statefulset + app.kubernetes.io/component: nms + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + serviceName: {{ include "corda-network-service.fullname" . }} + volumeClaimTemplates: + - metadata: + name: data + spec: + storageClassName: storage-{{ .Release.Name }} + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: {{ .Values.storage.size }} + template: + metadata: + labels: + app: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/name: nms-statefulset + app.kubernetes.io/component: nms + app.kubernetes.io/part-of: {{ include "corda-network-service.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + spec: + serviceAccountName: {{ .Values.global.serviceAccountName }} + hostname: {{ .Release.Name }} + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + securityContext: + fsGroup: 1000 + containers: + - name: nms + image: {{ .Values.image.nms }} + imagePullPolicy: IfNotPresent + env: + - name: NETWORKMAP_PORT + value: "{{ .Values.nms.port }}" + - name: NETWORKMAP_ROOT_CA_NAME + value: {{ .Values.nms.subject }} + - name: NETWORKMAP_TLS + value: "{{ .Values.tls.enabled }}" + - name: NETWORKMAP_DB + value: /opt/networkmap/db + - name: DOORMAN_AUTH_USERNAME + value: sa + - name: DB_URL + value: {{ .Release.Name }}-mongodb + - name: DB_PORT + value: "{{ .Values.settings.dbPort }}" + - name: DATABASE + value: admin + - name: DB_USERNAME + value: {{ .Values.nms.username }} + - name: NETWORKMAP_CACHE_TIMEOUT + value: 60S + - name: NETWORKMAP_MONGOD_DATABASE + value: networkmap + command: ["sh", "-c"] + args: + - |- + #!/usr/bin/env sh + + export DB_PASSWORD={{ .Values.nms.dbPassword }} + export NETWORKMAP_AUTH_PASSWORD={{ .Values.nms.authPassword }} + # Copy from read-only to read-write dirs + mkdir -p /opt/networkmap/db/certs/root + mkdir -p /opt/networkmap/db/certs/network-map + + cp /certs/rootcakeystore /opt/networkmap/db/certs/root/keys.jks + cp /certs/nmskeystore /opt/networkmap/db/certs/network-map/keys.jks + + if [ "$NETWORKMAP_TLS" = "true" ]; then + cat /certs/mongoCA.crt | base64 -d > /opt/networkmap/mongoCA.crt + export NETWORKMAP_MONGO_CONNECTION_STRING="mongodb://${DB_USERNAME}:${DB_PASSWORD}@${DB_URL}:${DB_PORT}/${DATABASE}?ssl=true&sslInvalidHostNameAllowed=true&streamType=netty" + + # tls certs are mounted via tls secrets + export NETWORKMAP_TLS_CERT_PATH="/secret/tls.crt" + export NETWORKMAP_TLS_KEY_PATH="/secret/tls.key" + + # import self signed tls certificate of mongodb, since java only trusts certificate signed by well known CA + yes | keytool -importcert -file /opt/networkmap/mongoCA.crt -storepass changeit -alias mongoca -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts + else + export NETWORKMAP_MONGO_CONNECTION_STRING="mongodb://${DB_USERNAME}:${DB_PASSWORD}@${DB_URL}:${DB_PORT}/${DATABASE}" + fi; + # command to run jar + java -jar /opt/networkmap/network-map-service.jar 2>&1 + ports: + - containerPort: {{ .Values.nms.port }} + volumeMounts: + - name: data + mountPath: "/opt/networkmap/db" + readOnly: false + - name: network-certs + mountPath: "/certs" +{{- if .Values.tls.enabled }} + - name: nms-certs + mountPath: "/secret" +{{- end }} + volumes: + - name: scripts-volume + configMap: + name: bevel-vault-script + defaultMode: 0777 + - name: network-certs + secret: + secretName: {{ .Release.Name }}-certs +{{- if .Values.tls.enabled }} + - name: nms-certs + secret: + secretName: nms-tls-certs +{{- end }} diff --git a/platforms/r3-corda/charts/corda-network-service/values.yaml b/platforms/r3-corda/charts/corda-network-service/values.yaml new file mode 100644 index 00000000000..3a388db5112 --- /dev/null +++ b/platforms/r3-corda/charts/corda-network-service/values.yaml @@ -0,0 +1,82 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## + +# Default values for nodechart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +global: + serviceAccountName: vault-auth + cluster: + provider: aws # choose from: minikube | aws | azure | gcp + cloudNativeServices: false # set to true to use Cloud Native Services (SecretsManager and IAM for AWS; KeyVault & Managed Identities for Azure) + vault: + type: hashicorp + role: vault-role + address: + authPath: supplychain + secretEngine: secretsv2 + secretPrefix: "data/supplychain" + proxy: + #This will be the proxy/ingress provider. Can have values "ambassador" or "none" + #Eg. provider: "ambassador" + provider: "ambassador" + #This field contains the external URL of the node + #Eg. externalUrlSuffix: test.blockchaincloudpoc.com + externalUrlSuffix: test.blockchaincloudpoc.com + +storage: + #Provide the size for PVC + #Eg. size: 4Gi + size: 1Gi + dbSize: 1Gi + allowedTopologies: + enabled: false + +tls: + enabled: false + settings: + networkServices: true + +image: + #Provide the docker secret name in the namespace + #Eg. pullSecret: regcred + pullSecret: + #Pull policy to be used for the Docker image + #Eg. pullPolicy: IfNotPresent + pullPolicy: IfNotPresent + #Provide a valid image and version for mongodb + mongo: + repository: mongo + tag: 3.6.6 + hooks: + repository: ghcr.io/hyperledger/bevel-build + tag: jdk8-stable + doorman: ghcr.io/hyperledger/bevel-doorman-linuxkit:latest + nms: ghcr.io/hyperledger/bevel-networkmap-linuxkit:latest + +settings: + removeKeysOnDelete: true + rootSubject: "CN=DLT Root CA,OU=DLT,O=DLT,L=New York,C=US" + mongoSubject: "C=US,ST=New York,L=New York,O=Lite,OU=DBA,CN=mongoDB" + #Provide the tcp node port for database + #Eg. dbPort: 27017 + dbPort: 27017 + +doorman: + subject: "CN=Corda Doorman CA,OU=DOORMAN,O=DOORMAN,L=New York,C=US" + username: doorman + authPassword: admin + dbPassword: newdbnm + #Provide the tcp port for node + #Eg. port: 27017 + port: 8080 + +nms: + subject: "CN=Network Map,OU=FRA,O=FRA,L=Berlin,C=DE" + username: networkmap + authPassword: admin + dbPassword: newdbnm + port: 8080 diff --git a/platforms/r3-corda/charts/corda-networkmap-tls/Chart.yaml b/platforms/r3-corda/charts/corda-networkmap-tls/Chart.yaml deleted file mode 100644 index 5d4a785f2de..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap-tls/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Deploys networkmap sevice with TLS." -name: corda-networkmap-tls -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-networkmap-tls/README.md b/platforms/r3-corda/charts/corda-networkmap-tls/README.md deleted file mode 100644 index 80d1bfcef42..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap-tls/README.md +++ /dev/null @@ -1,178 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# Nms Deployment - -- [Nms-tls Deployment Helm Chart](#Nms-tls-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - -## nms-tls Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-networkmap-tls) deploys a networkmap sevice with TLS enabled. - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- NetworkMap and Node's database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - -## Chart Structure ---- -This chart has following structue: - -``` - - ├── nms-tls - │ ├── Chart.yaml - │ ├── templates - │ │ ├── deployment.yaml - │ │ ├── Volume.yaml - │ │ └── service.yaml - │ └── values.yaml -``` - -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `deployment.yaml` : This file sets up a deployment with multiple containers, mounts volumes, retrieves secrets from Vault, and performs some initialization tasks before starting the main containers. -- `volume.yaml` : These PVCs can be used to provide persistent storage for the network map service deployment. -- `service.yaml` : This file defines a Kubernetes Service with multiple ports for protocols and targets, and supports Ambassador proxy annotations for specific configurations when using the "ambassador" proxy provider. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the image, storage, service, vault and ambassador. - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-networkmap-tls/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | network-map | - -### Metadata - -| Name | Description | Default Value | -| ----------------| -------------------------------------------------------- | ------------- | -| namespace | Provide the namespace for the nms Generator | default | - -### Image - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| containerName | Provide the containerName of image | "" | -| imagePullSecret | Provide the image pull secret of image | regcred | -| env | Provide enviroment variable for container image | "" | - -### Service - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------ | ------------- | -| type | Provide the type of service | "NodePort" | -| port | Provide the NMS service port | "30007" | -| nodePort | Provide the node port for node service to be accessible outside| "30050" | - - -### storage - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| Memory | Provide the memory for node | "4Gi" | - - -### Vault - -| Name | Description | Default Value | -| ------------------------- | --------------------------------------------------------------------------| ------------- | -| address | Address/URL of the Vault server | "" | -| role | Role used for authentication with Vault | vault-role | -| authpath | Authentication path for Vault | cordanms | -| secretprefix | Provide the kubernetes auth backed configured in vault | "" | -| imagesecretname | specify the name of the Kubernetes secret | "" | -| serviceaccountname | To authenticate with the Vault server and retrieve the secrets |vault-auth-issuer| -| ambassador | Provides the suffix to be used in external URL |"" | - - - -## Deployment ---- - -To deploy the nms-tls Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-networkmap-tls/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade, verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-networkmap-tls -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-networkmap-tls -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [Nms-tls Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-networkmap-tls), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-networkmap-tls/templates/deployment.yaml b/platforms/r3-corda/charts/corda-networkmap-tls/templates/deployment.yaml deleted file mode 100644 index c56e290e3e8..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap-tls/templates/deployment.yaml +++ /dev/null @@ -1,365 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Deployment -# Creates the replicated container and manages lifecycle -# TLS certs mounted -# Persistent Volume mounted -# Service points to this deployment (uses labels!) -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.nodeName }} - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.deployment.annotations }} - annotations: -{{ toYaml .Values.deployment.annotations | indent 8 }} - {{- end }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - template: - metadata: - labels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: {{ .Values.nodeName }}-service - image: {{ .Values.image.containerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - - # # add permissions to dir - # chmod 777 -R {{ .Values.image.mountPath.basePath }}/; - # chmod 777 -R {{ .Values.image.mountPath.basePath }}-tls/; - # Setting up enviroment variables required for jar - {{- range $.Values.image.env }} - export {{ .name }}="{{ .value }}" - {{- end }} - export NETWORKMAP_TLS_CERT_PATH="{{ .Values.image.mountPath.basePath }}-tls/certs/networkmap.crt" - export NETWORKMAP_TLS_KEY_PATH="{{ .Values.image.mountPath.basePath }}-tls/certs/networkmap.key" - export DB_PASSWORD=`cat /opt/creds/db_root_password` - export NETWORKMAP_MONGO_CONNECTION_STRING="mongodb://${DB_USERNAME}:${DB_PASSWORD}@${DB_URL}:${DB_PORT}/${DATABASE}?ssl=true&sslInvalidHostNameAllowed=true&streamType=netty" - export NETWORKMAP_AUTH_PASSWORD=`cat /opt/creds/user_cred` - - # import self signed tls certificate of mongodb, since java only trusts certificate signed by well known CA - yes | keytool -importcert -file {{ .Values.image.mountPath.basePath }}-tls/certs/mongoCA.crt -storepass changeit -alias mongoca -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - java -jar {{ .Values.image.mountPath.basePath }}/network-map-service.jar 2>&1 - ports: - - containerPort: {{ .Values.service.targetPort }} - volumeMounts: - - name: {{ .Values.nodeName }}-servicedata - mountPath: "{{ .Values.image.mountPath.basePath }}/db/" - readOnly: false - - name: certs - mountPath: "{{ .Values.image.mountPath.basePath }}/db/certs" - readOnly: false - - name: creds - mountPath: "/opt/creds" - readOnly: false - - name: tls-certs - mountPath: "{{ .Values.image.mountPath.basePath }}-tls/certs/" - readOnly: false - initContainers: - - name: init-certificates - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}/db/certs/ - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - OUTPUT_PATH=${MOUNT_PATH} - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/{{ .Values.vault.certsecretprefix }} | jq -r 'if .errors then . else . end') - - validateVaultResponse "${{ .Values.vault.certsecretprefix }})" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - - ROOTCA_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["rootcakey"]') - mkdir -p ${OUTPUT_PATH}/root; - echo "${ROOTCA_KEY}" | base64 -d > ${OUTPUT_PATH}/root/keys.jks - - NETWORKMAP_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["networkmap.jks"]') - mkdir -p ${OUTPUT_PATH}/network-map; - echo "${NETWORKMAP_KEY}" | base64 -d > ${OUTPUT_PATH}/network-map/keys.jks - - chmod 777 -R {{ .Values.image.mountPath.basePath }}/db - volumeMounts: - - name: certs - mountPath: "{{ .Values.image.mountPath.basePath }}/db/certs/" - readOnly: false - - name: init-certificates-tls - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}-tls/certs/ - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server: ${VAULT_ADDR}" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - echo "VAULT TOKEN IS : ${VAULT_TOKEN}" - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${MOUNT_PATH} - - if [ "{{ .Values.image.tlsCertificate }}" == true ] - then - # get networkmap tls cert and key from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/{{ .Values.vault.tlscertsecretprefix }} | jq -r 'if .errors then . else . end') - validateVaultResponse "${{ .Values.vault.tlscertsecretprefix }}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - NETWORKMAP_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["tlscacerts"]') - NETWORKMAP_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["tlskey"]') - echo "check-1 $NETWORKMAP_CRT" - echo "check-2 $NETWORKMAP_KEY" - echo "${NETWORKMAP_CRT}" | base64 -d > {{ .Values.image.mountPath.basePath }}-tls/certs/networkmap.crt - echo "${NETWORKMAP_KEY}" | base64 -d > {{ .Values.image.mountPath.basePath }}-tls/certs/networkmap.key - fi - - # get mongo tls cert from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/{{ .Values.vault.dbcertsecretprefix }} | jq -r 'if .errors then . else . end') - validateVaultResponse "{{ .Values.vault.dbcertsecretprefix }}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - CA_CERT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["mongoCA.crt"]') - echo "${CA_CERT}" | base64 -d > ${OUTPUT_PATH}/mongoCA.crt - echo "$CA_CERT" - # add permissions to dir - chmod 777 -R {{ .Values.image.mountPath.basePath }}-tls/certs/ - volumeMounts: - - name: tls-certs - mountPath: "{{ .Values.image.mountPath.basePath }}-tls/certs/" - readOnly: false - - name: init-certificates-cred - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: /opt/creds - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: DB_CRED_SECRET_PREFIX - value: {{ .Values.vault.dbcredsecretprefix }} - - name: USER_SECRET_PREFIX - value: {{ .Values.vault.secretnetworkmappass }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - # Login to Vault and so I can get an approle token - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${MOUNT_PATH} - - LOOKUP_PWD_RESPONSE_DB_PASS=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_CRED_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "${DB_CRED_SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE_DB_PASS}" "LOOKUPSECRETRESPONSE" - MONGODB_PASSWORD=$(echo ${LOOKUP_PWD_RESPONSE_DB_PASS} | jq -r '.data.data["mongodbPassword"]') - - echo "${MONGODB_PASSWORD}" >> ${MOUNT_PATH}/db_root_password - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${USER_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "${USER_SECRET_PREFIX}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - USER_PASSWORD=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["{{ .Values.image.authusername }}"]') - echo "${USER_PASSWORD}" >> ${MOUNT_PATH}/user_cred - - volumeMounts: - - name: creds - mountPath: "/opt/creds" - readOnly: false - - name: changepermissions - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}/db/certs - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - chmod 777 -R {{ .Values.image.mountPath.basePath }}; - volumeMounts: - - name: {{ .Values.nodeName }}-servicedata - mountPath: "{{ .Values.image.mountPath.basePath }}/db" - readOnly: false - - name: db-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - while [ "$COUNTER" -le {{ $.Values.healthcheck.readinessthreshold }} ] - do - DB_NODE={{ .Values.healthcheck.dburl }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.healthcheck.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - if [ "$COUNTER" -gt {{ $.Values.healthcheck.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: {{ .Values.nodeName }}-servicedata - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}-pvc - - name: certs - emptyDir: - medium: Memory - - name: creds - emptyDir: - medium: Memory - - name: tls-certs - emptyDir: - medium: Memory diff --git a/platforms/r3-corda/charts/corda-networkmap-tls/templates/service.yaml b/platforms/r3-corda/charts/corda-networkmap-tls/templates/service.yaml deleted file mode 100644 index f3035e4dc20..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap-tls/templates/service.yaml +++ /dev/null @@ -1,70 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.nodeName }} - namespace: {{ $.Values.metadata.namespace }} - annotations: - labels: - run: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - selector: - app: {{ .Values.nodeName }} - type: {{ .Values.service.type }} - ports: - - protocol: TCP - port: {{ .Values.service.port }} - targetPort: {{ .Values.service.targetPort }} - {{- if .Values.service.nodePort }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} -{{ if $.Values.ambassador }} ---- -apiVersion: getambassador.io/v3alpha1 -kind: Host -metadata: - name: {{ .Values.nodeName }}-host -spec: - hostname: {{ .Values.nodeName }}.{{ .Values.ambassador.external_url_suffix }} - acmeProvider: - authority: none - requestPolicy: - insecure: - action: Route - tlsSecret: - name: {{ .Values.nodeName }}-ambassador-certs - namespace: {{ .Values.metadata.namespace }} ---- -apiVersion: getambassador.io/v3alpha1 -kind: Mapping -metadata: - name: {{ .Values.nodeName }}-mapping - namespace: {{ .Values.metadata.namespace }} -spec: - host: {{ .Values.nodeName }}.{{ .Values.ambassador.external_url_suffix }} - prefix: / - service: https://{{ .Values.nodeName }}.{{ .Values.metadata.namespace }}:{{ .Values.service.port }} - tls: {{ .Values.nodeName }}-tlscontext ---- -apiVersion: getambassador.io/v3alpha1 -kind: TLSContext -metadata: - name: {{ .Values.nodeName }}-tlscontext - namespace: {{ .Values.metadata.namespace }} -spec: - hosts: - - {{ .Values.nodeName }}.{{ .Values.ambassador.external_url_suffix }} - secret: {{ .Values.nodeName }}-ambassador-certs.{{ .Values.metadata.namespace }} - secret_namespacing: true - min_tls_version: v1.2 -{{- end }} - diff --git a/platforms/r3-corda/charts/corda-networkmap-tls/templates/volume.yaml b/platforms/r3-corda/charts/corda-networkmap-tls/templates/volume.yaml deleted file mode 100644 index ed662b428c9..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap-tls/templates/volume.yaml +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.nodeName }}-pvc - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }}-pvc - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - storageClassName: {{ .Values.storage.name }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.storage.memory }} \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-networkmap-tls/values.yaml b/platforms/r3-corda/charts/corda-networkmap-tls/values.yaml deleted file mode 100644 index 56c681d49a0..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap-tls/values.yaml +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Default values for nmschart. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -#Provide the Name for node to be deployed -#Eg. nodeName: network-map -nodeName: network-map - -metadata: - #Provide the namespace - #Eg. namespace: default - namespace: default - -image: - #Provide the name of image for init container - #Eg. initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - #Provide the containerName of image - containerName: ghcr.io/hyperledger/bevel-networkmap-linuxkit:latest - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: - #Provide enviroment variable for container image - env: - #Provide rootcaname for the doorman - #Eg. rootcaname: CN=Corda Root CA, OU=FRA, O=FRA, L=London, ST=London, C=BR - rootcaname: - tlscertpath: - tlskeypath: - #Provide whether TLS is enabled or not - #Eg. tls: false - tls: - #Provide whether to enable Corda doorman protocol - #Eg. doorman: true - doorman: - #Provide whether to enable Cordite certman protocol so that nodes can authenticate using a signed TLS cert - #Eg. certman: true - certman: - #Provide database directory for this service - #Eg. database: db - database: - #Provide MongoDB connection string. If set to embed will start its own mongo instance - #Eg. dataSourceUrl: db - dataSourceUrl: - -service: - #Provide the NMS service port - #Eg. port: 30007 - port: 30007 - #Provide the type of service - #Eg. type: NodePort - type: NodePort - #Provide the node port for node service to be accessible outside - #Eg. nodePort: 30050 - nodePort: - -storage: - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - -vault: - #Provide the vault server address - #Eg. address: http://34.228.219.208:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: vault-role - #Eg. authpath: cordanms - authpath: cordanms - #Provide the kubernetes auth backed configured in vault - #Eg. secretprefix: - secretprefix: - #Eg. imagesecretname: - imagesecretname: - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: vault-auth-issuer - #Path in vault where tls certificates are present - tlscertsecretprefix: - -ambassador: - #Provides the suffix to be used in external URL - #Eg. external_url_suffix: org1.blockchaincloudpoc.com - external_url_suffix: diff --git a/platforms/r3-corda/charts/corda-networkmap/Chart.yaml b/platforms/r3-corda/charts/corda-networkmap/Chart.yaml deleted file mode 100644 index 75905e9de2f..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Deploys networkmap service without TLS." -name: corda-networkmap -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-networkmap/README.md b/platforms/r3-corda/charts/corda-networkmap/README.md deleted file mode 100644 index 0f3a690fee2..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap/README.md +++ /dev/null @@ -1,179 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# Nms Deployment - -- [Nms Deployment Helm Chart](#Nms-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - -## nms Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-networkmap) deploys a networkmap service without TLS. - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- NetworkMap and Node's database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - -## Chart Structure ---- -This chart has following structue: - -``` - - ├── nms - │ ├── Chart.yaml - │ ├── templates - │ │ ├── deployment.yaml - │ │ ├── Volume.yaml - │ │ └── service.yaml - │ └── values.yaml -``` - -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `deployment.yaml` : A Deployment controller provides declarative updates for Pods and ReplicaSets. -- `volume.yaml` : These PVCs can be used to provide persistent storage for the network map service deployment, allowing data to be stored and accessed across the lifecycle of the deployment. -- `service.yaml` : This file defines a Kubernetes Service with multiple ports for protocols and targets, and supports Ambassador proxy annotations for specific configurations when using the "ambassador" proxy provider. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the image, storage, service and vault. - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-networkmap/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | network-map | - -### Metadata - -| Name | Description | Default Value | -| ----------------| ---------------------------------------------------------------------------- | ------------- | -| namespace | Provide the namespace for the nms Generator | default | - -### Image - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| containerName | Provide the containerName of image | "" | -| imagePullSecret | Provide the image pull secret of image | regcred | -| env | Provide enviroment variable for container image | "" | - -### Service - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------ | ------------- | -| type | Provide the type of service | "NodePort" | -| port | Provide the NMS service port | "30007" | -| nodePort | Provide the node port for node service to be accessible outside| "32001" | - - -### storage - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| Memory | Provide the memory for node | "4Gi" | - - -### Vault - -| Name | Description | Default Value | -| ------------------------- | --------------------------------------------------------------------------| ------------- | -| address | Address/URL of the Vault server | "" | -| role | Role used for authentication with Vault | vault-role | -| authpath | Authentication path for Vault | cordanms | -| secretprefix | Provide the kubernetes auth backed configured in vault | "" | -| imagesecretname | specify the name of the Kubernetes secret | "" | -| serviceaccountname | To authenticate with the Vault server and retrieve the secrets |vault-auth-issuer| -| ambassador | Provides the suffix to be used in external URL |"" | - - - - -## Deployment ---- - -To deploy the nms Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-networkmap/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade, verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-networkmap -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-networkmap -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [Nms Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-networkmap), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-networkmap/templates/deployment.yaml b/platforms/r3-corda/charts/corda-networkmap/templates/deployment.yaml deleted file mode 100644 index 74cb9553ef3..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap/templates/deployment.yaml +++ /dev/null @@ -1,312 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Deployment -# Creates the replicated container and manages lifecycle -# TLS certs mounted -# Persistent Volume mounted -# Service points to this deployment (uses labels!) -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.nodeName }} - namespace: {{ .Values.metadata.namespace }} - {{- if .Values.deployment.annotations }} - annotations: -{{ toYaml .Values.deployment.annotations | indent 8 }} - {{- end }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - template: - metadata: - labels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: {{ .Values.nodeName }}-service - image: {{ .Values.image.containerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - {{- range $.Values.image.env }} - export {{ .name }}="{{ .value }}" - {{- end }} - export DB_PASSWORD=`cat /opt/creds/db_root_password` - export NETWORKMAP_MONGO_CONNECTION_STRING="mongodb://${DB_USERNAME}:${DB_PASSWORD}@${DB_URL}:${DB_PORT}/${DATABASE}" - export NETWORKMAP_AUTH_PASSWORD=`cat /opt/creds/user_cred` - java -jar {{ .Values.image.mountPath.basePath }}/network-map-service.jar 2>&1 - ports: - - containerPort: {{ .Values.service.targetPort }} - volumeMounts: - - name: {{ .Values.nodeName }}-servicedata - mountPath: "{{ .Values.image.mountPath.basePath }}/db" - readOnly: false - - name: {{ .Values.nodeName }}-logs - mountPath: "{{ .Values.image.mountPath.basePath }}/logs" - readOnly: false - - name: certs - mountPath: "{{ .Values.image.mountPath.basePath }}/db/certs" - readOnly: false - - name: creds - mountPath: "/opt/creds" - readOnly: false - - name: logs - image: "{{ .Values.image.initContainerName }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["sh", "-c"] - args: - - |- - cd /opt/networkmap/ - COUNTER=1 - NETWORK_ROOT_TRUST=/opt/networkmap/network-map-truststore.jks - while [ "$COUNTER" -le {{ $.Values.healthcheck.readinessthreshold }} ] - do - curl http://localhost:8080/network-map/truststore --output network-map-truststore.jks - if [ -f "$NETWORK_ROOT_TRUST" ] - then - echo "SUCCESS!" - echo "NMS running and fetched truststore" - break - else - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - fi - done - if ["$COUNTER" -gt {{ $.Values.healthcheck.readinessthreshold }} ] - then - exit 1 - fi - while true; do tail -f ./logs/*.log 2>/dev/null; sleep 5; done - volumeMounts: - - name: {{ .Values.nodeName }}-logs - mountPath: "{{ .Values.image.mountPath.basePath }}/logs" - initContainers: - - name: init-certificates - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}/db/certs/ - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - OUTPUT_PATH=${MOUNT_PATH} - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/{{ .Values.vault.certsecretprefix }} | jq -r 'if .errors then . else . end') - - validateVaultResponse "${{ .Values.vault.certsecretprefix }}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - - ROOTCA_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["rootcakey"]') - mkdir -p ${OUTPUT_PATH}/root; - echo "${ROOTCA_KEY}" | base64 -d > ${OUTPUT_PATH}/root/keys.jks - - NETWORKMAP_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["networkmap.jks"]') - mkdir -p ${OUTPUT_PATH}/network-map; - echo "${NETWORKMAP_KEY}" | base64 -d > ${OUTPUT_PATH}/network-map/keys.jks - - chmod 777 -R {{ .Values.image.mountPath.basePath }}/db - volumeMounts: - - name: certs - mountPath: "{{ .Values.image.mountPath.basePath }}/db/certs/" - readOnly: false - - name: init-certificates-cred - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: /opt/creds - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: DB_CRED_SECRET_PREFIX - value: {{ .Values.vault.dbcredsecretprefix }} - - name: USER_SECRET_PREFIX - value: {{ .Values.vault.secretnetworkmappass }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - # Login to Vault and so I can get an approle token - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - OUTPUT_PATH=${MOUNT_PATH} - - LOOKUP_PWD_RESPONSE_DB_PASS=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_CRED_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "${DB_CRED_SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE_DB_PASS}" "LOOKUPSECRETRESPONSE" - MONGODB_PASSWORD=$(echo ${LOOKUP_PWD_RESPONSE_DB_PASS} | jq -r '.data.data["mongodbPassword"]') - - echo "${MONGODB_PASSWORD}" >> ${MOUNT_PATH}/db_root_password - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${USER_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "secret (${CERTS_SECRET_PREFIX})" "${LOOKUP_SECRET_RESPONSE}" - USER_PASSWORD=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["{{ .Values.image.authusername }}"]') - echo "${USER_PASSWORD}" >> ${MOUNT_PATH}/user_cred - - volumeMounts: - - name: creds - mountPath: "/opt/creds" - readOnly: false - - name: changepermissions - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: MOUNT_PATH - value: {{ .Values.image.mountPath.basePath }}/db/certs - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: SECRET_PREFIX - value: {{.Values.vault.secretprefix}} - command: ["sh", "-c"] - args: - - |- - chmod 777 -R {{ .Values.image.mountPath.basePath }}; - volumeMounts: - - name: {{ .Values.nodeName }}-servicedata - mountPath: "{{ .Values.image.mountPath.basePath }}/db" - readOnly: false - - name: db-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - while [ "$COUNTER" -le {{ $.Values.healthcheck.readinessthreshold }} ] - do - DB_NODE={{ .Values.healthcheck.dburl }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.healthcheck.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - if [ "$COUNTER" -gt {{ $.Values.healthcheck.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: {{ .Values.nodeName }}-servicedata - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}-pvc - - name: {{ .Values.nodeName }}-logs - persistentVolumeClaim: - claimName: {{ .Values.nodeName }}-pvc-logs - - name: certs - emptyDir: - medium: Memory - - name: creds - emptyDir: - medium: Memory diff --git a/platforms/r3-corda/charts/corda-networkmap/templates/service.yaml b/platforms/r3-corda/charts/corda-networkmap/templates/service.yaml deleted file mode 100644 index 93833c487df..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap/templates/service.yaml +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.nodeName }} - namespace: {{ $.Values.metadata.namespace }} - annotations: - labels: - run: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - selector: - app: {{ .Values.nodeName }} - type: {{ .Values.service.type }} - ports: - - protocol: TCP - port: {{ .Values.service.port }} - targetPort: {{ .Values.service.targetPort }} - {{- if .Values.service.nodePort }} - nodePort: {{ .Values.service.nodePort}} - {{- end }} - -{{ if $.Values.ambassador }} ---- -apiVersion: getambassador.io/v3alpha1 -kind: Mapping -metadata: - name: {{ .Values.nodeName }}-mapping - namespace: {{ .Values.metadata.namespace }} -spec: - hostname: {{ .Values.nodeName }}.{{ .Values.ambassador.external_url_suffix }} - prefix: / - service: {{ .Values.nodeName }}.{{ .Values.metadata.namespace }}:{{ .Values.service.port }} -{{ end }} - diff --git a/platforms/r3-corda/charts/corda-networkmap/templates/volume.yaml b/platforms/r3-corda/charts/corda-networkmap/templates/volume.yaml deleted file mode 100644 index 1d487cfe4e5..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap/templates/volume.yaml +++ /dev/null @@ -1,42 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.nodeName }}-pvc - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }}-pvc - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - storageClassName: {{ .Values.storage.name }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.storage.memory }} ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.nodeName }}-pvc-logs - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }}-pvc-logs - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - storageClassName: {{ .Values.storage.name }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.storage.memory }} \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-networkmap/values.yaml b/platforms/r3-corda/charts/corda-networkmap/values.yaml deleted file mode 100644 index c1a73197c0a..00000000000 --- a/platforms/r3-corda/charts/corda-networkmap/values.yaml +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -# Default values for nmschart. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -#Provide the Name for node to be deployed -#Eg. nodeName: network-map -nodeName: network-map - -metadata: - #Provide the namespace - #Eg. namespace: default - namespace: default - -image: - #Provide the name of image for init container - #Eg. initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - #Provide the containerName of image - containerName: ghcr.io/hyperledger/bevel-networkmap-linuxkit:latest - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: regcred - #Provide enviroment variable for container image - env: - #Provide rootcaname for the doorman - #Eg. rootcaname: CN=Corda Root CA, OU=FRA, O=FRA, L=London, ST=London, C=BR - rootcaname: - tlscertpath: - tlskeypath: - #Provide whether TLS is enabled or not - #Eg. tls: false - tls: - #Provide whether to enable Corda doorman protocol - #Eg. doorman: true - doorman: - #Provide whether to enable Cordite certman protocol so that nodes can authenticate using a signed TLS cert - #Eg. certman: true - certman: - #Provide database directory for this service - #Eg. database: db - database: - #Provide MongoDB connection string. If set to embed will start its own mongo instance - #Eg. dataSourceUrl: db - dataSourceUrl: - -service: - #Provide the NMS service port - #Eg. port: 30007 - port: 30007 - #Provide the type of service - #Eg. type: NodePort - type: NodePort - #Provide the node port for node service to be accessible outside - #Eg. nodePort: 30050 - nodePort: - -storage: - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - -vault: - #Provide the vault server address - #Eg. address: http://34.228.219.208:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: vault-role - #Eg. authpath: cordanms - authpath: cordanms - #Provide the kubernetes auth backed configured in vault - #Eg. secretprefix: - secretprefix: - #Eg. imagesecretname: - imagesecretname: - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: vault-auth-issuer -ambassador: - #Provides the suffix to be used in external URL - #Eg. external_url_suffix: org1.blockchaincloudpoc.com - external_url_suffix: diff --git a/platforms/r3-corda/charts/corda-node-initial-registration/Chart.yaml b/platforms/r3-corda/charts/corda-node-initial-registration/Chart.yaml deleted file mode 100644 index 6ec236e2889..00000000000 --- a/platforms/r3-corda/charts/corda-node-initial-registration/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Job for initial node registration." -name: corda-node-initial-registration -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-node-initial-registration/README.md b/platforms/r3-corda/charts/corda-node-initial-registration/README.md deleted file mode 100644 index a9f0ec710a8..00000000000 --- a/platforms/r3-corda/charts/corda-node-initial-registration/README.md +++ /dev/null @@ -1,231 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# Node Deployment - -- [Node-initial-registration Deployment Helm Chart](#Node-initial-registration-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - - -## node-initial-registration Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-node-initial-registration) helps to delpoy the job for registering the r3corda node. - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- Node's database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - -This chart has following structue: -``` - . - ├── node-initial-registration - │ ├── templates - │ │ ├── _helpers.tpl - │ │ └── job.yaml - | ├── Chart.yaml - │ └── values.yaml -``` - -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `job.yaml` : This file is a configuration file for deployement in Kubernetes.It creates a deployment file with a specified number of replicas and defines various settings for the deployment. Including volume mounts, environment variables, and ports for the container. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the image, nodeconfig, credenatials, storage, service , vault, etc. -- `_helpers.tpl` : A template file used for defining custom labels and ports for the metrics in the Helm chart. - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-node-initial-registration/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | bank1 | - -### Metadata - -| Name | Description | Default Value | -| ----------------| ---------------------------------------------------------------------------- | ------------- | -| namespace | Provide the namespace for the Node-initial-registration Generator | default | -| labels | Provide any additional labels for the Node-initial-registration Generator | "" | - -### Image - -| Name | Description | Default Value | -| ------------------------ | --------------------------------------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| containerName | Provide the containerName of image | "" | -| imagePullSecret | Provide the image pull secret of image | regcred | -| privateCertificate | Provide true or false if private certificate to be added | "true" | -| doormanCertAlias | Provide true or false if private certificate to be added | "" | -| networkmapCertAlias | Provide true or false if private certificate to be added | "" | - -### NodeConf - -| Name | Description | Default Value | -| ------------------------ | -------------------------------------------------------------------------------------- | --------------- | -| p2p | The host and port on which the node is available for protocol operations over ArtemisMQ | "" | -| ambassadorAddress | Specify ambassador host:port which will be advertised in addition to p2paddress | "" | -| legalName | Provide the legalName for node | "" | -| dbUrl | Provide the h2Url for node | "bank1h2" | -| dbPort | Provide the h2Port for node | "9101" | -| networkMapURL | Provide the nms for node | "" | -| doormanURL | Provide the doorman for node | "" | -| jarVersion | Provide the jar Version for corda jar and finanace jar | "3.3-corda" | -| devMode | Provide the devMode for corda node | "true" | -| env | Provide the enviroment variables to be set | "" | - -### credentials - -| Name | Description | Default Value | -| ----------------| ----------------------------------------------| ------------- | -| dataSourceUser | Provide the dataSourceUser for corda node | "" | -| rpcUser | Provide the rpcUser for corda node | bank1operations| - -### Volume - -| Name | Description | Default Value | -| -----------------| -----------------------| ------------- | -| baseDir | Base directory | /home/bevel | - -### Resources - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| limits | Provide the limit memory for node | "1Gi" | -| requests | Provide the requests memory for node | "1Gi" | - -### storage - -| Name | Description | Default Value | -| --------------------- | -------------------------------------------------------- | ------------- | -| provisioner | Provide the provisioner for node | "" | -| name | Provide the name for node | bank1nodesc | -| memory | Provide the memory for node | "4Gi" | -| type | Provide the type for node | "gp2" | -| encrypted | Provide whether the EBS volume should be encrypted or not | "true" | -| annotations | Provide the annotation of the node | "" | - -### Service - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| type | Provide the type of service | NodePort | -| p2p port | Provide the tcp port for node | 10007 | -| p2p nodePort | Provide the p2p nodeport for node | 30007 | -| p2p targetPort | Provide the p2p targetPort for node | 30007 | -| rpc port | Provide the tpc port for node | 10008 | -| rpc targetPort | Provide the rpc targetport for node | 10003 | -| rpc nodePort | Provide the rpc nodePort for node | 30007 | -| rpcadmin port | Provide the rpcadmin port for node | 10108 | -| rpcadmin targetPort | Provide the rpcadmin targetport for node | 10005 | -| rpcadmin nodePort | Provide the rpcadmin nodePort for node | 30007 | - -### Vault - -| Name | Description | Default Value | -| ------------------------- | --------------------------------------------------------------------------| ------------------------- | -| address | Address/URL of the Vault server. | "" | -| role | Role used for authentication with Vault | vault-role | -| authpath | Authentication path for Vault | cordabank1 | -| serviceAccountName | Provide the already created service account name autheticated to vault | vault-auth-issuer | -| certSecretPrefix | Provide the vault path where the certificates are stored | bank1/certs | -| dbsecretprefix | Provide the secretprefix | bank1/credentials/database | -| rpcusersecretprefix | Provide the secretprefix | bank1/credentials/rpcusers | -| keystoresecretprefix | Provide the secretprefix | bank1/credentials/keystore | -| retires | Provide the no of retires | "" | - -### Healthcheck - -| Name | Description | Default Value | -| ----------------------------| ------------------------------------------------------------------------------| ------------- | -| readinesscheckinterval | Provide the interval in seconds you want to iterate till db to be ready | 5 | -| readinessthreshold | Provide the threshold till you want to check if specified db up and running | 2 | - - - -## Deployment ---- - -To deploy the node-initial-registration Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-node-initial-registration/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade,verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-node-initial-registration -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-node-initial-registration -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [node-initial-registration Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-node-initial-registration), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-node-initial-registration/templates/_helpers.tpl b/platforms/r3-corda/charts/corda-node-initial-registration/templates/_helpers.tpl deleted file mode 100644 index 7bf5f530a8e..00000000000 --- a/platforms/r3-corda/charts/corda-node-initial-registration/templates/_helpers.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{{- define "labels.custom" }} - {{ range $key, $val := $.Values.metadata.labels }} - {{ $key }}: {{ $val }} - {{ end }} -{{- end }} \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-node-initial-registration/templates/job.yaml b/platforms/r3-corda/charts/corda-node-initial-registration/templates/job.yaml deleted file mode 100644 index 178d93fe9c7..00000000000 --- a/platforms/r3-corda/charts/corda-node-initial-registration/templates/job.yaml +++ /dev/null @@ -1,545 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ .Values.nodeName }}-registration - namespace: {{ .Values.metadata.namespace }} - labels: - app: {{ .Values.nodeName }}-registration - app.kubernetes.io/name: {{ .Values.nodeName }}-registration - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - {{- include "labels.custom" . | nindent 2 }} -spec: - backoffLimit: 6 - template: - metadata: - labels: - app: {{ .Values.nodeName }}-initial-registration - app.kubernetes.io/name: {{ .Values.nodeName }}-registration - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - restartPolicy: "OnFailure" - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: node-initial-registration - image: {{ .Values.image.containerName }} - imagePullPolicy: Always - env: - - name: JAVA_OPTIONS - value: -Xmx512m - - name: CORDA_HOME - value: /opt/corda - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - rm -rf ${BASE_DIR}/certificates/done.txt - - # Setting up enviroment variables - export DEFAULT_TRUSTSTORE_PASSWORD=`cat /opt/node/creds/default_truststore_cred` - export KEYSTORE_PASSWORD=`cat /opt/node/creds/keystore_cred` - export TRUSTSTORE_PASSWORD=`cat /opt/node/creds/truststore_cred` - export DEFAULT_KEYSTORE_PASSWORD=`cat /opt/node/creds/default_keystore_cred` - - # import self signed tls certificate of doorman and networkmap, since java only trusts certificate signed by well known CA - {{- if .Values.image.privateCertificate }} - yes | keytool -importcert -file {{ $.Values.volume.baseDir }}/certificates/networkmap/networkmap.crt -storepass changeit -alias {{ $.Values.image.networkmapCertAlias }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - yes | keytool -importcert -file {{ $.Values.volume.baseDir }}/certificates/doorman/doorman.crt -storepass changeit -alias {{ $.Values.image.doormanCertAlias }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - {{- end }} - - # command to run corda jar and perform initial-registration - java $JAVA_OPTIONS -jar ${CORDA_HOME}/corda.jar initial-registration --network-root-truststore-password ${DEFAULT_TRUSTSTORE_PASSWORD} --network-root-truststore ${BASE_DIR}/certificates/network-map-truststore.jks --base-directory=${BASE_DIR} - - #changing password of keystore. - keytool -storepasswd -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${DEFAULT_KEYSTORE_PASSWORD} - keytool -storepasswd -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/sslkeystore.jks -storepass ${DEFAULT_KEYSTORE_PASSWORD} - keytool -storepasswd -new ${TRUSTSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/truststore.jks -storepass ${DEFAULT_TRUSTSTORE_PASSWORD} - - #changing password of nodekeystore.jks certificate. - keytool -keypasswd -alias cordaclientca -keypass ${DEFAULT_KEYSTORE_PASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${KEYSTORE_PASSWORD} - keytool -keypasswd -alias identity-private-key -keypass ${DEFAULT_KEYSTORE_PASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${KEYSTORE_PASSWORD} - - #changing password of sslkeystore.jks certificate. - keytool -keypasswd -alias cordaclienttls -keypass ${DEFAULT_KEYSTORE_PASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/sslkeystore.jks -storepass ${KEYSTORE_PASSWORD} - - # create dummy file to perform check if last line of the container is executed or not - touch ${BASE_DIR}/certificates/done.txt - volumeMounts: - - name: node-volume - mountPath: "{{ $.Values.volume.baseDir }}" - readOnly: false - - name: certificates - mountPath: "{{ $.Values.volume.baseDir }}/certificates" - readOnly: false - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}/node.conf" - subPath: "node.conf" - readOnly: false - - name: creds - mountPath: "/opt/node/creds" - readOnly: false - - name: store-certs - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: CERTS_SECRET_PREFIX - value: {{ .Values.vault.certsecretprefix }} - - name: JAVA_OPTIONS - value: -Xmx512m - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - - OUTPUT_PATH=${BASE_DIR} - - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - - # perform check if certificates are ready or not, and upload certificate into vault when ready - COUNTER=1 - cd ${BASE_DIR}/certificates - while [ "$COUNTER" -lt {{ $.Values.healthcheck.readinessthreshold }} ] - do - if [ -e nodekeystore.jks ] && [ -e sslkeystore.jks ] && [ -e truststore.jks ] && [ -e done.txt ] - then - echo "found certificates, performing vault put" - (echo '{"data": {"nodekeystore.jks": "'; base64 ${BASE_DIR}/certificates/nodekeystore.jks; echo '"}}') | curl -H "X-Vault-Token: ${VAULT_TOKEN}" -d @- ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/nodekeystore - (echo '{"data": {"sslkeystore.jks": "'; base64 ${BASE_DIR}/certificates/sslkeystore.jks; echo '"}}') | curl -H "X-Vault-Token: ${VAULT_TOKEN}" -d @- ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/sslkeystore - (echo '{"data": {"truststore.jks": "'; base64 ${BASE_DIR}/certificates/truststore.jks; echo '"}}') | curl -H "X-Vault-Token: ${VAULT_TOKEN}" -d @- ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore - # get nodekeystore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/nodekeystore | jq -r 'if .errors then . else . end') - TLS_NODEKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "nodekeystore.jks" ]' 2>&1) - # get sslkeystore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/sslkeystore | jq -r 'if .errors then . else . end') - TLS_SSLKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "sslkeystore.jks" ]' 2>&1) - # get truststore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore | jq -r 'if .errors then . else . end') - TLS_TRUSTSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "truststore.jks" ]' 2>&1) - if [ "$TLS_NODEKEYSTORE" == "null" ] || [ "$TLS_SSLKEYSTORE" == "null" ] || [ "$TLS_TRUSTSTORE" == "null" ] || [[ "$TLS_NODEKEYSTORE" == "parse error"* ]] || [[ "$TLS_SSLKEYSTORE" == "parse error"* ]] || [[ "$TLS_TRUSTSTORE" == "parse error"* ]] - then - echo "certificates write or read fail" - sleep {{ $.Values.healthcheck.readinessthreshold }} - if [ "$COUNTER" -ge {{ $.Values.vault.retries }} ] - then - echo "Retry attempted $COUNTER times, certificates have not been saved" - exit 1 - fi - fi - COUNTER=`expr "$COUNTER" + 1` - fi - done - volumeMounts: - - name: node-volume - mountPath: "{{ $.Values.volume.baseDir }}" - readOnly: false - - name: certificates - mountPath: "{{ $.Values.volume.baseDir }}/certificates" - readOnly: false - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}/node.conf" - subPath: "node.conf" - readOnly: false - initContainers: - - name: init-nodeconf - image : {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: KS_SECRET_PREFIX - value: {{ .Values.vault.keystoresecretprefix }} - - name: DB_SECRET_PREFIX - value: {{ .Values.vault.dbsecretprefix }} - - name: RPCUSER_SECRET_PREFIX - value: {{ .Values.vault.rpcusersecretprefix }} - command: ["/bin/sh","-c"] - args: - - |- - #!/bin/bash - # delete previously created node.conf, and create a new node.conf - rm -f ${BASE_DIR}/node.conf; - touch ${BASE_DIR}/node.conf; - - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - - # save keyStorePassword & trustStorePassword from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - CONF_KEYSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["defaultKeyStorePassword"]') - CONF_TRUSTSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["defaultTrustStorePassword"]') - - # save dataSourceUserPassword from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - CONF_DATASOURCEPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["{{ .Values.credentials.dataSourceUser }}"]') - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${RPCUSER_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - - #For more information for node.Conf fields please refer to: https://docs.corda.r3.com/releases/4.0/corda-configuration-file.html - cat << EOF > ${BASE_DIR}/node.conf - p2pAddress : "{{ .Values.nodeConf.p2p.url }}:{{ .Values.nodeConf.p2p.port }}" - myLegalName : "{{ .Values.nodeConf.legalName }}" - keyStorePassword : "${CONF_KEYSTOREPASSWORD}" - trustStorePassword : "${CONF_TRUSTSTOREPASSWORD}" - transactionCacheSizeMegaBytes : {{ .Values.nodeConf.transactionCacheSizeMegaBytes }} - attachmentContentCacheSizeMegaBytes : {{ .Values.nodeConf.attachmentContentCacheSizeMegaBytes }} - detectPublicIp = {{ .Values.nodeConf.detectPublicIp }} - additionalP2PAddresses = ["{{ .Values.nodeConf.ambassadorAddress }}"] - devMode : {{ .Values.nodeConf.devMode }} - dataSourceProperties = { - dataSourceClassName = "{{ .Values.nodeConf.dataSourceClassName }}" - dataSource.url = "{{ .Values.nodeConf.dataSourceUrl }}" - dataSource.user = {{ .Values.credentials.dataSourceUser }} - dataSource.password = "${CONF_DATASOURCEPASSWORD}" - } - database = { - exportHibernateJMXStatistics = {{ .Values.nodeConf.database.exportHibernateJMXStatistics }} - } - jarDirs = ["{{ .Values.nodeConf.jarPath }}"] - EOF - - if [ -z "{{ .Values.nodeConf.compatibilityZoneURL }}" ] - then - echo 'networkServices = { - doormanURL = "{{ .Values.nodeConf.doormanURL }}" - networkMapURL = "{{ .Values.nodeConf.networkMapURL }}" - }' >> ${BASE_DIR}/node.conf - else - echo 'compatibilityZoneURL : "{{ .Values.nodeConf.compatibilityZoneURL }}"' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.jvmArgs }}" ] - then - echo 'jvmArgs is not configured' - else - echo 'jvmArgs = "{{ .Values.nodeConf.jvmArgs }}" ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.sshd.port }}" ] - then - echo 'sshd port is not configured' - else - echo 'sshd { port = {{ .Values.nodeConf.sshd.port }} } ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.systemProperties }}" ] - then - echo 'systemProperties is not configured' - else - echo 'systemProperties = {{ .Values.nodeConf.systemProperties }} ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.exportJMXTo }}" ] - then - echo 'exportJMXTo is not configured' - else - echo 'exportJMXTo = {{ .Values.nodeConf.exportJMXTo }} ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.messagingServerAddress }}" ] - then - echo 'The address of the ArtemisMQ broker instance is not configured' - else - echo 'messagingServerAddress : "{{ .Values.nodeConf.messagingServerAddress }}" ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.credentials.rpcUser }}" ] - then - echo 'rpc useer is not configured' - else - echo 'rpcUsers : [' >> ${BASE_DIR}/node.conf - {{- range $.Values.credentials.rpcUser }} - echo '{ username={{ .name }} ,permissions={{ .permissions }} , ' >> ${BASE_DIR}/node.conf - echo " password=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["{{ .name }}"]') }" >> ${BASE_DIR}/node.conf - {{- end }} - echo ']' >> ${BASE_DIR}/node.conf - fi - - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - if [ "{{ .Values.nodeConf.rpcSettings.useSsl }}" == true ] - then - echo "rpcSettings { - standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} - address = "{{ .Values.nodeConf.rpcSettings.address }}" - adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" - useSsl = {{ .Values.nodeConf.rpcSettings.useSsl }} - ssl = { - keyStorePassword = $(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["sslkeyStorePassword"]') - trustStorePassword = $(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["ssltrustStorePassword"]') - certificatesDirectory = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }} - sslKeystore = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.sslKeystoreFileName }} - trustStoreFile = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.trustStoreFileName }} - } - }" >> ${BASE_DIR}/node.conf - else - echo 'rpcSettings { - standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} - address = "{{ .Values.nodeConf.rpcSettings.address }}" - adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" - }' >> ${BASE_DIR}/node.conf - fi - echo "node.conf created in ${BASE_DIR}" - volumeMounts: - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}" - - name: init-certificates - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: CERTS_SECRET_PREFIX - value: {{.Values.vault.certsecretprefix}} - - name: H2SSL_SECRET_PREFIX - value: {{ .Values.vault.h2sslsecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - # To check if custom nodekeystore is retrived from vault, if yes then store it in nodekeystore.jks - validateVaultResponseCustomnodeKeystore () { - if echo ${2} | grep "errors"; - then - echo "custom nodekeystore.jks is not provided and new one will be created." - else - echo "Found custom nodekeystore.jks" - echo "${NODE_KEY}" | base64 -d > ${OUTPUT_PATH}/nodekeystore.jks - fi - } - - # To check if certificates are already present in vault or not - validateVaultResponseKeystore () { - if echo ${2} | grep "errors"; - then - echo "Initial registration will create keystore ${1}" - else - echo "Initial registration was performed before." - exit 1 - fi - } - - # setting up env to get secrets from vault - echo "Getting secrets from Vault Server" - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${BASE_DIR} - - # get customnodekeystore from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/customnodekeystore ) - NODE_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["nodekeystore.jks"]') - validateVaultResponseCustomnodeKeystore "secret (${CERTS_SECRET_PREFIX}/customnodekeystore)" "${LOOKUP_SECRET_RESPONSE}" - - # get network-map-truststore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/networkmaptruststore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/networkmaptruststore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TLS_NMS=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["network-map-truststore"]') - echo "${TLS_NMS}" | base64 -d > ${OUTPUT_PATH}/network-map-truststore.jks - - # To check if sslkeystore,nodekeystore,truststore are present in vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/nodekeystore | jq -r 'if .errors then . else . end') - validateVaultResponseKeystore "secret on (${CERTS_SECRET_PREFIX}/nodekeystore)" "${LOOKUP_SECRET_RESPONSE}" - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/sslkeystore | jq -r 'if .errors then . else . end') - validateVaultResponseKeystore "secret on (${CERTS_SECRET_PREFIX}/sslkeystore)" "${LOOKUP_SECRET_RESPONSE}" - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore | jq -r 'if .errors then . else . end') - validateVaultResponseKeystore "secret on (${CERTS_SECRET_PREFIX}/truststore)" "${LOOKUP_SECRET_RESPONSE}" - - # when using doorman and networkmap in TLS: true, and using private certificate then download certificate - if [ "{{ .Values.image.privateCertificate }}" == true ] - then - mkdir -p ${OUTPUT_PATH}/networkmap - mkdir -p ${OUTPUT_PATH}/doorman - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/networkmap | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/networkmap" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - NETWORKMAP_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["networkmap.crt"]') - echo "${NETWORKMAP_CRT}" | base64 -d > ${OUTPUT_PATH}/networkmap/networkmap.crt - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/doorman | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/doorman" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - DOORMAN_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["doorman.crt"]') - echo "${DOORMAN_CRT}" | base64 -d > ${OUTPUT_PATH}/doorman/doorman.crt - fi - chmod 777 -R ${BASE_DIR}/; - echo "Done" - volumeMounts: - - name: certificates - mountPath: {{ $.Values.volume.baseDir }} - - name: init-credential - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: BASE_DIR - value: /opt/node/creds - - name: KS_SECRET_PREFIX - value: {{ .Values.vault.keystoresecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${BASE_DIR} - - # get keystore passwords from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "${KS_SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE}" "LOOKUPSECRETRESPONSE" - DEFAULT_TRUSTSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["defaultTrustStorePassword"]') - DEFAULT_KEYSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["defaultKeyStorePassword"]') - KEYSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["keyStorePassword"]') - TRUSTSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["trustStorePassword"]') - echo "${DEFAULT_TRUSTSTOREPASSWORD}" >> ${BASE_DIR}/default_truststore_cred - echo "${KEYSTOREPASSWORD}" >> ${BASE_DIR}/keystore_cred - echo "${TRUSTSTOREPASSWORD}" >> ${BASE_DIR}/truststore_cred - echo "${DEFAULT_KEYSTOREPASSWORD}" >> ${BASE_DIR}/default_keystore_cred - - echo "Done" - volumeMounts: - - name: creds - mountPath: "/opt/node/creds" - readOnly: false - - name: db-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - # perform health check if db is up and running before starting corda node - while [ "$COUNTER" -le {{ $.Values.healthcheck.readinessthreshold }} ] - do - DB_NODE={{ .Values.nodeConf.dbUrl }}:{{ .Values.nodeConf.dbPort }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.healthcheck.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - - if [ "$COUNTER" -gt {{ $.Values.healthcheck.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: node-volume - emptyDir: - medium: Memory - - name: certificates - emptyDir: - medium: Memory - - name: nodeconf - emptyDir: - medium: Memory - - name: creds - emptyDir: - medium: Memory - diff --git a/platforms/r3-corda/charts/corda-node-initial-registration/values.yaml b/platforms/r3-corda/charts/corda-node-initial-registration/values.yaml deleted file mode 100644 index 6884c027bbc..00000000000 --- a/platforms/r3-corda/charts/corda-node-initial-registration/values.yaml +++ /dev/null @@ -1,232 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -#Provide the nodeName for node -#Eg. nodeName: bank1 -nodeName: bank1 - -#Provide the replica set for node deployed -#Eg. replicas: 1 -replicas: 1 - -metadata: - #Provide the namespace - #Eg. namespace: default - namespace: default - #Provide the custom labels - #NOTE: Provide labels other than name, release name , release service, chart version , chart name , app. - #Eg. labels: - # role: create_channel - labels: - -image: - #Provide the containerName of image - #Eg. containerName: ghcr.io/hyperledger/bevel-corda:4.9 - containerName: ghcr.io/hyperledger/bevel-corda:4.9 - #Provide the name of image for init container - #Eg. name: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: regcred - #Provide true or false if private certificate to be added - #Eg. privateCertificate: true - privateCertificate: true - #Provide true or false if private certificate to be added - #Eg. doormanCertAlias: doorman.fracordakubetest7.com - doormanCertAlias: doorman.fracordakubetest7.com - #Provide true or false if private certificate to be added - #Eg. networkmapCertAlias: networkmap.fracordakubetest7.com - networkmapCertAlias: networkmap.fracordakubetest7.com - - -#For more information for node.Conf fields please refer to: https://docs.corda.net/releases/release-V3.3/corda-configuration-file.html -nodeConf: - #The host and port on which the node is available for protocol operations over ArtemisMQ. - p2p: - url: - port: - #Specify the ambassador host:port which will be advertised in addition to p2paddress - ambassadorAddress: - rpcSettings: - useSsl: - standAloneBroker: - address: - adminAddress: - ssl: - certificatesDirectory: - sslKeystorePath: - trustStoreFilePath: - #Provide the legalName for node - #Eg. legalName: "O=Bank1,L=London,C=GB,CN=Bank1" - legalName: - messagingServerAddress: - jvmArgs: - systemProperties: - sshd: - port: - exportJMXTo: - transactionCacheSizeMegaBytes: - attachmentContentCacheSizeMegaBytes: - notary: - validating: - detectPublicIp: - database: - exportHibernateJMXStatistics: - #Provide the h2Url for node - #Eg. h2Url: bank1h2 - dbUrl: bank1h2 - #Provide the h2Port for node - #Eg. h2Port: 9101 - dbPort: 9101 - dataSourceClassName: - dataSourceUrl: - jarPath: - #Provide the nms for node - #Eg. nms: "http://rp-elb-fra-corda-kube-cluster7-2016021309.us-west-1.elb.amazonaws.com:30050" - networkMapURL: - doormanURL: - compatibilityZoneURL: - webAddress: - #Provide the jar Version for corda jar and finanace jar - #Eg. jarVersion: 3.3-corda - jarVersion: 3.3-corda - #Provide the devMode for corda node - #Eg. devMode: true - devMode: true - #Provide the enviroment variables to be set - env: - - name: JAVA_OPTIONS - value: - - name: CORDA_HOME - value: - - name: BASE_DIR - value: - -credentials: - #Provide the dataSourceUser for corda node - #Eg. dataSourceUser: - dataSourceUser: - #Provide the rpcUser for corda node - rpcUser: - - name: bank1operations - permissions: [ALL] - -volume: - #Provide the base path - #Eg. mountPath: "/opt/h2-data" - baseDir: - -resources: - #Provide the limit memory for node - #Eg. limits: "1Gi" - limits: "1Gi" - #Provide the requests memory for node - #Eg. requests: "1Gi" - requests: "1Gi" - -storage: - #Provide the provisioner for node - #Eg. provisioner: kubernetes.io/aws-ebs - provisioner: - #Provide the name for node - #Eg. name: bank1nodesc - name: bank1nodesc - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - parameters: - #Provide the type for node - #Eg. type: gp2 - type: gp2 - # Provide whether the EBS volume should be encrypted or not - #Eg. encrypted: "true" - encrypted: "true" - # annotations: - # key: "value" - annotations: - - -service: -# Note: Target ports are dependent on image being used. Please change them accordingly -# nodePort should be kept empty while using service type as ClusterIP ( Values.service.type ) - #Provide the type of service - #Eg. type: NodePort or LoadBalancer etc - type: NodePort - p2p: - #Provide the p2p port for node - #Eg. port: 10007 - port: 10007 - #Provide the p2p node port for node - #Eg. port: 30007 - nodePort: - #Provide the p2p targetPort for node - #Eg. targetPort: 30007 - targetPort: 30007 - rpc: - #Provide the rpc port for node - #Eg. port: 10008 - port: 10008 - #Provide the rpc targetPort for node - #Eg. targetPort: 10003 - targetPort: 10003 - #Provide the rpc node port for node - #Eg. nodePort: 30007 - nodePort: - rpcadmin: - #Provide the rpcadmin port for node - #Eg. port: 10108 - port: 10108 - #Provide the rpcadmin targetPort for node - #Eg. targetPort: 10005 - targetPort: 10005 - #Provide the rpcadmin node port for node - #Eg. nodePort: 30007 - nodePort: - # annotations: - # key: "value" - annotations: - -pvc: - # annotations: - # key: "value" - annotations: - -vault: - #Provide the vault server address - #Eg. address: http://54.226.163.39:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: vault-role - #Provide the authpath - #Eg. authpath: cordabank1 - authpath: cordabank1 - #Provide the serviceaccountname - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: vault-auth-issuer - #Provide the secretprefix - #Eg. dbsecretprefix: bank1/credentials/database - dbsecretprefix: bank1/credentials/database - #Provide the secretprefix - #Eg. rpcusersecretprefix: bank1/credentials/rpcusers - rpcusersecretprefix: bank1/credentials/rpcusers - #Provide the secretprefix - #Eg. keystoresecretprefix: bank1/credentials/keystore - keystoresecretprefix: bank1/credentials/keystore - #Provide the secretprefix - #Eg. certsecretprefix: bank1/certs - certsecretprefix: bank1/certs - # Number of retries to check contents from vault -  retries: - -healthcheck: - #Provide the interval in seconds you want to iterate till db to be ready - #Eg. readinesscheckinterval: 5 - readinesscheckinterval: 5 - #Provide the threshold till you want to check if specified db up and running - #Eg. readinessthreshold: 2 - readinessthreshold: 2 diff --git a/platforms/r3-corda/charts/corda-node/Chart.yaml b/platforms/r3-corda/charts/corda-node/Chart.yaml index 54ec97a8dc2..ff8e21005c9 100644 --- a/platforms/r3-corda/charts/corda-node/Chart.yaml +++ b/platforms/r3-corda/charts/corda-node/Chart.yaml @@ -5,7 +5,21 @@ ############################################################################################## apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Deploys the r3corda node." name: corda-node -version: 1.0.0 +description: "R3 Corda: Deploys the Corda Open-source node." +version: 1.0.1 +appVersion: "latest" +keywords: + - bevel + - corda + - hyperledger + - enterprise + - blockchain + - deployment + - accenture +home: https://hyperledger-bevel.readthedocs.io/en/latest/ +sources: + - https://github.com/hyperledger/bevel +maintainers: + - name: Hyperledger Bevel maintainers + email: bevel@lists.hyperledger.org diff --git a/platforms/r3-corda/charts/corda-node/README.md b/platforms/r3-corda/charts/corda-node/README.md index 18d3fb5b88b..13a217f073d 100644 --- a/platforms/r3-corda/charts/corda-node/README.md +++ b/platforms/r3-corda/charts/corda-node/README.md @@ -3,236 +3,166 @@ [//]: # (SPDX-License-Identifier: Apache-2.0) [//]: # (##############################################################################################) - -# Node Deployment - -- [Node Deployment Helm Chart](#Node-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - -## node Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-node) helps to delpoy the r3corda node. - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- Node's database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - -This chart has following structue: -``` - . - ├── node - │ ├── Chart.yaml - │ ├── templates - │ │ ├── deployment.yaml - │ │ ├── _helpers.tpl - │ │ ├── pvc.yaml - │ │ └── service.yaml - │ └── values.yaml +# corda-node + +This chart is a component of Hyperledger Bevel. The corda-node chart deploys a R3 Corda Opens-source node with different settings like notary or node. If enabled, the keys are then stored on the configured vault and stored as Kubernetes secrets. See [Bevel documentation](https://hyperledger-bevel.readthedocs.io/en/latest/) for details. + +## TL;DR + +```bash +helm repo add bevel https://hyperledger.github.io/bevel +helm install notary bevel/corda-node ``` -Type of files used: +## Prerequisitess -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `deployment.yaml`: This file is a configuration file for deployement in Kubernetes.It creates a deployment file with a specified number of replicas and defines various settings for the deployment.It includes an init container for initializing the retrieves secrets from Vault and checks if node registration is complete, and a main container for running the r3corda node.It also specifies volume mounts for storing certificates and data. -- `pvc.yaml` : A PersistentVolumeClaim (PVC) is a request for storage by a user. -- `service.yaml` : This file defines a Kubernetes Service with multiple ports for protocols and targets, and supports Ambassador proxy annotations for specific configurations when using the "ambassador" proxy provider. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the image, nodeconfig, credenatials, storage, service , vault, etc. -- `_helpers.tpl` : A template file used for defining custom labels and ports for the metrics in the Helm chart. +- Kubernetes 1.19+ +- Helm 3.2.0+ - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-node/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: +If Hashicorp Vault is used, then +- HashiCorp Vault Server 1.13.1+ -## Parameters ---- +> **Important**: Ensure the `corda-init` chart has been installed before installing this. Also check the dependent charts. -### Name +## Installing the Chart -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | bank1 | +To install the chart with the release name `notary`: -### Metadata +```bash +helm repo add bevel https://hyperledger.github.io/bevel +helm install notary bevel/corda-node +``` -| Name | Description | Default Value | -| ----------------| -----------------------------------------------------------------| ------------- | -| namespace | Provide the namespace for the Node Generator | default | -| labels | Provide any additional labels for the Node Generator | "" | +The command deploys the chart on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. -### Image +> **Tip**: List all releases using `helm list` -| Name | Description | Default Value | -| ------------------------ | --------------------------------------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| containerName | Provide the containerName of image | "" | -| imagePullSecret | Provide the image pull secret of image | regcred | -| gitContainerName | Provide the name of image for git clone container | "" | -| privateCertificate | Provide true or false if private certificate to be added | "true" | -| doormanCertAlias | Provide true or false if private certificate to be added | "" | -| networkmapCertAlias | Provide true or false if private certificate to be added | "" | - -### NodeConf - -| Name | Description | Default Value | -| ------------------------ | -------------------------------------------------------------------------------------- | --------------- | -| p2p | The host and port on which the node is available for protocol operations over ArtemisMQ | "" | -| ambassadorAddress | Specify ambassador host:port which will be advertised in addition to p2paddress | "" | -| legalName | Provide the legalName for node | "" | -| dbUrl | Provide the h2Url for node | "bank1h2" | -| dbPort | Provide the h2Port for node | "9101" | -| networkMapURL | Provide the nms for node | "" | -| doormanURL | Provide the doorman for node | "" | -| jarVersion | Provide the jar Version for corda jar and finanace jar | "3.3-corda" | -| devMode | Provide the devMode for corda node | "true" | -| useHTTPS | Provide the useHTTPS for corda node | "false" | -| env | Provide the enviroment variables to be set | "" | - -### credentials - -| Name | Description | Default Value | -| ----------------| ----------------------------------------------| ------------- | -| dataSourceUser | Provide the dataSourceUser for corda node | "" | -| rpcUser | Provide the rpcUser for corda node | bank1operations| - -### Volume - -| Name | Description | Default Value | -| -----------------| -----------------------| ------------- | -| baseDir | Base directory | /home/bevel | +## Uninstalling the Chart -### Resources +To uninstall/delete the `notary` deployment: -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| limits | Provide the limit memory for node | "1Gi" | -| requests | Provide the requests memory for node | "1Gi" | - -### storage - -| Name | Description | Default Value | -| --------------------- | -------------------------------------------------------- | ------------- | -| provisioner | Provide the provisioner for node | "" | -| name | Provide the name for node | bank1nodesc | -| memory | Provide the memory for node | "4Gi" | -| type | Provide the type for node | "gp2" | -| encrypted | Provide whether the EBS volume should be encrypted or not | "true" | -| annotations | Provide the annotation of the node | "" | - -### Service - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| type | Provide the type of service | NodePort | -| p2p port | Provide the tcp port for node | 10007 | -| p2p nodePort | Provide the p2p nodeport for node | 30007 | -| p2p targetPort | Provide the p2p targetPort for node | 30007 | -| rpc port | Provide the tpc port for node | 10008 | -| rpc targetPort | Provide the rpc targetport for node | 10003 | -| rpc nodePort | Provide the rpc nodePort for node | 30007 | -| rpcadmin port | Provide the rpcadmin port for node | 10108 | -| rpcadmin targetPort | Provide the rpcadmin targetport for node | 10005 | -| rpcadmin nodePort | Provide the rpcadmin nodePort for node | 30007 | - -### Vault - -| Name | Description | Default Value | -| ------------------------- | --------------------------------------------------------------------------| ------------------------- | -| address | Address/URL of the Vault server. | "" | -| role | Role used for authentication with Vault | vault-role | -| authpath | Authentication path for Vault | cordabank1 | -| serviceAccountName | Provide the already created service account name autheticated to vault | vault-auth-issuer | -| certSecretPrefix | Provide the vault path where the certificates are stored | bank1/certs | -| dbsecretprefix | Provide the secretprefix | bank1/credentials/database | -| rpcusersecretprefix | Provide the secretprefix | bank1/credentials/rpcusers | -| keystoresecretprefix | Provide the secretprefix | bank1/credentials/keystore | -| cordappsreposecretprefix | Provide the secretprefix | bank1/credentials/cordapps | - -### cordapps - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| getcordapps | Provide if you want to provide jars in cordapps | "" | -| repository | Provide the repository of cordapps | "" | -| jars url | Provide url to download the jar using wget cmd | "" | - -### Healthcheck - -| Name | Description | Default Value | -| ----------------------------| ------------------------------------------------------------------------------| ------------- | -| readinesscheckinterval | Provide the interval in seconds you want to iterate till db to be ready | 5 | -| readinessthreshold | Provide the threshold till you want to check if specified db up and running | 2 | - -### ambassador - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | -------------------------- | -| component_name | Provides component name | node | -| external_url_suffix | Provides the suffix to be used in external URL | org1.blockchaincloudpoc.com | -| p2p_ambassador | Provide the p2p port for ambassador | 10007 | - - - - -## Deployment ---- - -To deploy the node Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-node/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade,verify, delete the chart: - -To install the chart: ```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-node +helm uninstall notary ``` -To upgrade the chart: -```bash -helm upgrade ./corda-node -``` +The command removes all the Kubernetes components associated with the chart and deletes the release. -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. +## Parameters -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. +### Global parameters +These parameters are refered to as same in each parent or child chart +| Name | Description | Default Value | +|--------|---------|-------------| +|`global.serviceAccountName` | The serviceaccount name that will be used for Vault Auth management| `vault-auth` | +| `global.cluster.provider` | Kubernetes cluster provider like AWS EKS or minikube. Currently ony `aws` and `minikube` is tested | `aws` | +| `global.cluster.cloudNativeServices` | only `false` is implemented, `true` to use Cloud Native Services (SecretsManager and IAM for AWS; KeyVault & Managed Identities for Azure) is for future | `false` | +| `global.vault.type` | Type of Vault to support other providers. Currently, only `hashicorp` is supported. | `hashicorp` | +| `global.vault.role` | Role used for authentication with Vault | `vault-role` | +| `global.vault.address`| URL of the Vault server. | `""` | +| `global.vault.authPath` | Authentication path for Vault | `supplychain` | +| `global.vault.secretEngine` | The value for vault secret engine name | `secretsv2` | +| `global.vault.secretPrefix` | The value for vault secret prefix which must start with `data/` | `data/supplychain` | +| `global.proxy.provider` | The proxy or Ingress provider. Can be `none` or `ambassador` | `ambassador` | +| `global.proxy.externalUrlSuffix` | The External URL suffix at which the Corda P2P service will be available | `test.blockchaincloudpoc.com` | +| `global.proxy.p2p` | The external port at which the Corda P2P service will be available. This port must be unique for a single cluster and enabled on Ambassador. | `15010` | + +### Storage + +| Name | Description | Default Value | +|--------|---------|-------------| +| `storage.size` | Size of the Volume needed for Corda node | `1Gi` | +| `storage.dbSize` | Size of the Volume needed for H2 Database node | `2Gi` | +| `storage.allowedTopologies.enabled` | Check [bevel-storageclass](../../../shared/charts/bevel-storageclass/README.md) for details | `false` | + +### TLS +This is where you can override the values for the [corda-certs-gen subchart](../corda-certs-gen/README.md). + +| Name | Description | Default Value | +|--------|---------|-------------| +| `tls.enabled` | Flag to enable TLS and certificate generation | `true` | +### Image +| Name | Description | Default Value | +| -------------| ---------- | --------- | +| `image.pullSecret` | Provide the docker secret name in the namespace | `""` | +| `image.pullPolicy` | Pull policy to be used for the Docker images | `IfNotPresent` | +| `image.h2` | H2 DB image repository and tag | `ghcr.io/hyperledger/h2:2018`| +| `image.corda.repository` | Corda Image repository | `ghcr.io/hyperledger/bevel-corda`| +| `image.corda.tag` | Corda image tag as per version of Corda | `4.9`| +| `image.initContainer` | Image repository and tag for alpine container | `ghcr.io/hyperledger/bevel-alpine:latest` | +| `image.hooks.repository` | Corda hooks image repository | `ghcr.io/hyperledger/bevel-build` | +| `image.hooks.tag` | Corda hooks image tag | `jdk8-stable` | + + +### Corda nodeConf + +This contains all the parameters for the Corda node. Please read [R3 Corda documentation](https://docs.r3.com/en/platform/corda/4.9/community/corda-configuration-fields.html) for detailed explanation of each parameter. + +| Name | Description | Default Value | +| ----------------| ----------- | ------------- | +| `nodeConf.defaultKeystorePassword` | Default Keystore password, do not change this | `cordacadevpass` | +| `nodeConf.defaultTruststorePassword` | Default Truststore password, do not change this | `trustpass` | +| `nodeConf.keystorePassword` | New keystore password which will be set after initialisation | `newpass` | +| `nodeConf.truststorePassword` | New truststore password which will be set after initialisation | `newtrustpass` | +| `nodeConf.sslkeyStorePassword` | SSL keystore password which will be set after initialisation | `sslpass` | +| `nodeConf.ssltrustStorePassword` | SSL truststore password which will be set after initialisation | `ssltrustpass` | +| `nodeConf.removeKeysOnDelete` | Flag to delete the keys when the release is uninstalled | `true` | +| `nodeConf.rpcUser` | Array of RPC Users that you want to create at initialization | `- name: nodeoperations`
`password: nodeoperationsAdmin`
`permissions: [ALL]` | +| `nodeConf.p2pPort` | P2P Port for Corda Node | `10002` | +| `nodeConf.rpcPort` | RPC Port for Corda Node | `10003` | +| `nodeConf.rpcadminPort` | RPC Admin Port for Corda Node | `10005` | +| `nodeConf.rpcSettings.useSsl` | Use SSL for RPC | `false` | +| `nodeConf.rpcSettings.standAloneBroker` | Standalone Broker setting for RPC | `false` | +| `nodeConf.rpcSettings.address` | Address for RPC Service | `"0.0.0.0:10003"` | +| `nodeConf.rpcSettings.adminAddress` | Address for RPC Admin Service | `"0.0.0.0:10005"` | +| `nodeConf.rpcSettings.ssl.certificatesDirectory` | SSL Certificate directory when useSSl is `true` | `na-ssl-false` | +| `nodeConf.rpcSettings.ssl.sslKeystorePath` | SSL Keystore path when useSSl is `true` | `na-ssl-false` | +| `nodeConf.rpcSettings.ssl.trustStoreFilePath` | SSL Truststore path when useSSl is `true` | `na-ssl-false` | +| `nodeConf.legalName` | X.509 Subject for Corda Node Identity. Must be unique for different nodes in a network | `"O=Notary,OU=Notary,L=London,C=GB"` | +| `nodeConf.messagingServerAddress` | Messaging Server Address | `""` | +| `nodeConf.jvmArgs` | Additional JVM Args | `""` | +| `nodeConf.systemProperties` | Additional System properties | `""` | +| `nodeConf.sshd.port` | SSHD Admin port | `""` | +| `nodeConf.exportJMXTo` | JMX Reporter Address | `""` | +| `nodeConf.transactionCacheSizeMegaBytes` | Specify how much memory should be used for caching of ledger transactions in memory (in MB) | `8` | +| `nodeConf.attachmentContentCacheSizeMegaBytes` | Specify how much memory should be used to cache attachment contents in memory (in MB) | `10` | +| `nodeConf.notary.enabled` | Enable this Corda node as a Notary | `true` | +| `nodeConf.notary.validating` | Flag to setup validating or non-validating notary | `true` | +| `nodeConf.notary.serviceLegalName` | Specify the legal name of the notary cluster or node | `"O=Notary Service,OU=Notary,L=London,C=GB"` | +| `nodeConf.detectPublicIp` | Flag to detect public IP | `false` | +| `nodeConf.database.exportHibernateJMXStatistics` | Whether to export Hibernate JMX statistics | `false` | +| `nodeConf.dbPort` | Database port | `9101` | +| `nodeConf.dataSourceUser` | Database username | `sa` | +| `nodeConf.dataSourcePassword` | Database user password | `admin` | +| `nodeConf.dataSourceClassName` | JDBC Data Source class name | `"org.h2.jdbcx.JdbcDataSource"` | +| `nodeConf.jarPath` | Additional Jar path| `"/data/corda-workspace/h2/bin"` | +| `nodeConf.networkMapURL` | Root address of the network map service. | `https://supplychain-nms.supplychain-ns` | +| `nodeConf.doormanURL` | Root address of the doorman service | `https://supplychain-doorman.supplychain-ns` | +| `nodeConf.devMode` | Flag to set the node to run in development mode. | `false` | +| `nodeConf.javaOptions` | Additional JAVA_OPTIONS for Corda | `"-Xmx512m"` | + +### CordApps + +| Name | Description | Default Value | +|--------|---------|-------------| +| `cordApps.getCordApps` | Flag to download CordApps from urls provided | `false` | +| `cordApps.jars` | List of `url`s from where the CordApps will be downloaded | `- url: ""` | + +### Resources - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [node Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-node), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). +| Name | Description | Default Value | +|--------|---------|-------------| +| `resources.db.memLimit` | Kubernetes Memory limit for H2 Database pod | `1G` | +| `resources.db.memRequest` | Kubernetes Memory request for H2 Database pod | `512M` | +| `resources.node.memLimit` | Kubernetes Memory limit for Corda pod | `2G` | +| `resources.node.memRequest` | Kubernetes Memory request for Corda pod | `1G` | - ## License This chart is licensed under the Apache v2.0 license. -Copyright © 2023 Accenture +Copyright © 2024 Accenture ### Attribution diff --git a/platforms/r3-corda/charts/corda-node/requirements.yaml b/platforms/r3-corda/charts/corda-node/requirements.yaml new file mode 100644 index 00000000000..35059a61d0d --- /dev/null +++ b/platforms/r3-corda/charts/corda-node/requirements.yaml @@ -0,0 +1,14 @@ +dependencies: + - name: bevel-storageclass + alias: storage + repository: "file://../../../shared/charts/bevel-storageclass" + tags: + - storage + version: ~1.0.0 + - name: corda-certs-gen + alias: tls + repository: "file://../corda-certs-gen" + tags: + - bevel + version: ~1.0.0 + condition: tls.enabled diff --git a/platforms/r3-corda/charts/corda-node/templates/_helpers.tpl b/platforms/r3-corda/charts/corda-node/templates/_helpers.tpl index 592feeaa311..e05e77e8efa 100644 --- a/platforms/r3-corda/charts/corda-node/templates/_helpers.tpl +++ b/platforms/r3-corda/charts/corda-node/templates/_helpers.tpl @@ -1,10 +1,44 @@ -{{- define "labels.custom" }} - {{ range $key, $val := $.Values.metadata.labels }} - {{ $key }}: {{ $val }} - {{ end }} -{{- end }} - -{{- define "application.labels" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} \ No newline at end of file +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "corda-node.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 "corda-node.fullname" -}} +{{- $name := default .Chart.Name -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" $name .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "corda-node.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "corda-node.doormanDomain" -}} +{{- $url := .Values.nodeConf.doormanURL -}} +{{- $urlParts := splitList "//" $url -}} +{{- $protocol := index $urlParts 0 -}} +{{- $domainParts := splitList "/" (index $urlParts 1) -}} +{{- index $domainParts 0 -}} +{{- end -}} + +{{- define "corda-node.nmsDomain" -}} +{{- $url := .Values.nodeConf.networkMapURL -}} +{{- $urlParts := splitList "//" $url -}} +{{- $protocol := index $urlParts 0 -}} +{{- $domainParts := splitList "/" (index $urlParts 1) -}} +{{- index $domainParts 0 -}} +{{- end -}} diff --git a/platforms/r3-corda/charts/corda-node/templates/deployment.yaml b/platforms/r3-corda/charts/corda-node/templates/deployment.yaml deleted file mode 100644 index ed6aa47b0a6..00000000000 --- a/platforms/r3-corda/charts/corda-node/templates/deployment.yaml +++ /dev/null @@ -1,539 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.nodeName }} - {{- if .Values.deployment.annotations }} - annotations: -{{ toYaml .Values.deployment.annotations | indent 8 }} - {{- end }} - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - {{- include "labels.custom" . | nindent 2 }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - strategy: - type: Recreate - rollingUpdate: null - template: - metadata: - labels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: corda-node - image: {{ .Values.image.containerName }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - - # Setting up enviroment variables required for corda jar - {{- range $.Values.nodeConf.env }} - export {{ .name }}="{{ .value }}" - {{- end }} - - # import self signed tls certificate of doorman and networkmap, since java only trusts certificate signed by well known CA - {{- if .Values.image.privateCertificate }} - yes | keytool -importcert -file {{ $.Values.volume.baseDir }}/certificates/networkmap/networkmap.crt -storepass changeit -alias {{ $.Values.image.networkmapCertAlias }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - yes | keytool -importcert -file {{ $.Values.volume.baseDir }}/certificates/doorman/doorman.crt -storepass changeit -alias {{ $.Values.image.doormanCertAlias }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - {{- end }} - - # to clean network-parameters on every restart - rm -rf ${BASE_DIR}/network-parameters - - # Run schema migration scripts for corDApps - java -Djavax.net.ssl.keyStore=${BASE_DIR}/certificates/sslkeystore.jks -Djavax.net.ssl.keyStorePassword=newpass $JAVA_OPTIONS -jar ${CORDA_HOME}/corda.jar run-migration-scripts --core-schemas --app-schemas --base-directory=${BASE_DIR} - # command to run corda jar, we are setting javax.net.ssl.keyStore as ${BASE_DIR}/certificates/sslkeystore.jks since keystore gets reset when using h2 ssl - java -Djavax.net.ssl.keyStore=${BASE_DIR}/certificates/sslkeystore.jks -Djavax.net.ssl.keyStorePassword=newpass $JAVA_OPTIONS -jar ${CORDA_HOME}/corda.jar --base-directory=${BASE_DIR} 2>&1 - resources: - limits: - memory: {{ .Values.resources.limits }} - requests: - memory: {{ .Values.resources.requests }} - ports: - - containerPort: {{ .Values.service.p2p.targetPort }} - name: p2p - - containerPort: {{ .Values.service.rpc.targetPort }} - name: rpc - - containerPort: {{ .Values.service.rpcadmin.targetPort }} - name: rpcadmin - volumeMounts: - - name: node-volume - mountPath: "{{ $.Values.volume.baseDir }}" - readOnly: false - - name: certificates - mountPath: "{{ $.Values.volume.baseDir }}/certificates" - readOnly: false - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}/node.conf" - subPath: "node.conf" - readOnly: false - livenessProbe: - tcpSocket: - port: {{ .Values.service.p2p.targetPort }} - initialDelaySeconds: 65 - periodSeconds: 30 - - name: corda-logs - image: {{ .Values.image.initContainerName }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - {{- range $.Values.nodeConf.env }} - export {{ .name }}="{{ .value }}" - {{- end }} - COUNTER=0 - if [ -e ${BASE_DIR}/logs/node-{{ .Values.nodeName }}.log ] - then - clear - tail -f ${BASE_DIR}/logs/node-{{ .Values.nodeName }}.log - else - echo "waiting for corda to generate log, sleeping for 10s" - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - fi - volumeMounts: - - name: node-volume - mountPath: "{{ $.Values.volume.baseDir }}" - readOnly: false - initContainers: - - name: init-checkregistration - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: CERTS_SECRET_PREFIX - value: {{ .Values.vault.certsecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - # setting up env to get secrets from vault - echo "Getting secrets from Vault Server" - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - - COUNTER=1 - while [ "$COUNTER" -lt {{ $.Values.healthcheck.readinessthreshold }} ] - do - # get truststore from vault to see if registration is done or not - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore | jq -r 'if .errors then . else . end') - if echo ${LOOKUP_SECRET_RESPONSE} | grep "errors" - then - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - break - fi - COUNTER=`expr "$COUNTER" + 1` - done - - if [ "$COUNTER" -ge {{ $.Values.healthcheck.readinessthreshold }} ] - then - # printing number of trial done before giving up - echo "$COUNTER" - echo "Node registration might not have been done." - exit 1 - fi - echo "Done" - - name: init-nodeconf - image : {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: KS_SECRET_PREFIX - value: {{ .Values.vault.keystoresecretprefix }} - - name: DB_SECRET_PREFIX - value: {{ .Values.vault.dbsecretprefix }} - - name: RPCUSER_SECRET_PREFIX - value: {{ .Values.vault.rpcusersecretprefix }} - command: ["/bin/sh","-c"] - args: - - |- - #!/bin/bash - # delete previously created node.conf, and create a new node.conf - rm -f ${BASE_DIR}/node.conf; - touch ${BASE_DIR}/node.conf; - - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - - # save keyStorePassword & trustStorePassword from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - CONF_KEYSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["keyStorePassword"]') - CONF_TRUSTSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["trustStorePassword"]') - - # save dataSourceUserPassword from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - CONF_DATASOURCEPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["{{ .Values.credentials.dataSourceUser }}"]') - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${RPCUSER_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - - #For more information for node.Conf fields please refer to: https://docs.corda.r3.com/releases/4.0/corda-configuration-file.html - cat << EOF > ${BASE_DIR}/node.conf - p2pAddress : "{{ .Values.nodeConf.p2p.url }}:{{ .Values.nodeConf.p2p.port }}" - myLegalName : "{{ .Values.nodeConf.legalName }}" - keyStorePassword : "${CONF_KEYSTOREPASSWORD}" - trustStorePassword : "${CONF_TRUSTSTOREPASSWORD}" - transactionCacheSizeMegaBytes : {{ .Values.nodeConf.transactionCacheSizeMegaBytes }} - attachmentContentCacheSizeMegaBytes : {{ .Values.nodeConf.attachmentContentCacheSizeMegaBytes }} - detectPublicIp = {{ .Values.nodeConf.detectPublicIp }} - additionalP2PAddresses = ["{{ .Values.nodeConf.ambassadorAddress }}"] - devMode : {{ .Values.nodeConf.devMode }} - dataSourceProperties = { - dataSourceClassName = "{{ .Values.nodeConf.dataSourceClassName }}" - dataSource.url = "{{ .Values.nodeConf.dataSourceUrl }}" - dataSource.user = {{ .Values.credentials.dataSourceUser }} - dataSource.password = "${CONF_DATASOURCEPASSWORD}" - } - database = { - exportHibernateJMXStatistics = {{ .Values.nodeConf.database.exportHibernateJMXStatistics }} - } - jarDirs = ["{{ .Values.nodeConf.jarPath }}"] - EOF - if [ -z "{{ .Values.nodeConf.compatibilityZoneURL }}" ] - then - echo 'networkServices = { - doormanURL = "{{ .Values.nodeConf.doormanURL }}" - networkMapURL = "{{ .Values.nodeConf.networkMapURL }}" - }' >> ${BASE_DIR}/node.conf - else - echo 'compatibilityZoneURL : "{{ .Values.nodeConf.compatibilityZoneURL }}"' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.jvmArgs }}" ] - then - echo 'jvmArgs is not configured' - else - echo 'jvmArgs = "{{ .Values.nodeConf.jvmArgs }}" ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.sshd.port }}" ] - then - echo 'sshd port is not configured' - else - echo 'sshd { port = {{ .Values.nodeConf.sshd.port }} } ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.systemProperties }}" ] - then - echo 'systemProperties is not configured' - else - echo 'systemProperties = {{ .Values.nodeConf.systemProperties }} ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.exportJMXTo }}" ] - then - echo 'exportJMXTo is not configured' - else - echo 'exportJMXTo = {{ .Values.nodeConf.exportJMXTo }} ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.messagingServerAddress }}" ] - then - echo 'The address of the ArtemisMQ broker instance is not configured' - else - echo 'messagingServerAddress : "{{ .Values.nodeConf.messagingServerAddress }}" ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.credentials.rpcUser }}" ] - then - echo 'rpc useer is not configured' - else - echo 'rpcUsers : [' >> ${BASE_DIR}/node.conf - {{- range $.Values.credentials.rpcUser }} - echo '{ username={{ .name }} ,permissions={{ .permissions }}, ' >> ${BASE_DIR}/node.conf - echo " password=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["{{ .name }}"]') }" >> ${BASE_DIR}/node.conf - {{- end }} - echo ']' >> ${BASE_DIR}/node.conf - fi - - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - if [ "{{ .Values.nodeConf.rpcSettings.useSsl }}" == true ] - then - echo "rpcSettings { - standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} - address = "{{ .Values.nodeConf.rpcSettings.address }}" - adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" - useSsl = {{ .Values.nodeConf.rpcSettings.useSsl }} - ssl = { - keyStorePassword = $(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["sslkeyStorePassword"]') - trustStorePassword = $(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["ssltrustStorePassword"]') - certificatesDirectory = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }} - sslKeystore = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.sslKeystoreFileName }} - trustStoreFile = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.trustStoreFileName }} - } - }" >> ${BASE_DIR}/node.conf - else - echo 'rpcSettings { - standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} - address = "{{ .Values.nodeConf.rpcSettings.address }}" - adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" - }' >> ${BASE_DIR}/node.conf - fi - echo "node.conf created in ${BASE_DIR}" - volumeMounts: - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}" - - name: init-certificates - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: CERTS_SECRET_PREFIX - value: {{ .Values.vault.certsecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - # setting up env to get secrets from vault - echo "Getting secrets from Vault Server" - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - - OUTPUT_PATH=${BASE_DIR} - - # get nodekeystore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/nodekeystore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/nodekeystore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TLS_NODEKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["nodekeystore.jks"]') - echo "${TLS_NODEKEYSTORE}" | base64 -d > ${OUTPUT_PATH}/nodekeystore.jks - - # get sslkeystore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/sslkeystore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/sslkeystore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TLS_SSLKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["sslkeystore.jks"]') - echo "${TLS_SSLKEYSTORE}" | base64 -d > ${OUTPUT_PATH}/sslkeystore.jks - - # get truststore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/truststore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TLS_TRUSTSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["truststore.jks"]') - echo "${TLS_TRUSTSTORE}" | base64 -d > ${OUTPUT_PATH}/truststore.jks - - # get network-map-truststore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/networkmaptruststore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/networkmaptruststore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TLS_NMS=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["network-map-truststore"]') - echo "${TLS_NMS}" | base64 -d > ${OUTPUT_PATH}/network-map-truststore.jks - - # when using doorman and networkmap in TLS: true, and using private certificate then download certificate - if [ "{{ .Values.image.privateCertificate }}" == true ] - then - mkdir -p ${OUTPUT_PATH}/networkmap - mkdir -p ${OUTPUT_PATH}/doorman - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/networkmap | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/networkmap" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - NETWORKMAP_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["networkmap.crt"]') - echo "${NETWORKMAP_CRT}" | base64 -d > ${OUTPUT_PATH}/networkmap/networkmap.crt - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/doorman | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/doorman" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - DOORMAN_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["doorman.crt"]') - echo "${DOORMAN_CRT}" | base64 -d > ${OUTPUT_PATH}/doorman/doorman.crt - fi - - # when using custom sslKeystore while setting in node.conf - if [ "{{ .Values.nodeConf.rpcSettings.useSsl }}" == true ] - then - mkdir -p ${OUTPUT_PATH}/${SSL_CERT_PATH} - chmod -R ${OUTPUT_PATH}/${SSL_CERT_PATH} - SSL_CERT_PATH={{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }} - SSL_KEYSTORE_FILE_NAME_KEY={{ .Values.nodeConf.rpcSettings.ssl.sslKeystoreFileName }} - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/${SSL_KEYSTORE_FILE_NAME_KEY} | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/${SSL_KEYSTORE_FILE_NAME_KEY}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - SSLKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["SSL_KEYSTORE_FILE_NAME_KEY"]') - echo "${SSLKEYSTORE}" | base64 -d > ${OUTPUT_PATH}/${SSL_CERT_PATH}/${SSL_KEYSTORE_FILE_NAME_KEY} - TRUSTKEYSTORE_FILE_NAME_KEY={{ .Values.nodeConf.rpcSettings.ssl.sslKeystoreFileName }} - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/${TRUSTKEYSTORE_FILE_NAME_KEY} | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/${TRUSTKEYSTORE_FILE_NAME_KEY}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TRUSTSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["TRUSTKEYSTORE_FILE_NAME_KEY"]') - echo "${TRUSTSTORE}" | base64 -d > ${OUTPUT_PATH}/${SSL_CERT_PATH}/${TRUSTKEYSTORE_FILE_NAME_KEY} - else - echo "" - fi - - echo "Done" - volumeMounts: - - name: certificates - mountPath: {{ $.Values.volume.baseDir }} - - name: init-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - # perform health check if db is up and running before starting corda node - while [ "$COUNTER" -le {{ $.Values.healthcheck.readinessthreshold }} ] - do - DB_NODE={{ .Values.nodeConf.dbUrl }}:{{ .Values.nodeConf.dbPort }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.healthcheck.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - if [ "$COUNTER" -gt {{ $.Values.healthcheck.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - - name: init-cordapps - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - env: - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: SECRET_PREFIX - value: {{ $.Values.vault.cordappsreposecretprefix }} - args: - - |- - # crearting cordapps dir in volume to keep jars - mkdir -p {{ .Values.volume.baseDir }}/cordapps - {{- if .Values.cordapps.getcordapps }} - mkdir -p /tmp/downloaded-jars - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - - # Save CorDapps repository login password from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${SECRET_PREFIX} | jq -r 'if .errors then . else . end') - REPO_USER_PASS=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["repo_password"]') - REPO_USER=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["repo_username"]') - - # Downloading official corda provided jars using curl - {{- range .Values.cordapps.jars }} - cd /tmp/downloaded-jars && curl -u $REPO_USER:$REPO_USER_PASS -O -L {{ .url }} - {{- end }} - cp -ar /tmp/downloaded-jars/* {{ $.Values.volume.baseDir }}/cordapps - {{- end }} - volumeMounts: - - name: node-volume - mountPath: "{{ $.Values.volume.baseDir }}" - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: node-volume - persistentVolumeClaim: - claimName: {{ .Values.pvc.name }} - - name: certificates - emptyDir: - medium: Memory - - name: nodeconf - emptyDir: - medium: Memory - - name: nodeprops - emptyDir: - medium: Memory diff --git a/platforms/r3-corda/charts/corda-node/templates/hooks-pre-delete.yaml b/platforms/r3-corda/charts/corda-node/templates/hooks-pre-delete.yaml new file mode 100644 index 00000000000..2f987b6a44b --- /dev/null +++ b/platforms/r3-corda/charts/corda-node/templates/hooks-pre-delete.yaml @@ -0,0 +1,71 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "corda-node.fullname" . }}-pre-delete-hook + namespace: {{ .Release.Namespace }} + annotations: + helm.sh/hook: pre-delete + helm.sh/hook-weight: "0" + helm.sh/hook-delete-policy: "hook-succeeded" + labels: + app.kubernetes.io/name: pre-delete-hook + app.kubernetes.io/component: cleanup + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm +spec: + backoffLimit: 3 + completions: 1 + template: + metadata: + labels: + app.kubernetes.io/name: pre-delete-hook + app.kubernetes.io/component: cleanup + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm + spec: + serviceAccountName: {{ .Values.global.serviceAccountName }} + restartPolicy: "Never" + containers: + - name: {{ template "corda-node.fullname" . }}-cleanup + image: "{{ .Values.image.hooks.repository }}:{{ .Values.image.hooks.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /bin/bash + - -c + args: + - | + + echo "{{ template "corda-node.fullname" . }} pre-delete-hook ..." + +{{- if and (ne .Values.global.cluster.provider "minikube") (.Values.global.cluster.cloudNativeServices) }} + # placeholder for cloudNative deleteSecret function +{{- else }} + + function deleteSecret { + key=$1 + kubectl delete secret ${key} --namespace {{ .Release.Namespace }} + } + +{{- end }} + +{{- if .Values.nodeConf.removeKeysOnDelete }} + +{{- if and (ne .Values.global.cluster.provider "minikube") (.Values.global.cluster.cloudNativeServices) }} + deleteSecret {{.Release.Name }}-nmskeystore + deleteSecret {{.Release.Name }}-doormankeystore + deleteSecret {{.Release.Name }}-rootcakeystore + deleteSecret {{.Release.Name }}-rootcacert + deleteSecret {{.Release.Name }}-rootcakey + deleteSecret {{.Release.Name }}-dbcert + deleteSecret {{.Release.Name }}-dbcacert +{{- else }} + deleteSecret {{.Release.Name }}-certs +{{- end }} + +{{- end }} + echo "Completed" diff --git a/platforms/r3-corda/charts/corda-node/templates/hooks-pre-install.yaml b/platforms/r3-corda/charts/corda-node/templates/hooks-pre-install.yaml new file mode 100644 index 00000000000..4192dcb5642 --- /dev/null +++ b/platforms/r3-corda/charts/corda-node/templates/hooks-pre-install.yaml @@ -0,0 +1,165 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "corda-node.fullname" . }}-pre-install-hook + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-weight": "0" + "helm.sh/hook-delete-policy": "before-hook-creation" + labels: + app.kubernetes.io/name: pre-install-hook + app.kubernetes.io/component: certgen + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm +spec: + backoffLimit: 1 + completions: 1 + template: + metadata: + labels: + app.kubernetes.io/name: pre-install-hook + app.kubernetes.io/component: certgen + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm + spec: + serviceAccountName: {{ .Values.global.serviceAccountName }} + restartPolicy: "OnFailure" + containers: + - name: corda-certgen + image: {{ .Values.image.hooks.repository }}:{{ .Values.image.hooks.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + runAsUser: 0 + volumeMounts: + - name: generated-config + mountPath: /home + - name: scripts-volume + mountPath: /scripts/bevel-vault.sh + subPath: bevel-vault.sh + {{- if (eq .Values.global.vault.type "hashicorp") }} + env: + - name: VAULT_ADDR + value: "{{ .Values.global.vault.address }}" + - name: VAULT_SECRET_ENGINE + value: "{{ .Values.global.vault.secretEngine }}" + - name: VAULT_SECRET_PREFIX + value: "{{ .Values.global.vault.secretPrefix }}" + - name: KUBERNETES_AUTH_PATH + value: "{{ .Values.global.vault.authPath }}" + - name: VAULT_APP_ROLE + value: "{{ .Values.global.vault.role }}" + - name: VAULT_TYPE + value: "{{ .Values.global.vault.type }}" + {{- end }} + command: + - /bin/bash + - -c + args: + - | +{{- if (eq .Values.global.vault.type "hashicorp") }} + . /scripts/bevel-vault.sh + echo "Getting vault Token..." + vaultBevelFunc "init" + #Read if secret exists in Vault + vaultBevelFunc 'readJson' "${VAULT_SECRET_ENGINE}/${VAULT_SECRET_PREFIX}/{{ .Release.Name }}-certs" + function safeWriteSecret { + key=$1 + fpath=$2 + if [ "$SECRETS_AVAILABLE" == "yes" ] + then + # Get secret from Vault and create the k8s secret if it does not exist + kubectl get secret ${key}-certs --namespace {{ .Release.Namespace }} -o json > /dev/null 2>&1 + if [ $? -ne 0 ]; then + NMS_STORE=$(echo ${VAULT_SECRET} | jq -r '.["nmstruststore_base64"]') + NODE_CERTS=$(echo ${VAULT_SECRET} | jq -r '.["nodecert_base64"]') + NODE_KEY=$(echo ${VAULT_SECRET} | jq -r '.["nodekey_base64"]') + NODE_STORE=$(echo ${VAULT_SECRET} | jq -r '.["nodekeystore_base64"]') + echo $NMS_STORE | base64 -d > /tmp/nmstruststore.jks + echo $NODE_STORE | base64 -d > /tmp/nodekeystore.jks + echo $NODE_CERTS > /tmp/node.cer + echo $NODE_KEY > /tmp/node.key + kubectl create secret generic ${key}-certs --namespace {{ .Release.Namespace }} \ + --from-file=network-map-truststore.jks=/tmp/nmstruststore.jks --from-file=nodekeystore.jks=/tmp/nodekeystore.jks \ + --from-file=node.crt=/tmp/node.cer --from-file=node.key=/tmp/node.key + fi + else + # Save keystores/truststores to Vault + # Use -w0 to get single line base64 -w0 + NMS_STORE=$(cat ${fpath}/network-map-truststore.jks | base64 -w0) + NODE_STORE=$(cat ${fpath}/nodekeystore.jks | base64 -w0) + NODE_CERTS=$(cat ${fpath}/node.cer | base64 -w0) + NODE_KEY=$(cat ${fpath}/node.key | base64 -w0) + # create a JSON file for the data related to node crypto + echo " + { + \"data\": + { + \"nmstruststore_base64\": \"${NMS_STORE}\", + \"nodekeystore_base64\": \"${NODE_STORE}\", + \"nodecert_base64\": \"${NODE_CERTS}\", + \"nodekey_base64\": \"${NODE_KEY}\" + } + }" > payload.json + vaultBevelFunc 'write' "${VAULT_SECRET_ENGINE}/${VAULT_SECRET_PREFIX}/${key}-certs" 'payload.json' + rm payload.json + # Also create the k8s secret + kubectl create secret generic ${key}-certs --namespace {{ .Release.Namespace }} \ + --from-file=network-map-truststore.jks=${fpath}/network-map-truststore.jks --from-file=nodekeystore.jks=${fpath}/nodekeystore.jks \ + --from-literal=node.crt=${NODE_CERTS} --from-literal=node.key=${NODE_KEY} + fi + } +{{- else }} + function safeWriteSecret { + key=$1 + fpath=$2 + kubectl get secret ${key}-certs --namespace {{ .Release.Namespace }} -o json > /dev/null 2>&1 + if [ $? -ne 0 ]; then + kubectl create secret generic ${key}-certs --namespace {{ .Release.Namespace }} \ + --from-file=network-map-truststore.jks=${fpath}/network-map-truststore.jks --from-file=nodekeystore.jks=${fpath}/nodekeystore.jks \ + --from-file=node.crt=<(base64 -w0 ${fpath}/node.cer) --from-file=node.key=<(base64 -w0 ${fpath}/node.key) + fi + } +{{- end }} + if [ "$SECRETS_AVAILABLE" == "yes" ] + then + echo "Certificates found for {{ .Release.Name }} ..." + else + echo "Creating certificates for {{ .Release.Name }} ..." + # Generate node certs + CA_PATH=/home/certificates/node + + mkdir -p ${CA_PATH} + DEFAULT_KEYSTORE_PASS={{ .Values.nodeConf.defaultKeystorePassword }} + + cd ${CA_PATH} + openssl genrsa -out node.key 3072 + openssl req -new -x509 -key node.key -out node.cer -days 365 -subj '/{{ .Values.nodeConf.legalName | replace "," "/" }}' + openssl dgst -sha256 -sign node.key node.cer | base64 | cat node.cer + openssl pkcs12 -export -in node.cer -inkey node.key -out testkeystore.p12 -passin pass:${DEFAULT_KEYSTORE_PASS} -passout pass:${DEFAULT_KEYSTORE_PASS} + eval "yes | keytool -importkeystore -srckeystore testkeystore.p12 -srcstoretype pkcs12 -srcstorepass ${DEFAULT_KEYSTORE_PASS} -destkeystore nodekeystore.jks -deststorepass ${DEFAULT_KEYSTORE_PASS} -deststoretype JKS" + # Get networkmap-truststore + wget --no-check-certificate {{ .Values.nodeConf.networkMapURL }}/network-map/truststore -O network-map-truststore.jks + fi; + echo "Creating {{ .Release.Name }}-certs secrets in k8s ..." +{{- if and (ne .Values.global.cluster.provider "minikube") (.Values.global.cluster.cloudNativeServices) }} + safeWriteSecret {{ .Release.Name }}-network-map-truststore.jks $CA_PATH/network-map-truststore.jks + safeWriteSecret {{ .Release.Name }}-cert $CA_PATH/node.cer + safeWriteSecret {{ .Release.Name }}-key $CA_PATH/node.key + safeWriteSecret {{ .Release.Name }}-nodekeystore.jks $CA_PATH/nodekeystore.jks +{{- else }} + safeWriteSecret {{ .Release.Name }} ${CA_PATH} +{{- end }} + echo "Completed ..." + volumes: + - name: generated-config + emptyDir: {} + - name: scripts-volume + configMap: + name: bevel-vault-script + defaultMode: 0777 diff --git a/platforms/r3-corda/charts/corda-node/templates/pvc.yaml b/platforms/r3-corda/charts/corda-node/templates/pvc.yaml deleted file mode 100644 index 95f123ad10a..00000000000 --- a/platforms/r3-corda/charts/corda-node/templates/pvc.yaml +++ /dev/null @@ -1,29 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.pvc.name }} - {{- if .Values.pvc.annotations }} - annotations: -{{ toYaml .Values.pvc.annotations | indent 8 }} - {{- end }} - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.pvc.name }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - {{- include "labels.custom" . | nindent 2 }} -spec: - storageClassName: {{ .Values.pvc.storageClassName }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.pvc.memory }} \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-node/templates/service.yaml b/platforms/r3-corda/charts/corda-node/templates/service.yaml index 43341c2dd23..5bde0e4d1d8 100644 --- a/platforms/r3-corda/charts/corda-node/templates/service.yaml +++ b/platforms/r3-corda/charts/corda-node/templates/service.yaml @@ -3,89 +3,113 @@ # # SPDX-License-Identifier: Apache-2.0 ############################################################################################## - apiVersion: v1 kind: Service metadata: - name: {{ .Values.service.name }} - namespace: {{ .Values.metadata.namespace }} - annotations: + name: {{ .Release.Name }}-db + namespace: {{ .Release.Namespace }} labels: - run: {{ .Values.service.name }} - app.kubernetes.io/name: {{ .Values.service.name }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/name: h2-service + app.kubernetes.io/component: database + app.kubernetes.io/part-of: "{{ include "corda-node.fullname" . }}" app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - {{- include "labels.custom" . | nindent 2 }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} spec: - type: {{ .Values.service.type }} - selector: - app: {{ .Values.nodeName }} - ports: - # for p2p communication among corda node - - name: p2p - protocol: TCP - port: {{ .Values.service.p2p.port }} - targetPort: {{ .Values.service.p2p.targetPort }} - {{- if .Values.service.p2p.nodePort }} - nodePort: {{ .Values.service.p2p.nodePort}} - {{- end }} - # for rpc communication between corda node and webserver - - name: rpc - protocol: TCP - port: {{ .Values.service.rpc.port }} - targetPort: {{ .Values.service.rpc.targetPort }} - {{- if .Values.service.rpc.nodePort }} - nodePort: {{ .Values.service.rpc.nodePort}} - {{- end }} - # for rpc admin communication - - name: rpcadmin - protocol: TCP - port: {{ .Values.service.rpcadmin.port }} - targetPort: {{ .Values.service.rpcadmin.targetPort }} - {{- if .Values.service.rpcadmin.nodePort }} - nodePort: {{ .Values.service.rpcadmin.nodePort}} - {{- end }} - -{{ if $.Values.ambassador }} + type: ClusterIP + selector: + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + ports: + - name: tcp + protocol: TCP + port: {{ .Values.nodeConf.dbPort }} + targetPort: 1521 + - name: web + protocol: TCP + port: 8080 + targetPort: 81 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: p2p-service + app.kubernetes.io/component: corda + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +spec: + type: ClusterIP + selector: + app.kubernetes.io/component: corda + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + ports: + # for p2p communication among corda node + - name: p2p + protocol: TCP + port: {{ .Values.nodeConf.p2pPort }} + targetPort: {{ .Values.nodeConf.p2pPort }} + # for rpc communication between corda node and webserver + - name: rpc + protocol: TCP + port: {{ .Values.nodeConf.rpcPort }} + targetPort: {{ .Values.nodeConf.rpcPort }} + # for rpc admin communication + - name: rpcadmin + protocol: TCP + port: {{ .Values.nodeConf.rpcadminPort }} + targetPort: {{ .Values.nodeConf.rpcadminPort }} +{{- if eq .Values.global.proxy.provider "ambassador" }} +{{- if .Values.tls.enabled }} --- apiVersion: getambassador.io/v3alpha1 kind: Host metadata: - name: {{ .Values.ambassador.component_name }}-host - namespace: {{ .Values.metadata.namespace }} + name: {{ .Release.Name }}-host + namespace: {{ .Release.Namespace }} spec: - hostname: {{ .Values.ambassador.component_name }}.{{ .Values.ambassador.external_url_suffix }} + hostname: {{ .Release.Name }}.{{ .Values.global.proxy.externalUrlSuffix }} acmeProvider: authority: none requestPolicy: insecure: action: Route tlsSecret: - name: {{ .Values.ambassador.component_name }}-ambassador-certs - namespace: {{ .Values.metadata.namespace }} + name: {{ .Release.Name }}-tls-certs + namespace: {{ .Release.Namespace }} +{{- end }} --- apiVersion: getambassador.io/v3alpha1 -kind: TLSContext +kind: Mapping metadata: - name: {{ .Values.ambassador.component_name }}-context - namespace: {{ .Values.metadata.namespace }} + name: {{ .Release.Name }}-p2p-mapping + namespace: {{ .Release.Namespace }} spec: - hosts: - - {{ .Values.ambassador.component_name }}.{{ .Values.ambassador.external_url_suffix }} - secret: {{ .Values.ambassador.component_name }}-ambassador-certs.{{ .Values.metadata.namespace }} - secret_namespacing: true - min_tls_version: v1.2 + host: {{ .Release.Name }}.{{ .Values.global.proxy.externalUrlSuffix }} + prefix: / + service: {{ .Release.Name }}.{{ .Release.Namespace }}:{{ .Values.nodeConf.p2pPort }} +{{- if .Values.tls.enabled }} + tls: {{ .Release.Name }}-tlscontext --- apiVersion: getambassador.io/v3alpha1 -kind: Mapping +kind: TLSContext metadata: - name: {{ .Values.ambassador.component_name }}-p2p-mapping - namespace: {{ .Values.metadata.namespace }} + name: {{ .Release.Name }}-tlscontext + namespace: {{ .Release.Namespace }} spec: - host: {{ .Values.ambassador.component_name }}.{{ .Values.ambassador.external_url_suffix }} - prefix: / - service: https://{{ .Values.ambassador.component_name }}.{{ .Values.metadata.namespace }}:{{ .Values.nodeConf.p2p.port }} - tls: {{ .Values.ambassador.component_name }}-context -{{ end }} - + hosts: + - {{ .Release.Name }}.{{ .Values.global.proxy.externalUrlSuffix }} + secret: {{ .Release.Name }}-tls-certs.{{ .Release.Namespace }} + secret_namespacing: true + min_tls_version: v1.2 +{{- end }} +{{- end }} diff --git a/platforms/r3-corda/charts/corda-node/templates/statefulset-db.yaml b/platforms/r3-corda/charts/corda-node/templates/statefulset-db.yaml new file mode 100644 index 00000000000..c880c8ded9a --- /dev/null +++ b/platforms/r3-corda/charts/corda-node/templates/statefulset-db.yaml @@ -0,0 +1,85 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "corda-node.fullname" . }}-db + namespace: {{ .Release.Namespace }} + labels: + app: {{ include "corda-node.fullname" . }} + app.kubernetes.io/name: h2-statefulset + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +spec: + replicas: 1 + podManagementPolicy: OrderedReady + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app: {{ include "corda-node.fullname" . }} + app.kubernetes.io/name: h2-statefulset + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + serviceName: {{ include "corda-node.fullname" . }} + volumeClaimTemplates: + - metadata: + name: data-h2 + spec: + storageClassName: storage-{{ .Release.Name }} + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: {{ .Values.storage.dbSize }} + template: + metadata: + labels: + app: {{ include "corda-node.fullname" . }} + app.kubernetes.io/name: h2-statefulset + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + spec: + hostname: {{ .Release.Name }}db + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + securityContext: + fsGroup: 1000 + containers: + - name: database + image: {{ .Values.image.h2 }} + resources: + limits: + memory: {{ .Values.resources.db.memLimit }} + requests: + memory: {{ .Values.resources.db.memRequest }} + ports: + - containerPort: 1521 + name: p2p + - containerPort: 81 + name: web + env: + - name: JAVA_OPTIONS + value: -Xmx512m + volumeMounts: + - name: data-h2 + mountPath: "/opt/h2-data" + readOnly: false + livenessProbe: + tcpSocket: + port: 1521 + initialDelaySeconds: 15 + periodSeconds: 20 diff --git a/platforms/r3-corda/charts/corda-node/templates/statefulset-node.yaml b/platforms/r3-corda/charts/corda-node/templates/statefulset-node.yaml new file mode 100644 index 00000000000..130cdeaa395 --- /dev/null +++ b/platforms/r3-corda/charts/corda-node/templates/statefulset-node.yaml @@ -0,0 +1,632 @@ +############################################################################################## +# Copyright Accenture. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +############################################################################################## +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "corda-node.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ include "corda-node.fullname" . }} + app.kubernetes.io/name: node-statefulset + app.kubernetes.io/component: corda + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} +spec: + replicas: 1 + podManagementPolicy: OrderedReady + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app: {{ include "corda-node.fullname" . }} + app.kubernetes.io/name: node-statefulset + app.kubernetes.io/component: corda + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + serviceName: {{ include "corda-node.fullname" . }} + volumeClaimTemplates: + - metadata: + name: node-volume + spec: + storageClassName: storage-{{ .Release.Name }} + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: {{ .Values.storage.size }} + template: + metadata: + labels: + app: {{ include "corda-node.fullname" . }} + app.kubernetes.io/name: node-statefulset + app.kubernetes.io/component: corda + app.kubernetes.io/part-of: {{ include "corda-node.fullname" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/namespace: {{ .Release.Namespace }} + app.kubernetes.io/release: {{ .Release.Name }} + spec: + serviceAccountName: {{ .Values.global.serviceAccountName }} + hostname: {{ .Release.Name }} + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + securityContext: + fsGroup: 1000 + initContainers: + - name: db-healthcheck + image: {{ .Values.image.initContainer }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh", "-c"] + args: + - |- + #!/usr/bin/env sh + COUNTER=1 + FLAG=true + # Check if db is up and running before starting corda node + while [ "$COUNTER" -le 10 ] + do + DB_NODE={{ .Release.Name }}-db:{{ .Values.nodeConf.dbPort }} + STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) + if [ "$STATUS" == 0 ] + then + FLAG=false + else + FLAG=true + echo "DB up and running" + fi + if [ "$FLAG" == false ] + then + echo "Retry attempted $COUNTER times, retrying after 5 seconds" + COUNTER=`expr "$COUNTER" + 1` + sleep 5 + else + echo "SUCCESS!" + echo "DB up and running!" + exit 0 + break + fi + done + if [ "$COUNTER" -gt 10 ] || [ "$FLAG" == false ] + then + echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" + exit 1 + break + fi + - name: init-nodeconf + image : {{ .Values.image.initContainer }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: BASE_DIR + value: "/base/corda" + {{- if (eq .Values.global.vault.type "hashicorp") }} + - name: VAULT_ADDR + value: {{ .Values.global.vault.address }} + - name: VAULT_SECRET_ENGINE + value: "{{ .Values.global.vault.secretEngine }}" + - name: VAULT_SECRET_PREFIX + value: "{{ .Values.global.vault.secretPrefix }}" + - name: KUBERNETES_AUTH_PATH + value: {{ .Values.global.vault.authPath }} + - name: VAULT_APP_ROLE + value: {{ .Values.global.vault.role }} + - name: VAULT_TYPE + value: "{{ .Values.global.vault.type }}" + {{- end }} + command: ["/bin/sh","-c"] + args: + - |- + #!/bin/bash + {{- if (eq .Values.global.vault.type "hashicorp") }} + . /scripts/bevel-vault.sh + echo "Getting vault Token..." + vaultBevelFunc "init" + #Read if secret exists in Vault + function checkSecret { + key=$1 + fpath=$2 + mkdir -p ${fpath} + vaultBevelFunc 'readJson' "${VAULT_SECRET_ENGINE}/${VAULT_SECRET_PREFIX}/${key}-registrationcerts" + if [ "$SECRETS_AVAILABLE" == "yes" ] + then + # Get secret from Vault and store in fpath + SSL_STORE=$(echo ${VAULT_SECRET} | jq -r '.["sslkeystore_base64"]') + SSL_TRUST=$(echo ${VAULT_SECRET} | jq -r '.["ssltruststore_base64"]') + NODE_STORE=$(echo ${VAULT_SECRET} | jq -r '.["nodekeystore_base64"]') + echo $SSL_STORE | base64 -d > ${fpath}/sslkeystore.jks + echo $SSL_TRUST | base64 -d > ${fpath}/truststore.jks + echo $NODE_STORE | base64 -d > ${fpath}/nodekeystore.jks + fi + } + {{- else }} + function checkSecret { + key=$1 + fpath=$2 + #Do nothing as certs are not stored as k8s secrets as of now + } + {{- end }} + # delete previously created node.conf, and create a new node.conf + rm -f ${BASE_DIR}/node.conf; + touch ${BASE_DIR}/node.conf; + + #For more information for node.Conf fields please refer to: https://docs.corda.r3.com/releases/4.0/corda-configuration-file.html + cat << 'EOF' > ${BASE_DIR}/node.conf + p2pAddress : "{{ .Release.Name }}.{{ .Release.Namespace }}:{{ .Values.nodeConf.p2pPort }}" + myLegalName : {{ .Values.nodeConf.legalName | quote }} + keyStorePassword : ${CONF_KEYSTOREPASSWORD} + trustStorePassword : ${CONF_TRUSTSTOREPASSWORD} + transactionCacheSizeMegaBytes : {{ .Values.nodeConf.transactionCacheSizeMegaBytes }} + attachmentContentCacheSizeMegaBytes : {{ .Values.nodeConf.attachmentContentCacheSizeMegaBytes }} + {{- if .Values.nodeConf.notary.enabled }} + notary : { + serviceLegalName : "{{ .Values.nodeConf.notary.serviceLegalName }}" + validating : {{ .Values.nodeConf.notary.validating }} + } + {{- end }} + detectPublicIp = {{ .Values.nodeConf.detectPublicIp }} + additionalP2PAddresses = ["{{ .Release.Name }}.{{ .Values.global.proxy.externalUrlSuffix }}:{{ .Values.global.proxy.p2p }}"] + devMode : {{ .Values.nodeConf.devMode }} + dataSourceProperties = { + dataSourceClassName = "{{ .Values.nodeConf.dataSourceClassName }}" + dataSource.url = "jdbc:h2:tcp://{{ .Release.Name }}-db:{{ .Values.nodeConf.dbPort }}/persistence;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;WRITE_DELAY=100;AUTO_RECONNECT=TRUE;" + dataSource.user = {{ .Values.nodeConf.dataSourceUser }} + dataSource.password = ${CONF_DATASOURCEPASSWORD} + } + database = { + exportHibernateJMXStatistics = {{ .Values.nodeConf.database.exportHibernateJMXStatistics }} + } + jarDirs = [{{ .Values.nodeConf.jarPath }}] + networkServices = { + doormanURL = "{{ .Values.nodeConf.doormanURL }}" + networkMapURL = "{{ .Values.nodeConf.networkMapURL }}" + } + EOF + + if [ -z "{{ .Values.nodeConf.jvmArgs }}" ] + then + echo 'jvmArgs is not configured' + else + echo 'jvmArgs = "{{ .Values.nodeConf.jvmArgs }}" ' >> ${BASE_DIR}/node.conf + fi + + if [ -z "{{ .Values.nodeConf.sshd.port }}" ] + then + echo 'sshd port is not configured' + else + echo 'sshd { port = {{ .Values.nodeConf.sshd.port }} } ' >> ${BASE_DIR}/node.conf + fi + + if [ -z "{{ .Values.nodeConf.systemProperties }}" ] + then + echo 'systemProperties is not configured' + else + echo 'systemProperties = {{ .Values.nodeConf.systemProperties }} ' >> ${BASE_DIR}/node.conf + fi + + if [ -z "{{ .Values.nodeConf.exportJMXTo }}" ] + then + echo 'exportJMXTo is not configured' + else + echo 'exportJMXTo = {{ .Values.nodeConf.exportJMXTo }} ' >> ${BASE_DIR}/node.conf + fi + + if [ -z "{{ .Values.nodeConf.messagingServerAddress }}" ] + then + echo 'The address of the ArtemisMQ broker instance is not configured' + else + echo 'messagingServerAddress : "{{ .Values.nodeConf.messagingServerAddress }}" ' >> ${BASE_DIR}/node.conf + fi + + if [ -z "{{ .Values.nodeConf.rpcUser }}" ] + then + echo 'rpc user is not configured' + else + echo 'rpcUsers : [' >> ${BASE_DIR}/node.conf + {{- range $.Values.nodeConf.rpcUser }} + echo '{ username={{ .name }} ,permissions={{ .permissions }}, ' >> ${BASE_DIR}/node.conf + echo " password={{ .password }} }" >> ${BASE_DIR}/node.conf + {{- end }} + echo ']' >> ${BASE_DIR}/node.conf + fi + + if [ "{{ .Values.nodeConf.rpcSettings.useSsl }}" == true ] + then + echo 'rpcSettings { + standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} + address = "{{ .Values.nodeConf.rpcSettings.address }}" + adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" + useSsl = {{ .Values.nodeConf.rpcSettings.useSsl }} + ssl = { + keyStorePassword = {{ .Values.nodeConf.sslkeyStorePassword }} + trustStorePassword = {{ .Values.nodeConf.ssltrustStorePassword }} + certificatesDirectory = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }} + sslKeystore = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.sslKeystoreFileName }} + trustStoreFile = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.trustStoreFileName }} + } + }' >> ${BASE_DIR}/node.conf + else + echo 'rpcSettings { + standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} + address = "{{ .Values.nodeConf.rpcSettings.address }}" + adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" + }' >> ${BASE_DIR}/node.conf + fi + echo "node.conf created in ${BASE_DIR}" + checkSecret {{ .Release.Name }} ${BASE_DIR}/certificates + volumeMounts: + - name: nodeconf + mountPath: "/base/corda" + readOnly: false + - name: certificates + mountPath: "/base/corda/certificates" + readOnly: false + - name: scripts-volume + mountPath: /scripts/bevel-vault.sh + subPath: bevel-vault.sh + - name: init-registration + image: {{ .Values.image.corda.repository }}:{{ .Values.image.corda.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - name: node-volume + mountPath: "/base/corda" + readOnly: false + - name: certificates + mountPath: "/base/corda/certificates" + readOnly: false + - name: node-certs + mountPath: "/opt/corda/certificates" + - name: nodeconf + mountPath: "/base/corda/node.conf" + subPath: "node.conf" + readOnly: false + {{- if .Values.tls.enabled }} + - name: nms-certs + mountPath: "/certs/nms" + - name: doorman-certs + mountPath: "/certs/doorman" + {{- end }} + env: + - name: BASE_DIR + value: /base/corda + - name: CORDA_HOME + value: /opt/corda + - name: JAVA_OPTIONS + value: {{ .Values.nodeConf.javaOptions | quote }} + - name: CONF_KEYSTOREPASSWORD + value: {{ .Values.nodeConf.defaultKeystorePassword }} + - name: CONF_TRUSTSTOREPASSWORD + value: {{ .Values.nodeConf.defaultTruststorePassword }} + - name: CONF_DATASOURCEPASSWORD + value: {{ .Values.nodeConf.dataSourcePassword }} + - name: KEYSTORE_PASSWORD + value: {{ .Values.nodeConf.keystorePassword }} + - name: TRUSTSTORE_PASSWORD + value: {{ .Values.nodeConf.truststorePassword }} + command: ["sh", "-c"] + args: + - |- + #!/usr/bin/env sh + if [ -e /opt/corda/certificates/truststore.jks ] + then + cp /opt/corda/certificates/* ${BASE_DIR}/certificates/ + echo "Initial Registration already complete for {{ .Release.Name }} ..." + else + echo "Initial registration start ..." + cp /opt/corda/certificates/* ${BASE_DIR}/certificates/ + chmod +w ${BASE_DIR}/certificates/nodekeystore.jks + + # import self signed tls certificate of doorman and networkmap, since java only trusts certificate signed by well known CA + {{- if .Values.tls.enabled }} + eval "yes | keytool -importcert -file /certs/nms/tls.crt -storepass changeit -alias {{ include "corda-node.nmsDomain" . }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts" + eval "yes | keytool -importcert -file /certs/doorman/tls.crt -storepass changeit -alias {{ include "corda-node.doormanDomain" . }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts" + {{- end }} + + # command to run corda jar and perform initial-registration + java $JAVA_OPTIONS -jar ${CORDA_HOME}/corda.jar initial-registration --network-root-truststore-password ${CONF_TRUSTSTOREPASSWORD} --network-root-truststore ${BASE_DIR}/certificates/network-map-truststore.jks --base-directory=${BASE_DIR} + + #changing password of keystore. + keytool -storepasswd -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${CONF_KEYSTOREPASSWORD} + if [ $? -ne 0 ]; then + echo "Error in initial-registration" + exit 1 + fi + keytool -storepasswd -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/sslkeystore.jks -storepass ${CONF_KEYSTOREPASSWORD} + keytool -storepasswd -new ${TRUSTSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/truststore.jks -storepass ${CONF_TRUSTSTOREPASSWORD} + + #changing password of nodekeystore.jks certificate. + keytool -keypasswd -alias cordaclientca -keypass ${CONF_KEYSTOREPASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${KEYSTORE_PASSWORD} + keytool -keypasswd -alias identity-private-key -keypass ${CONF_KEYSTOREPASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${KEYSTORE_PASSWORD} + {{- if .Values.nodeConf.notary.enabled }} + keytool -keypasswd -alias distributed-notary-private-key -keypass ${CONF_KEYSTOREPASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${KEYSTORE_PASSWORD} + {{- end }} + #changing password of sslkeystore.jks certificate. + keytool -keypasswd -alias cordaclienttls -keypass ${CONF_KEYSTOREPASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/sslkeystore.jks -storepass ${KEYSTORE_PASSWORD} + + echo "Initial Registration Complete" + fi; + - name: init-cordapps + image: {{ .Values.image.initContainer }} + imagePullPolicy: Always + env: + - name: BASE_DIR + value: "/base/corda" + - name: VAULT_APP_ROLE + value: {{ .Values.global.vault.role }} + - name: VAULT_ADDR + value: {{ .Values.global.vault.address }} + - name: KUBERNETES_AUTH_PATH + value: {{ .Values.global.vault.authPath }} + - name: SECRET_PREFIX + value: {{ .Values.global.vault.secretPrefix }} + command: ["sh", "-c"] + args: + - |- + # crearting cordapps dir in volume to keep jars + mkdir -p /base/corda/cordapps + {{- if .Values.cordApps.getCordApps }} + mkdir -p /tmp/downloaded-jars + # setting up env to get secrets from vault + KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) + echo "Getting secrets from Vault Server" + VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') + + # save cordapps repository login password from vault + LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${SECRET_PREFIX} | jq -r 'if .errors then . else . end') + REPO_USER_PASS=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["repo_password"]') + REPO_USER=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["repo_username"]') + + # Downloading official corda provided jars using curl + {{- range .Values.cordApps.jars }} + cd /tmp/downloaded-jars && curl -u $REPO_USER:$REPO_USER_PASS -O -L {{ .url }} + {{- end }} + cp -ar /tmp/downloaded-jars/* /base/corda/cordapps + {{- end }} + volumeMounts: + - name: node-volume + mountPath: "/base/corda" + containers: + - name: node + image: {{ .Values.image.corda.repository }}:{{ .Values.image.corda.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: BASE_DIR + value: /base/corda + - name: CORDA_HOME + value: /opt/corda + - name: JAVA_OPTIONS + value: {{ .Values.nodeConf.javaOptions | quote }} + - name: CONF_KEYSTOREPASSWORD + value: {{ .Values.nodeConf.keystorePassword }} + - name: CONF_TRUSTSTOREPASSWORD + value: {{ .Values.nodeConf.truststorePassword }} + - name: CONF_DATASOURCEPASSWORD + value: {{ .Values.nodeConf.dataSourcePassword }} + command: ["sh", "-c"] + args: + - |- + #!/usr/bin/env sh + + # import self signed tls certificate of doorman and networkmap, since java only trusts certificate signed by well known CA + {{- if .Values.tls.enabled }} + eval "yes | keytool -importcert -file /certs/nms/tls.crt -storepass changeit -alias {{ include "corda-node.nmsDomain" . }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts" + eval "yes | keytool -importcert -file /certs/doorman/tls.crt -storepass changeit -alias {{ include "corda-node.doormanDomain" . }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts" + {{- end }} + + # to clean network-parameters on every restart + rm -rf ${BASE_DIR}/network-parameters + # Run schema migration scripts for corDApps + java -Djavax.net.ssl.keyStore=${BASE_DIR}/certificates/sslkeystore.jks -Djavax.net.ssl.keyStorePassword=$CONF_KEYSTOREPASSWORD $JAVA_OPTIONS -jar ${CORDA_HOME}/corda.jar run-migration-scripts --core-schemas --app-schemas --base-directory=${BASE_DIR} + + # command to run corda jar, we are setting javax.net.ssl.keyStore as ${BASE_DIR}/certificates/sslkeystore.jks since keystore gets reset when using h2 ssl + java -Djavax.net.ssl.keyStore=${BASE_DIR}/certificates/sslkeystore.jks -Djavax.net.ssl.keyStorePassword=$CONF_KEYSTOREPASSWORD $JAVA_OPTIONS -jar ${CORDA_HOME}/corda.jar --base-directory=${BASE_DIR} + resources: + limits: + memory: {{ .Values.resources.node.memLimit }} + requests: + memory: {{ .Values.resources.node.memRequest }} + ports: + - containerPort: {{ .Values.nodeConf.p2pPort }} + name: p2p + - containerPort: {{ .Values.nodeConf.rpcPort }} + name: rpc + - containerPort: {{ .Values.nodeConf.rpcadminPort }} + name: rpcadmin + volumeMounts: + - name: node-volume + mountPath: "/base/corda" + readOnly: false + - name: certificates + mountPath: "/base/corda/certificates" + readOnly: false + - name: nodeconf + mountPath: "/base/corda/node.conf" + subPath: "node.conf" + readOnly: false + {{- if .Values.tls.enabled }} + - name: nms-certs + mountPath: "/certs/nms" + - name: doorman-certs + mountPath: "/certs/doorman" + {{- end }} + livenessProbe: + tcpSocket: + port: {{ .Values.nodeConf.p2pPort }} + initialDelaySeconds: 65 + periodSeconds: 30 + - name: corda-logs + image: {{ .Values.image.initContainer }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: BASE_DIR + value: /base/corda + - name: CORDA_HOME + value: /opt/corda + - name: JAVA_OPTIONS + value: {{ .Values.nodeConf.javaOptions | quote }} + {{- if (eq .Values.global.vault.type "hashicorp") }} + - name: VAULT_ADDR + value: {{ .Values.global.vault.address }} + - name: VAULT_SECRET_ENGINE + value: "{{ .Values.global.vault.secretEngine }}" + - name: VAULT_SECRET_PREFIX + value: "{{ .Values.global.vault.secretPrefix }}" + - name: KUBERNETES_AUTH_PATH + value: {{ .Values.global.vault.authPath }} + - name: VAULT_APP_ROLE + value: {{ .Values.global.vault.role }} + - name: VAULT_TYPE + value: "{{ .Values.global.vault.type }}" + {{- end }} + command: ["sh", "-c"] + args: + - |- + #!/usr/bin/env sh + {{- if (eq .Values.global.vault.type "hashicorp") }} + . /scripts/bevel-vault.sh + echo "Getting vault Token..." + vaultBevelFunc "init" + function safeWriteSecret { + key=$1 + fpath=$2 + #Read if secret exists in Vault + vaultBevelFunc 'readJson' "${VAULT_SECRET_ENGINE}/${VAULT_SECRET_PREFIX}/${key}-registrationcerts" + if [ "$SECRETS_AVAILABLE" == "yes" ] + then + echo "Registration Secrets already stored on Vault" + else + # Save secrets to Vault + # Use -w0 to get single line base64 -w0 + NODE_STORE=$(cat ${fpath}/nodekeystore.jks | base64 -w0) + SSL_STORE=$(cat ${fpath}/sslkeystore.jks | base64 -w0) + SSL_TRUST=$(cat ${fpath}/truststore.jks | base64 -w0) + # create a JSON file for the data related to node crypto + echo " + { + \"data\": + { + \"nodekeystore_base64\": \"${NODE_STORE}\", + \"sslkeystore_base64\": \"${SSL_STORE}\", + \"ssltruststore_base64\": \"${SSL_TRUST}\" + } + }" > payload.json + vaultBevelFunc 'write' "${VAULT_SECRET_ENGINE}/${VAULT_SECRET_PREFIX}/${key}-registrationcerts" 'payload.json' + kubectl patch secret ${key}-certs -p "{\"data\":{\"nodekeystore.jks\":\"$NODE_STORE\", \"sslkeystore.jks\":\"$SSL_STORE\", \"truststore.jks\":\"$SSL_TRUST\" }}" + rm payload.json + fi + } + {{- else }} + function safeWriteSecret { + key=$1 + fpath=$2 + # Use -w0 to get single line base64 -w0 + NODE_STORE=$(cat ${fpath}/nodekeystore.jks | base64 -w0) + SSL_STORE=$(cat ${fpath}/sslkeystore.jks | base64 -w0) + SSL_TRUST=$(cat ${fpath}/truststore.jks | base64 -w0) + kubectl patch secret ${key}-certs -p "{\"data\":{\"nodekeystore.jks\":\"$NODE_STORE\", \"sslkeystore.jks\":\"$SSL_STORE\", \"truststore.jks\":\"$SSL_TRUST\" }}" + } + {{- end }} + {{- if .Values.nodeConf.notary.enabled }} + if [ -e ${BASE_DIR}/notaryregistered ] + then + echo "Notary already registered" + else + NMS_USER_ID={{ .Values.nodeConf.dataSourceUser }} + NMS_USER_PASSWORD={{ .Values.nodeConf.dataSourcePassword }} + + STATUS=0 + while [ "$STATUS" -ne 1 ] + do + # get node-info file name + cd ${BASE_DIR} + NOTARYNODEINFOFILENAME=$(ls ${BASE_DIR}/ | grep nodeInfo | awk '{print $1}'); + echo "NOTARYNODEINFOFILENAME=$NOTARYNODEINFOFILENAME" + if [ -z $NOTARYNODEINFOFILENAME ] + then + echo "node-info file not ready, sleeping for 10s" + sleep 10 + STATUS=0 + else + # get url for registration + url={{ .Values.nodeConf.networkMapURL }} + # check if notary type is validating or non validating, and form url accordingly + if [ {{ .Values.nodeConf.notary.validating }} == "true" ] + then + section=/admin/api/notaries/validating + else + section=/admin/api/notaries/nonValidating + fi + + # get one time login token from networkmap + token=$(curl -k --silent --show-error -X POST "$url/admin/api/login" -H "accept: text/plain" -H "Content-Type: application/json" -d "{ \"user\": \"${NMS_USER_ID}\", \"password\": \"${NMS_USER_PASSWORD}\"}" | awk '{print $1}'); + # curl command to register notary, if resonse is okay then registration is sucessfull + cd ${BASE_DIR} + response=$(curl -k --silent --show-error -X POST -H "Authorization: Bearer ${token}" -H "accept: text/plain" -H "Content-Type: application/octet-stream" --data-binary @${NOTARYNODEINFOFILENAME} ${url}${section} | awk '{print $1}') + echo "responsevar=$response" + if [ $response = "OK" ] + then + echo "Response is OK"; + echo "Registered notary with Networkmap successfully" + touch ${BASE_DIR}/notaryregistered + else + echo "Response from NMS is not ok"; + echo "Something went wrong" + fi + STATUS=1 + break + fi + done + fi + {{- end }} + {{- if and (ne .Values.global.cluster.provider "minikube") (.Values.global.cluster.cloudNativeServices) }} + safeWriteSecret {{ .Release.Name }}-sslkeystore ${BASE_DIR}/certificates/sslkeystore.jks + safeWriteSecret {{ .Release.Name }}-ssltruststore ${BASE_DIR}/certificates/truststore.jks + safeWriteSecret {{ .Release.Name }}-nodekeystore ${BASE_DIR}/certificates/nodekeystore.jks + {{- else }} + safeWriteSecret {{ .Release.Name }} ${BASE_DIR}/certificates + {{- end }} + echo "Completed ..." + if [ -e ${BASE_DIR}/logs/node-{{ include "corda-node.fullname" . }}-0.log ] + then + tail -f ${BASE_DIR}/logs/node-{{ include "corda-node.fullname" . }}-0.log + else + echo "waiting for corda to generate log, sleeping for 10s" + sleep 10 + fi + volumeMounts: + - name: node-volume + mountPath: "/base/corda" + readOnly: false + - name: certificates + mountPath: "/base/corda/certificates" + readOnly: false + - name: scripts-volume + mountPath: /scripts/bevel-vault.sh + subPath: bevel-vault.sh + volumes: + - name: scripts-volume + configMap: + name: bevel-vault-script + defaultMode: 0777 + - name: nodeconf + emptyDir: + medium: Memory + - name: certificates + emptyDir: + medium: Memory + - name: node-certs + secret: + secretName: {{ .Release.Name }}-certs +{{- if .Values.tls.enabled }} + - name: nms-certs + secret: + secretName: nms-tls-certs + - name: doorman-certs + secret: + secretName: doorman-tls-certs +{{- end }} diff --git a/platforms/r3-corda/charts/corda-node/values.yaml b/platforms/r3-corda/charts/corda-node/values.yaml index e590a2d72b3..8ea579a7c3b 100644 --- a/platforms/r3-corda/charts/corda-node/values.yaml +++ b/platforms/r3-corda/charts/corda-node/values.yaml @@ -3,262 +3,139 @@ # # SPDX-License-Identifier: Apache-2.0 ############################################################################################## +global: + serviceAccountName: vault-auth + cluster: + provider: aws # choose from: minikube | aws | azure | gcp + cloudNativeServices: false # set to true to use Cloud Native Services (SecretsManager and IAM for AWS; KeyVault & Managed Identities for Azure) + vault: + type: hashicorp + role: vault-role + address: + authPath: supplychain + secretEngine: secretsv2 + secretPrefix: "data/supplychain" + proxy: + #This will be the proxy/ingress provider. Can have values "ambassador" or "none" + #Eg. provider: "ambassador" + provider: "ambassador" + #This field contains the external URL of the node + #Eg. externalUrlSuffix: test.blockchaincloudpoc.com + externalUrlSuffix: test.blockchaincloudpoc.com + p2p: 15010 -#Provide the nodeName for node -#Eg. nodeName: bank1 -nodeName: bank1 - -#Provide the replica set for node deployed -#Eg. replicas: 1 -replicas: 1 +storage: + #Provide the storage for node + #Eg. size: 1Gi + size: 1Gi + dbSize: 2Gi + allowedTopologies: + enabled: false +tls: + enabled: true -metadata: - #Provide the namespace - #Eg. namespace: default - namespace: - #Provide the custom labels - #NOTE: Provide labels other than name, release name , release service, chart version , chart name , app. - #Eg. labels: - # role: create_channel - labels: - image: + #Provide the image pull secret of image + #Eg. pullSecret: regcred + pullSecret: + pullPolicy: IfNotPresent + h2: ghcr.io/hyperledger/h2:2018 #Provide the containerName of image #Eg. containerName: ghcr.io/hyperledger/bevel-corda:4.9 - containerName: ghcr.io/hyperledger/bevel-corda:4.9 + corda: + repository: ghcr.io/hyperledger/bevel-corda + tag: 4.9 #Provide the name of image for init container - #Eg. name: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: regcred - #Provide true or false if private certificate to be added - #Eg. privateCertificate: true - privateCertificate: true - #Provide true or false if private certificate to be added - #Eg. doormanCertAlias: doorman.fracordakubetest7.com - doormanCertAlias: doorman.fracordakubetest7.com - #Provide true or false if private certificate to be added - #Eg. networkmapCertAlias: networkmap.fracordakubetest7.com - networkmapCertAlias: networkmap.fracordakubetest7.com - + #Eg. initContainer: ghcr.io/hyperledger/bevel-alpine:latest + initContainer: ghcr.io/hyperledger/bevel-alpine:latest + hooks: + repository: ghcr.io/hyperledger/bevel-build + tag: jdk8-stable -#For more information for node.Conf fields please refer to: https://docs.corda.net/releases/release-V3.3/corda-configuration-file.html +#For more information for node.Conf fields please refer to: https://docs.r3.com/en/platform/corda/4.9/community/corda-configuration-fields.html nodeConf: + defaultKeystorePassword: cordacadevpass + defaultTruststorePassword: trustpass + keystorePassword: newpass + truststorePassword: newtrustpass + sslkeyStorePassword: sslpass + ssltrustStorePassword: ssltrustpass + removeKeysOnDelete: true + #Provide the rpcUser for corda node + rpcUser: + - name: nodeoperations + password: nodeoperationsAdmin + permissions: [ALL] #The host and port on which the node is available for protocol operations over ArtemisMQ. - p2p: - url: - port: - #Specify the ambassador host:port which will be advertised in addition to p2paddress - ambassadorAddress: + p2pPort: 10002 + rpcPort: 10003 + rpcadminPort: 10005 rpcSettings: - useSsl: - standAloneBroker: - address: - adminAddress: + useSsl: false + standAloneBroker: false + address: "0.0.0.0:10003" + adminAddress: "0.0.0.0:10005" ssl: - certificatesDirectory: - sslKeystorePath: - trustStoreFilePath: + certificatesDirectory: na-ssl-false + sslKeystorePath: na-ssl-false + trustStoreFilePath: na-ssl-false #Provide the legalName for node - #Eg. legalName: "O=Bank1,L=London,C=GB,CN=Bank1" - legalName: + #Eg. legalName: "O=Notary,OU=Notary,L=London,C=GB" + legalName: "O=Notary,OU=Notary,L=London,C=GB" messagingServerAddress: jvmArgs: systemProperties: sshd: port: exportJMXTo: - transactionCacheSizeMegaBytes: - attachmentContentCacheSizeMegaBytes: + transactionCacheSizeMegaBytes: 8 + attachmentContentCacheSizeMegaBytes: 10 notary: - validating: - detectPublicIp: - database: - exportHibernateJMXStatistics: - #Provide the h2Url for node - #Eg. h2Url: bank1h2 - dbUrl: bank1h2 - #Provide the h2Port for node - #Eg. h2Port: 9101 + enabled: true + validating: true + serviceLegalName: "O=Notary Service,OU=Notary,L=London,C=GB" + detectPublicIp: false + database: + exportHibernateJMXStatistics: false + #Provide the database port + #Eg. dbPort: 9101 dbPort: 9101 - dataSourceClassName: - dataSourceUrl: - jarPath: + dataSourceUser: sa + dataSourcePassword: admin + dataSourceClassName: "org.h2.jdbcx.JdbcDataSource" + jarPath: "/data/corda-workspace/h2/bin" #Provide the nms for node - #Eg. nms: "http://rp-elb-fra-corda-kube-cluster7-2016021309.us-west-1.elb.amazonaws.com:30050" - networkMapURL: - doormanURL: - compatibilityZoneURL: - webAddress: - #Provide the jar Version for corda jar and finanace jar - #Eg. jarVersion: 3.3-corda - jarVersion: 3.3-corda + #Eg. networkMapURL: "https://supplychain-nms.supplychain-ns" + networkMapURL: https://supplychain-nms.supplychain-ns + doormanURL: https://supplychain-doorman.supplychain-ns #Provide the devMode for corda node #Eg. devMode: true - devMode: true - #Provide the useHTTPS for corda node - #Eg. useHTTPS: false - useHTTPS: false - #Provide the enviroment variables to be set - env: - - name: JAVA_OPTIONS - value: - - name: CORDA_HOME - value: - - name: BASE_DIR - value: - -credentials: - #Provide the dataSourceUser for corda node - #Eg. dataSourceUser: - dataSourceUser: - #Provide the rpcUser for corda node - rpcUser: - - name: bank1operations - permissions: [ALL] - -volume: - #Provide the base path - #Eg. mountPath: "/opt/h2-data" - baseDir: - -resources: - #Provide the limit memory for node - #Eg. limits: "1Gi" - limits: "1Gi" - #Provide the requests memory for node - #Eg. requests: "1Gi" - requests: "1Gi" - -storage: - #Provide the provisioner for node - #Eg. provisioner: kubernetes.io/aws-ebs - provisioner: kubernetes.io/aws-ebs - #Provide the name for node - #Eg. name: bank1nodesc - name: bank1nodesc - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - parameters: - #Provide the type for node - #Eg. type: gp2 - type: gp2 - # Provide whether the EBS volume should be encrypted or not - #Eg. encrypted: "true" - encrypted: "true" - # annotations: - # key: "value" - annotations: + devMode: false + #Provide the JAVA_OPTIONS for Corda Node as string + javaOptions: "-Xmx512m" - -service: -# Note: Target ports are dependent on image being used. Please change them accordingly -# nodePort should be kept empty while using service type as ClusterIP ( Values.service.type ) - #Provide the type of service - #Eg. type: NodePort or LoadBalancer etc - type: NodePort - p2p: - #Provide the p2p port for node - #Eg. port: 10007 - port: 10007 - #Provide the p2p node port for node - #Eg. port: 30007 - nodePort: - #Provide the p2p targetPort for node - #Eg. targetPort: 30007 - targetPort: 30007 - rpc: - #Provide the rpc port for node - #Eg. port: 10008 - port: 10008 - #Provide the rpc targetPort for node - #Eg. targetPort: 10003 - targetPort: 10003 - #Provide the rpc node port for node - #Eg. nodePort: 30007 - nodePort: - rpcadmin: - #Provide the rpcadmin port for node - #Eg. port: 10108 - port: 10108 - #Provide the rpcadmin targetPort for node - #Eg. targetPort: 10005 - targetPort: 10005 - #Provide the rpcadmin node port for node - #Eg. nodePort: 30007 - nodePort: - # annotations: - # key: "value" - annotations: - -deployment: - annotations: -# annotations: -# key: "value" - -pvc: - # annotations: - # key: "value" - annotations: - -vault: - #Provide the vault server address - #Eg. address: http://54.226.163.39:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: vault-role - #Provide the authpath - #Eg. authpath: cordabank1 - authpath: cordabank1 - #Provide the serviceaccountname - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: vault-auth-issuer - #Provide the secretprefix - #Eg. dbsecretprefix: bank1/credentials/database - dbsecretprefix: bank1/credentials/database - #Provide the secretprefix - #Eg. rpcusersecretprefix: bank1/credentials/rpcusers - rpcusersecretprefix: bank1/credentials/rpcusers - #Provide the secretprefix - #Eg. keystoresecretprefix: bank1/credentials/keystore - keystoresecretprefix: bank1/credentials/keystore - #Provide the secretprefix - #Eg. certsecretprefix: bank1/certs - certsecretprefix: bank1/certs - #Provide the secretprefix - #Eg. cordappsreposecretprefix: bank1/credentials/cordapps - cordappsreposecretprefix: bank1/credentials/cordapps - -cordapps: - #Provide if you want to provide jars in cordapps - #Eg. getcordapps: true or false - getcordapps: - repository: +cordApps: + #Provide if you want to provide jars in cordApps + #Eg. getCordApps: true or false + getCordApps: false jars: #Provide url to download the jar using wget cmd #Eg. url: https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases/net/corda/corda-finance/3.3-corda/corda-finance-3.3-corda.jar - url: - url: - -healthcheck: - #Provide the interval in seconds you want to iterate till db to be ready - #Eg. readinesscheckinterval: 5 - readinesscheckinterval: 5 - #Provide the threshold till you want to check if specified db up and running - #Eg. readinessthreshold: 2 - readinessthreshold: 2 - -ambassador: - #Provides component name - #Eg. component_name: node - component_name: node - #Provides the suffix to be used in external URL - #Eg. external_url_suffix: org1.blockchaincloudpoc.com - external_url_suffix: org1.blockchaincloudpoc.com - #Provide the p2p port for ambassador - #Eg. p2p_ambassador: 10007 - p2p_ambassador: +resources: + db: + #Provide the limit memory for node + #Eg. memLimit: "1Gi" + memLimit: "1G" + #Provide the requests memory for node + #Eg. memRequest: "1Gi" + memRequest: "512M" + node: + #Provide the limit memory for node + #Eg. memLimit: "1Gi" + memLimit: "2G" + #Provide the requests memory for node + #Eg. memRequest: "1Gi" + memRequest: "1G" diff --git a/platforms/r3-corda/charts/corda-notary-initial-registration/Chart.yaml b/platforms/r3-corda/charts/corda-notary-initial-registration/Chart.yaml deleted file mode 100644 index bd03c0e2602..00000000000 --- a/platforms/r3-corda/charts/corda-notary-initial-registration/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Job for initial notary node registration." -name: corda-notary-initial-registration -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-notary-initial-registration/README.md b/platforms/r3-corda/charts/corda-notary-initial-registration/README.md deleted file mode 100644 index e4cad681e1d..00000000000 --- a/platforms/r3-corda/charts/corda-notary-initial-registration/README.md +++ /dev/null @@ -1,220 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# Node Deployment - -- [Notary-initial-registration Deployment Helm Chart](#Notary-initial-registration-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - -## notary-initial-registration Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-notary-initial-registration) helps to deploy the job for initial notory node registration. - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- networkmap and Node's database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - - -This chart has following structue: -``` - . - ├── notary-initial-registration - │ ├── Chart.yaml - │ ├── templates - │ │ ├── _helpers.tpl - │ │ └── job.yaml - │ └── values.yaml -``` - -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `job.yaml` : This file is a configuration file for deployement in Kubernetes.It creates a deployment file with a specified number of replicas and defines various settings for the deployment, Init container is responsible for intial node registration process is completed successfully before the main containers start.It also specifies volume mounts for storing certificates and data. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the image, nodeconfig, credenatials, storage, service , vault, etc. -- `_helpers.tpl` : A template file used for defining custom labels and ports for the metrics in the Helm chart. - - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-notary-initial-registration/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | bank1 | - -### Metadata - -| Name | Description | Default Value | -| ----------------| ---------------------------------------------------------------------------- | ------------- | -| namespace | Provide the namespace for the Notary-initial-registration Generator | default | -| labels | Provide any additional labels for the Notary-initial-registration Generator | "" | - -### Image - -| Name | Description | Default Value | -| ------------------------ | --------------------------------------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| containerName | Provide the containerName of image | "" | -| imagePullSecret | Provide the image pull secret of image | regcred | -| privateCertificate | Provide true or false if private certificate to be added | "true" | -| doormanCertAlias | Provide true or false if private certificate to be added | "" | -| networkmapCertAlias | Provide true or false if private certificate to be added | "" | - -### NodeConf - -| Name | Description | Default Value | -| ------------------------ | -------------------------------------------------------------------------------------- | --------------- | -| p2p | The host and port on which the node is available for protocol operations over ArtemisMQ | "" | -| ambassadorAddress | Specify ambassador host:port which will be advertised in addition to p2paddress | "" | -| legalName | Provide the legalName for node | "" | -| dbUrl | Provide the h2Url for node | "bank1h2" | -| dbPort | Provide the h2Port for node | "9101" | -| networkMapURL | Provide the nms for node | "" | -| doormanURL | Provide the doorman for node | "" | -| jarVersion | Provide the jar Version for corda jar and finanace jar | "3.3-corda" | -| devMode | Provide the devMode for corda node | "true" | -| env | Provide the enviroment variables to be set | "" | - -### credentials - -| Name | Description | Default Value | -| ----------------| ----------------------------------------------| ------------- | -| dataSourceUser | Provide the dataSourceUser for corda node | "" | -| rpcUser | Provide the rpcUser for corda node | bank1operations| - -### Volume - -| Name | Description | Default Value | -| -----------------| -----------------------| ------------- | -| baseDir | Base directory | /home/bevel | - -### Resources - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| limits | Provide the limit memory for node | "1Gi" | -| requests | Provide the requests memory for node | "1Gi" | - -### Service - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| type | Provide the type of service | NodePort | -| p2p port | Provide the tcp port for node | 10007 | -| p2p nodePort | Provide the p2p nodeport for node | 30007 | -| p2p targetPort | Provide the p2p targetPort for node | 30007 | -| rpc port | Provide the tpc port for node | 10008 | -| rpc targetPort | Provide the rpc targetport for node | 10003 | -| rpc nodePort | Provide the rpc nodePort for node | 30007 | -| rpcadmin port | Provide the rpcadmin port for node | 10108 | -| rpcadmin targetPort | Provide the rpcadmin targetport for node | 10005 | -| rpcadmin nodePort | Provide the rpcadmin nodePort for node | 30007 | - -### Vault - -| Name | Description | Default Value | -| ------------------------- | --------------------------------------------------------------------------| ------------------------- | -| address | Address/URL of the Vault server | "" | -| role | Role used for authentication with Vault | vault-role | -| authpath | Authentication path for Vault | cordabank1 | -| serviceAccountName | Provide the already created service account name autheticated to vault | vault-auth-issuer | -| certSecretPrefix | Provide the vault path where the certificates are stored | bank1/certs | -| dbsecretprefix | Provide the secretprefix | bank1/credentials/database | -| rpcusersecretprefix | Provide the secretprefix | bank1/credentials/rpcusers | -| keystoresecretprefix | Provide the secretprefix | bank1/credentials/keystore | -| retires | Provide the no of retires | "" | - -### Healthcheck - -| Name | Description | Default Value | -| ----------------------------| ------------------------------------------------------------------------------| ------------- | -| readinesscheckinterval | Provide the interval in seconds you want to iterate till db to be ready | 5 | -| readinessthreshold | Provide the threshold till you want to check if specified db up and running | 2 | - - - -## Deployment ---- - -To deploy the notary-initial-registration Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-notary-initial-registration/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade,verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-notary-initial-registration -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-notary-initial-registration -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [notary-initial-registration Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-notary-initial-registration), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-notary-initial-registration/templates/_helpers.tpl b/platforms/r3-corda/charts/corda-notary-initial-registration/templates/_helpers.tpl deleted file mode 100644 index 7bf5f530a8e..00000000000 --- a/platforms/r3-corda/charts/corda-notary-initial-registration/templates/_helpers.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{{- define "labels.custom" }} - {{ range $key, $val := $.Values.metadata.labels }} - {{ $key }}: {{ $val }} - {{ end }} -{{- end }} \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-notary-initial-registration/templates/job.yaml b/platforms/r3-corda/charts/corda-notary-initial-registration/templates/job.yaml deleted file mode 100644 index f8a26e74629..00000000000 --- a/platforms/r3-corda/charts/corda-notary-initial-registration/templates/job.yaml +++ /dev/null @@ -1,544 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ .Values.nodeName }}-registration - namespace: {{ .Values.metadata.namespace }} - labels: - app: {{ .Values.nodeName }}-registration - app.kubernetes.io/name: {{ .Values.nodeName }}-registration - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - {{- include "labels.custom" . | nindent 2 }} -spec: - backoffLimit: 6 - template: - metadata: - labels: - app: {{ .Values.nodeName }}-initial-registration - app.kubernetes.io/name: {{ .Values.nodeName }}-registration - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - restartPolicy: "OnFailure" - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: notary-initial-registration - image: {{ .Values.image.containerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - # Setting up enviroment variables required for corda jar - {{- range $.Values.nodeConf.env }} - export {{ .name }}="{{ .value }}" - {{- end }} - rm -rf ${BASE_DIR}/certificates/done.txt - - # Setting up enviroment variables - export DEFAULT_TRUSTSTORE_PASSWORD=`cat /opt/node/creds/default_truststore_cred` - export KEYSTORE_PASSWORD=`cat /opt/node/creds/keystore_cred` - export TRUSTSTORE_PASSWORD=`cat /opt/node/creds/truststore_cred` - export DEFAULT_KEYSTORE_PASSWORD=`cat /opt/node/creds/default_keystore_cred` - - # import self signed tls certificate of doorman and networkmap, since java only trusts certificate signed by well known CA - {{- if .Values.image.privateCertificate }} - yes | keytool -importcert -file {{ $.Values.volume.baseDir }}/certificates/networkmap/networkmap.crt -storepass changeit -alias {{ $.Values.image.networkmapCertAlias }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - yes | keytool -importcert -file {{ $.Values.volume.baseDir }}/certificates/doorman/doorman.crt -storepass changeit -alias {{ $.Values.image.doormanCertAlias }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - {{- end }} - - # command to run corda jar and perform initial-registration - java $JAVA_OPTIONS -jar ${CORDA_HOME}/corda.jar initial-registration --network-root-truststore-password ${DEFAULT_TRUSTSTORE_PASSWORD} --network-root-truststore ${BASE_DIR}/certificates/network-map-truststore.jks --base-directory=${BASE_DIR} - - #changing password of keystore. - keytool -storepasswd -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${DEFAULT_KEYSTORE_PASSWORD} - keytool -storepasswd -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/sslkeystore.jks -storepass ${DEFAULT_KEYSTORE_PASSWORD} - keytool -storepasswd -new ${TRUSTSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/truststore.jks -storepass ${DEFAULT_TRUSTSTORE_PASSWORD} - - #changing password of nodekeystore.jks certificate. - keytool -keypasswd -alias cordaclientca -keypass ${DEFAULT_KEYSTORE_PASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${KEYSTORE_PASSWORD} - keytool -keypasswd -alias identity-private-key -keypass ${DEFAULT_KEYSTORE_PASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${KEYSTORE_PASSWORD} - keytool -keypasswd -alias distributed-notary-private-key -keypass ${DEFAULT_KEYSTORE_PASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/nodekeystore.jks -storepass ${KEYSTORE_PASSWORD} - - #changing password of sslkeystore.jks certificate. - keytool -keypasswd -alias cordaclienttls -keypass ${DEFAULT_KEYSTORE_PASSWORD} -new ${KEYSTORE_PASSWORD} -keystore ${BASE_DIR}/certificates/sslkeystore.jks -storepass ${KEYSTORE_PASSWORD} - - # create dummy file to perform check if last line of the container is executed or not - touch ${BASE_DIR}/certificates/done.txt - volumeMounts: - - name: node-volume - mountPath: "{{ $.Values.volume.baseDir }}" - readOnly: false - - name: certificates - mountPath: "{{ $.Values.volume.baseDir }}/certificates" - readOnly: false - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}/node.conf" - subPath: "node.conf" - readOnly: false - - name: creds - mountPath: "/opt/node/creds" - readOnly: false - - name: store-certs - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: CERTS_SECRET_PREFIX - value: {{ .Values.vault.certsecretprefix }} - - name: JAVA_OPTIONS - value: -Xmx512m - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - - OUTPUT_PATH=${BASE_DIR} - - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - - # perform check if certificates are ready or not, and upload certificate into vault when ready - COUNTER=1 - cd ${BASE_DIR}/certificates - while [ "$COUNTER" -lt {{ $.Values.healthcheck.readinessthreshold }} ] - do - if [ -e nodekeystore.jks ] && [ -e sslkeystore.jks ] && [ -e truststore.jks ] && [ -e done.txt ] - then - echo "found certificates, performing vault put" - (echo '{"data": {"nodekeystore.jks": "'; base64 ${BASE_DIR}/certificates/nodekeystore.jks; echo '"}}') | curl -H "X-Vault-Token: ${VAULT_TOKEN}" -d @- ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/nodekeystore - (echo '{"data": {"sslkeystore.jks": "'; base64 ${BASE_DIR}/certificates/sslkeystore.jks; echo '"}}') | curl -H "X-Vault-Token: ${VAULT_TOKEN}" -d @- ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/sslkeystore - (echo '{"data": {"truststore.jks": "'; base64 ${BASE_DIR}/certificates/truststore.jks; echo '"}}') | curl -H "X-Vault-Token: ${VAULT_TOKEN}" -d @- ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore - # get nodekeystore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/nodekeystore | jq -r 'if .errors then . else . end') - TLS_NODEKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "nodekeystore.jks" ]' 2>&1) - # get sslkeystore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/sslkeystore | jq -r 'if .errors then . else . end') - TLS_SSLKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "sslkeystore.jks" ]' 2>&1) - # get truststore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore | jq -r 'if .errors then . else . end') - TLS_TRUSTSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data[ "truststore.jks" ]' 2>&1) - if [ "$TLS_NODEKEYSTORE" == "null" ] || [ "$TLS_SSLKEYSTORE" == "null" ] || [ "$TLS_TRUSTSTORE" == "null" ] || [[ "$TLS_NODEKEYSTORE" == "parse error"* ]] || [[ "$TLS_SSLKEYSTORE" == "parse error"* ]] || [[ "$TLS_TRUSTSTORE" == "parse error"* ]] - then - echo "certificates write or read fail" - sleep {{ $.Values.healthcheck.readinessthreshold }} - if [ "$COUNTER" -ge {{ $.Values.vault.retries }} ] - then - echo "Retry attempted $COUNTER times, certificates have not been saved" - exit 1 - fi - fi - COUNTER=`expr "$COUNTER" + 1` - fi - done - volumeMounts: - - name: node-volume - mountPath: "{{ $.Values.volume.baseDir }}" - readOnly: false - - name: certificates - mountPath: "{{ $.Values.volume.baseDir }}/certificates" - readOnly: false - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}/node.conf" - subPath: "node.conf" - readOnly: false - initContainers: - - name: init-nodeconf - image : {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: KS_SECRET_PREFIX - value: {{ .Values.vault.keystoresecretprefix }} - - name: DB_SECRET_PREFIX - value: {{ .Values.vault.dbsecretprefix }} - - name: RPCUSER_SECRET_PREFIX - value: {{ .Values.vault.rpcusersecretprefix }} - command: ["/bin/sh","-c"] - args: - - |- - #!/bin/bash - # delete previously created node.conf, and create a new node.conf - rm -f ${BASE_DIR}/node.conf; - touch ${BASE_DIR}/node.conf; - - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - - # save keyStorePassword & trustStorePassword from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - CONF_KEYSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["defaultKeyStorePassword"]') - CONF_TRUSTSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["defaultTrustStorePassword"]') - - # save dataSourceUserPassword from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - CONF_DATASOURCEPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["{{ .Values.credentials.dataSourceUser }}"]') - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${RPCUSER_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - - #For more information for node.Conf fields please refer to: https://docs.corda.r3.com/releases/4.0/corda-configuration-file.html - cat << EOF > ${BASE_DIR}/node.conf - p2pAddress : "{{ .Values.nodeConf.p2p.url }}:{{ .Values.nodeConf.p2p.port }}" - myLegalName : "{{ .Values.nodeConf.legalName }}" - keyStorePassword : "${CONF_KEYSTOREPASSWORD}" - trustStorePassword : "${CONF_TRUSTSTOREPASSWORD}" - transactionCacheSizeMegaBytes : {{ .Values.nodeConf.transactionCacheSizeMegaBytes }} - attachmentContentCacheSizeMegaBytes : {{ .Values.nodeConf.attachmentContentCacheSizeMegaBytes }} - notary : { - serviceLegalName : "{{ .Values.nodeConf.notary.serviceLegalName }}" - validating : {{ .Values.nodeConf.notary.validating }} - } - detectPublicIp = {{ .Values.nodeConf.detectPublicIp }} - additionalP2PAddresses = ["{{ .Values.nodeConf.ambassadorAddress }}"] - devMode : {{ .Values.nodeConf.devMode }} - dataSourceProperties = { - dataSourceClassName = "{{ .Values.nodeConf.dataSourceClassName }}" - dataSource.url = "{{ .Values.nodeConf.dataSourceUrl }}" - dataSource.user = {{ .Values.credentials.dataSourceUser }} - dataSource.password = "${CONF_DATASOURCEPASSWORD}" - } - database = { - exportHibernateJMXStatistics = {{ .Values.nodeConf.database.exportHibernateJMXStatistics }} - } - jarDirs = ["{{ .Values.nodeConf.jarPath }}"] - EOF - - if [ -z "{{ .Values.nodeConf.compatibilityZoneURL }}" ] - then - echo 'networkServices = { - doormanURL = "{{ .Values.nodeConf.doormanURL }}" - networkMapURL = "{{ .Values.nodeConf.networkMapURL }}" - }' >> ${BASE_DIR}/node.conf - else - echo 'compatibilityZoneURL : "{{ .Values.nodeConf.compatibilityZoneURL }}"' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.jvmArgs }}" ] - then - echo 'jvmArgs is not configured' - else - echo 'jvmArgs = "{{ .Values.nodeConf.jvmArgs }}" ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.sshd.port }}" ] - then - echo 'sshd port is not configured' - else - echo 'sshd { port = {{ .Values.nodeConf.sshd.port }} } ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.systemProperties }}" ] - then - echo 'systemProperties is not configured' - else - echo 'systemProperties = {{ .Values.nodeConf.systemProperties }} ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.exportJMXTo }}" ] - then - echo 'exportJMXTo is not configured' - else - echo 'exportJMXTo = {{ .Values.nodeConf.exportJMXTo }} ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.messagingServerAddress }}" ] - then - echo 'The address of the ArtemisMQ broker instance is not configured' - else - echo 'messagingServerAddress : "{{ .Values.nodeConf.messagingServerAddress }}" ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.credentials.rpcUser }}" ] - then - echo 'rpc useer is not configured' - else - echo 'rpcUsers : [' >> ${BASE_DIR}/node.conf - {{- range $.Values.credentials.rpcUser }} - echo '{ username={{ .name }} ,permissions={{ .permissions }}, ' >> ${BASE_DIR}/node.conf - echo " password=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["{{ .name }}"]') }" >> ${BASE_DIR}/node.conf - {{- end }} - echo ']' >> ${BASE_DIR}/node.conf - fi - - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - if [ "{{ .Values.nodeConf.rpcSettings.useSsl }}" == true ] - then - echo "rpcSettings { - standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} - address = "{{ .Values.nodeConf.rpcSettings.address }}" - adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" - useSsl = {{ .Values.nodeConf.rpcSettings.useSsl }} - ssl = { - keyStorePassword = $(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["sslkeyStorePassword"]') - trustStorePassword = $(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["ssltrustStorePassword"]') - certificatesDirectory = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }} - sslKeystore = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.sslKeystoreFileName }} - trustStoreFile = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.trustStoreFileName }} - } - }" >> ${BASE_DIR}/node.conf - else - echo 'rpcSettings { - standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} - address = "{{ .Values.nodeConf.rpcSettings.address }}" - adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" - }' >> ${BASE_DIR}/node.conf - fi - echo "node.conf created in ${BASE_DIR}" - volumeMounts: - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}" - - name: init-certificates - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: CERTS_SECRET_PREFIX - value: {{.Values.vault.certsecretprefix}} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - # To check if custom nodekeystore is retrived from vault, if yes then store it in nodekeystore.jks - validateVaultResponseCustomnodeKeystore () { - if echo ${2} | grep "errors"; - then - echo "custom nodekeystore.jks is not provided and new one will be created." - else - echo "Found custom nodekeystore.jks" - echo "${NODE_KEY}" | base64 -d > ${OUTPUT_PATH}/nodekeystore.jks - fi - } - - # To check if certificates are already present in vault or not - validateVaultResponseKeystore () { - if echo ${2} | grep "errors"; - then - echo "Initial registration will create keystore ${1}" - else - echo "Initial registration was performed before." - exit 1 - fi - } - - # setting up env to get secrets from vault - echo "Getting secrets from Vault Server" - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${BASE_DIR} - - # get customnodekeystore from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/customnodekeystore ) - NODE_KEY=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["nodekeystore.jks"]') - validateVaultResponseCustomnodeKeystore "secret (${CERTS_SECRET_PREFIX}/customnodekeystore)" "${LOOKUP_SECRET_RESPONSE}" - - # get network-map-truststore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/networkmaptruststore | jq -r 'if .errors then . else . end') - validateVaultResponse "secret (${CERTS_SECRET_PREFIX}/networkmaptruststore)" "${LOOKUP_SECRET_RESPONSE}" - TLS_NMS=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["network-map-truststore"]') - echo "${TLS_NMS}" | base64 -d > ${OUTPUT_PATH}/network-map-truststore.jks - - # To check if sslkeystore,nodekeystore,truststore are present in vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/nodekeystore | jq -r 'if .errors then . else . end') - validateVaultResponseKeystore "secret on (${CERTS_SECRET_PREFIX}/nodekeystore)" "${LOOKUP_SECRET_RESPONSE}" - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/sslkeystore | jq -r 'if .errors then . else . end') - validateVaultResponseKeystore "secret on (${CERTS_SECRET_PREFIX}/sslkeystore)" "${LOOKUP_SECRET_RESPONSE}" - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore | jq -r 'if .errors then . else . end') - validateVaultResponseKeystore "secret on (${CERTS_SECRET_PREFIX}/truststore)" "${LOOKUP_SECRET_RESPONSE}" - - # when using doorman and networkmap in TLS: true, and using private certificate then download certificate - if [ "{{ .Values.image.privateCertificate }}" == true ] - then - mkdir -p ${OUTPUT_PATH}/networkmap - mkdir -p ${OUTPUT_PATH}/doorman - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/networkmap | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/networkmap" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - NETWORKMAP_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["networkmap.crt"]') - echo "${NETWORKMAP_CRT}" | base64 -d > ${OUTPUT_PATH}/networkmap/networkmap.crt - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/doorman | jq -r 'if .errors then . else . end') - validateVaultResponse "secret (${CERTS_SECRET_PREFIX}/doorman)" "${LOOKUP_SECRET_RESPONSE}" - DOORMAN_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["doorman.crt"]') - echo "${DOORMAN_CRT}" | base64 -d > ${OUTPUT_PATH}/doorman/doorman.crt - fi - chmod 777 -R ${BASE_DIR}/; - echo "Done" - volumeMounts: - - name: certificates - mountPath: {{ $.Values.volume.baseDir }} - - name: init-credential - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{.Values.vault.address}} - - name: KUBERNETES_AUTH_PATH - value: {{.Values.vault.authpath}} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: BASE_DIR - value: /opt/node/creds - - name: KS_SECRET_PREFIX - value: {{ .Values.vault.keystoresecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${BASE_DIR} - - # get keystore passwords from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - validateVaultResponse "${KS_SECRET_PREFIX}" "${LOOKUP_PWD_RESPONSE}" "LOOKUPSECRETRESPONSE" - DEFAULT_TRUSTSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["defaultTrustStorePassword"]') - DEFAULT_KEYSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["defaultKeyStorePassword"]') - KEYSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["keyStorePassword"]') - TRUSTSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["trustStorePassword"]') - echo "${DEFAULT_TRUSTSTOREPASSWORD}" >> ${BASE_DIR}/default_truststore_cred - echo "${KEYSTOREPASSWORD}" >> ${BASE_DIR}/keystore_cred - echo "${TRUSTSTOREPASSWORD}" >> ${BASE_DIR}/truststore_cred - echo "${DEFAULT_KEYSTOREPASSWORD}" >> ${BASE_DIR}/default_keystore_cred - - echo "Done" - volumeMounts: - - name: creds - mountPath: "/opt/node/creds" - readOnly: false - - name: db-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - # perform health check if db is up and running before starting corda node - while [ "$COUNTER" -le {{ $.Values.healthcheck.readinessthreshold }} ] - do - DB_NODE={{ .Values.nodeConf.dbUrl }}:{{ .Values.nodeConf.dbPort }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.healthcheck.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - - if [ "$COUNTER" -gt {{ $.Values.healthcheck.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: node-volume - emptyDir: - medium: Memory - - name: certificates - emptyDir: - medium: Memory - - name: nodeconf - emptyDir: - medium: Memory - - name: creds - emptyDir: - medium: Memory \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-notary-initial-registration/values.yaml b/platforms/r3-corda/charts/corda-notary-initial-registration/values.yaml deleted file mode 100644 index eef0caeeba6..00000000000 --- a/platforms/r3-corda/charts/corda-notary-initial-registration/values.yaml +++ /dev/null @@ -1,204 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -#Provide the nodeName for node -#Eg. nodeName: bank1 -nodeName: bank1 - -#Provide the replica set for node deployed -#Eg. replicas: 1 -replicas: - -metadata: - #Provide the namespace - #Eg. namespace: default - namespace: default - #Provide the custom labels - #NOTE: Provide labels other than name, release name , release service, chart version , chart name , app. - #Eg. labels: - # role: create_channel - labels: - -image: - #Provide the containerName of image - #Eg. containerName: ghcr.io/hyperledger/bevel-corda:4.9 - containerName: ghcr.io/hyperledger/bevel-corda:4.9 - #Provide the name of image for init container - #Eg. name: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: "" - #Provide true or false if private certificate to be added - #Eg. privateCertificate: true - privateCertificate: true - #Provide doorman domain alias - #Eg. doormanCertAlias: doorman.fracordakubetest7.com - doormanCertAlias: doorman.fracordakubetest7.com - #Provide networkmap domain alias - #Eg. networkmapCertAlias: networkmap.fracordakubetest7.com - networkmapCertAlias: networkmap.fracordakubetest7.com - - -#For more information for node.Conf fields please refer to: https://docs.corda.net/releases/release-V3.3/corda-configuration-file.html -nodeConf: - #The host and port on which the node is available for protocol operations over ArtemisMQ. - p2p: - url: - port: - #Specify the ambassador host:port which will be advertised in addition to p2paddress - ambassadorAddress: - rpcSettings: - useSsl: - standAloneBroker: - address: - adminAddress: - ssl: - certificatesDirectory: - sslKeystorePath: - trustStoreFilePath: - #Provide the legalName for node - #Eg. legalName: "O=Bank1,L=London,C=GB,CN=Bank1" - legalName: - messagingServerAddress: - jvmArgs: - systemProperties: - sshd: - port: - exportJMXTo: - transactionCacheSizeMegaBytes: - attachmentContentCacheSizeMegaBytes: - notary: - validating: - serviceLegalName: - detectPublicIp: - database: - exportHibernateJMXStatistics: - #Provide the h2Url for node - #Eg. h2Url: bank1h2 - dbUrl: bank1h2 - #Provide the h2Port for node - #Eg. h2Port: 9101 - dbPort: 9101 - dataSourceClassName: - dataSourceUrl: - jarPath: - #Provide the nms for node - #Eg. nms: "http://rp-elb-fra-corda-kube-cluster7-2016021309.us-west-1.elb.amazonaws.com:30050" - networkMapURL: - doormanURL: - # compatibilityZoneURL is for NMS only implementation - compatibilityZoneURL: - #Provide the jar Version for corda jar and finanace jar - #Eg. jarVersion: 3.3-corda - jarVersion: 3.3-corda - #Provide the devMode for corda node - #Eg. devMode: true - devMode: true - #Provide the enviroment variables to be set - env: - - name: JAVA_OPTIONS - value: - - name: CORDA_HOME - value: - - name: BASE_DIR - value: - -credentials: - #Provide the dataSourceUser for corda node - #Eg. dataSourceUser: - dataSourceUser: - #Provide the rpcUser for corda node - rpcUser: - - name: bank1operations - permissions: [ALL] - -volume: - #Provide the base path - #Eg. mountPath: "/opt/h2-data" - baseDir: - -resources: - #Provide the limit memory for node - #Eg. limits: "1Gi" - limits: "1Gi" - #Provide the requests memory for node - #Eg. requests: "1Gi" - requests: "1Gi" - -service: -# Note: Target ports are dependent on image being used. Please change them accordingly -# nodePort should be kept empty while using service type as ClusterIP ( Values.service.type ) - #Provide the type of service - #Eg. type: NodePort or LoadBalancer etc - type: NodePort - p2p: - #Provide the p2p port for node - #Eg. port: 10007 - port: 10007 - #Provide the p2p node port for node - #Eg. port: 30007 - nodePort: - #Provide the p2p targetPort for node - #Eg. targetPort: 30007 - targetPort: 30007 - rpc: - #Provide the rpc port for node - #Eg. port: 10008 - port: 10008 - #Provide the rpc targetPort for node - #Eg. targetPort: 10003 - targetPort: 10003 - #Provide the rpc node port for node - #Eg. nodePort: 10003 - nodePort: - rpcadmin: - #Provide the rpcadmin port for node - #Eg. port: 10108 - port: 10108 - #Provide the rpcadmin targetPort for node - #Eg. targetPort: 10005 - targetPort: 10005 - #Provide the rpcadmin node port for node - #Eg. nodePort: 30007 - nodePort: - -vault: - #Provide the vault server address - #Eg. address: http://54.226.163.39:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: vault-role - #Provide the authpath - #Eg. authpath: cordabank1 - authpath: cordabank1 - #Provide the serviceaccountname - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: vault-auth-issuer - #Provide the secretprefix - #Eg. dbsecretprefix: bank1/credentials/database - dbsecretprefix: bank1/credentials/database - #Provide the secretprefix - #Eg. rpcusersecretprefix: bank1/credentials/rpcusers - rpcusersecretprefix: bank1/credentials/rpcusers - #Provide the secretprefix - #Eg. keystoresecretprefix: bank1/credentials/keystore - keystoresecretprefix: bank1/credentials/keystore - #Provide the secretprefix - #Eg. certsecretprefix: bank1/certs - certsecretprefix: bank1/certs - # Number of retries to check contents from vault -  retries: - -healthcheck: - #Provide the interval in seconds you want to iterate till db to be ready - #Eg. readinesscheckinterval: 5 - readinesscheckinterval: 5 - #Provide the threshold till you want to check if specified db up and running - #Eg. readinessthreshold: 2 - readinessthreshold: 2 diff --git a/platforms/r3-corda/charts/corda-notary/Chart.yaml b/platforms/r3-corda/charts/corda-notary/Chart.yaml deleted file mode 100644 index 2324c43e17e..00000000000 --- a/platforms/r3-corda/charts/corda-notary/Chart.yaml +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -appVersion: "2.0" -description: "R3-corda-os: Deploys the notary node." -name: corda-notary -version: 1.0.0 diff --git a/platforms/r3-corda/charts/corda-notary/README.md b/platforms/r3-corda/charts/corda-notary/README.md deleted file mode 100644 index eaf7b56af35..00000000000 --- a/platforms/r3-corda/charts/corda-notary/README.md +++ /dev/null @@ -1,249 +0,0 @@ -[//]: # (##############################################################################################) -[//]: # (Copyright Accenture. All Rights Reserved.) -[//]: # (SPDX-License-Identifier: Apache-2.0) -[//]: # (##############################################################################################) - - -# Notary Deployment - -- [Notary Deployment Helm Chart](#Notary-deployment-helm-chart) -- [Prerequisites](#prerequisites) -- [Chart Structure](#chart-structure) -- [Configuration](#configuration) -- [Deployment](#deployment) -- [Contributing](#contributing) -- [License](#license) - - - -## Notary Deployment Helm Chart ---- -This [Helm chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-notary) helps to deploy the r3corda notory node. - - - -## Prerequisites ---- -Before deploying the chart please ensure you have the following prerequisites: - -- NetworkMap and Node's database up and running. -- Kubernetes cluster up and running. -- A HashiCorp Vault instance is set up and configured to use Kubernetes service account token-based authentication. -- The Vault is unsealed and initialized. -- Helm is installed. - -This chart has following structure: -``` - - ├── notary - │   ├── Chart.yaml - │   ├── templates - │   │   ├── deployment.yaml - │   │   ├── _helpers.tpl - │   │   ├── pvc.yaml - │   │   └── service.yaml - │   └── values.yaml -``` - -Type of files used: - -- `templates` : This directory contains the Kubernetes manifest templates that define the resources to be deployed. -- `deployment.yaml`: This file is a configuration file for deployement in Kubernetes.It creates a deployment file with a specified number of replicas and defines various settings for the deployment, Init container is responsible for node registration process is completed successfully before the main containers start.It also specifies volume mounts for storing certificates and data. -- `pvc.yaml` : A PersistentVolumeClaim (PVC) is a request for storage by a user. -- `service.yaml` : This file defines a Kubernetes Service with multiple ports for protocols and targets, and supports Ambassador proxy annotations for specific configurations when using the "ambassador" proxy provider. -- `chart.yaml` : Provides metadata about the chart, such as its name, version, and description. -- `values.yaml` : Contains the default configuration values for the chart. It includes configuration for the image, nodeconfig, credenatials, storage, service , vault, etc. -- `_helpers.tpl` : A template file used for defining custom labels and ports for the metrics in the Helm chart. - - - -## Configuration ---- -The [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-notary/values.yaml) file contains configurable values for the Helm chart. We can modify these values according to the deployment requirements. Here are some important configuration options: - -## Parameters ---- - -### Name - -| Name | Description | Default Value | -| -----------| -------------------------------------------------- | ------------- | -| name | Provide the name of the node | bank1 | - -### Metadata - -| Name | Description | Default Value | -| ----------------| -------------------------------------------------------------| ------------- | -| namespace | Provide the namespace for the Notary Generator | default | -| labels | Provide any additional labels for the Notary Generator | "" | - -### Image - -| Name | Description | Default Value | -| ------------------------ | --------------------------------------------------------------------------------------- | --------------- | -| initContainerName | Provide the alpine utils image, which is used for all init-containers of deployments/jobs | "" | -| containerName | Provide the containerName of image | "" | -| imagePullSecret | Provide the image pull secret of image | regcred | -| privateCertificate | Provide true or false if private certificate to be added | "true" | -| doormanCertAlias | Provide true or false if private certificate to be added | "" | -| networkmapCertAlias | Provide true or false if private certificate to be added | "" | - -### NodeConf - -| Name | Description | Default Value | -| ------------------------ | -------------------------------------------------------------------------------------- | --------------- | -| p2p | The host and port on which the node is available for protocol operations over ArtemisMQ | "" | -| ambassadorAddress | Specify ambassador host:port which will be advertised in addition to p2paddress | "" | -| legalName | Provide the legalName for node | "" | -| dbUrl | Provide the h2Url for node | "bank1h2" | -| dbPort | Provide the h2Port for node | "9101" | -| networkMapURL | Provide the nms for node | "" | -| doormanURL | Provide the doorman for node | "" | -| jarVersion | Provide the jar Version for corda jar and finanace jar | "3.3-corda" | -| devMode | Provide the devMode for corda node | "true" | -| env | Provide the enviroment variables to be set | "" | - -### credentials - -| Name | Description | Default Value | -| ----------------| ----------------------------------------------| ------------- | -| dataSourceUser | Provide the dataSourceUser for corda node | "" | -| rpcUser | Provide the rpcUser for corda node | bank1operations| - -### cordapps - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| getcordapps | Provide if you want to provide jars in cordapps | "" | -| repository | Provide the repository of cordapps | "" | -| jars url | Provide url to download the jar using wget cmd | "" | - -### Volume - -| Name | Description | Default Value | -| -----------------| -----------------------| ------------- | -| baseDir | Base directory | /home/bevel | - -### Resources - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| limits | Provide the limit memory for node | "1Gi" | -| requests | Provide the requests memory for node | "1Gi" | - -### PVC - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | --------------- | -| name | Provide the name for pvc | bank1-pvc | -| memory | Provide the memory for node | "4Gi" | -| storageClassName | Provide the name for the storageclass | bank1nodesc | - -### Service - -| Name | Description | Default Value | -| --------------------- | ------------------------------------------| ------------- | -| service Name | Provide the service | bank1 | -| type | Provide the type of service | NodePort | -| p2p port | Provide the tcp port for node | 10007 | -| p2p nodePort | Provide the p2p nodeport for node | 30007 | -| p2p targetPort | Provide the p2p targetPort for node | 30007 | -| rpc port | Provide the tpc port for node | 10008 | -| rpc targetPort | Provide the rpc targetport for node | 10003 | -| rpc nodePort | Provide the rpc nodePort for node | 30007 | -| rpcadmin port | Provide the rpcadmin port for node | 10108 | -| rpcadmin targetPort | Provide the rpcadmin targetport for node | 10005 | -| rpcadmin nodePort | Provide the rpcadmin nodePort for node | 30007 | - -### Vault - -| Name | Description | Default Value | -| ------------------------- | --------------------------------------------------------------------------| ------------------------- | -| address | Address/URL of the Vault server | "" | -| role | Role used for authentication with Vault | vault-role | -| authpath | Authentication path for Vault | cordabank1 | -| serviceAccountName | Provide the already created service account name autheticated to vault | vault-auth-issuer | -| certSecretPrefix | Provide the vault path where the certificates are stored | bank1/certs | -| dbsecretprefix | Provide the secretprefix | bank1/credentials/database | -| rpcusersecretprefix | Provide the secretprefix | bank1/credentials/rpcusers | -| keystoresecretprefix | Provide the secretprefix | bank1/credentials/keystore | -| cordappsreposecretprefix | Provide the secretprefix | bank1/credentials/cordapps | - -### Healthcheck - -| Name | Description | Default Value | -| ----------------------------| ------------------------------------------------------------------------------| ------------- | -| readinesscheckinterval | Provide the interval in seconds you want to iterate till db to be ready | 5 | -| readinessthreshold | Provide the threshold till you want to check if specified db up and running | 2 | - -### ambassador - -| Name | Description | Default Value | -| ------------------------ | ------------------------------------------------------- | -------------------------- | -| component_name | Provides component name | node | -| external_url_suffix | Provides the suffix to be used in external URL | org1.blockchaincloudpoc.com | -| p2p_ambassador | Provide the p2p port for ambassador | 10007 | - - - -## Deployment ---- - -To deploy the notary Helm chart, follow these steps: - -1. Modify the [values.yaml](https://github.com/hyperledger/bevel/blob/develop/platforms/r3-corda/charts/corda-notary/values.yaml) file to set the desired configuration values. -2. Run the following Helm command to install, upgrade,verify, delete the chart: - -To install the chart: -```bash -helm repo add bevel https://hyperledger.github.io/bevel/ -helm install ./corda-notary -``` - -To upgrade the chart: -```bash -helm upgrade ./corda-notary -``` - -To verify the deployment: -```bash -kubectl get jobs -n -``` -Note : Replace `` with the actual namespace where the Job was created. This command will display information about the Job, including the number of completions and the current status of the Job's pods. - -To delete the chart: -```bash -helm uninstall -``` -Note : Replace `` with the desired name for the release. - - - -## Contributing ---- -If you encounter any bugs, have suggestions, or would like to contribute to the [notary Deployment Helm Chart](https://github.com/hyperledger/bevel/tree/develop/platforms/r3-corda/charts/corda-notary), please feel free to open an issue or submit a pull request on the [project's GitHub repository](https://github.com/hyperledger/bevel). - - -## License - -This chart is licensed under the Apache v2.0 license. - -Copyright © 2023 Accenture - -### Attribution - -This chart is adapted from the [charts](https://hyperledger.github.io/bevel/) which is licensed under the Apache v2.0 License which is reproduced here: - -``` -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. -``` diff --git a/platforms/r3-corda/charts/corda-notary/templates/_helpers.tpl b/platforms/r3-corda/charts/corda-notary/templates/_helpers.tpl deleted file mode 100644 index 7bf5f530a8e..00000000000 --- a/platforms/r3-corda/charts/corda-notary/templates/_helpers.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{{- define "labels.custom" }} - {{ range $key, $val := $.Values.metadata.labels }} - {{ $key }}: {{ $val }} - {{ end }} -{{- end }} \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-notary/templates/deployment.yaml b/platforms/r3-corda/charts/corda-notary/templates/deployment.yaml deleted file mode 100644 index c21279777ae..00000000000 --- a/platforms/r3-corda/charts/corda-notary/templates/deployment.yaml +++ /dev/null @@ -1,617 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.nodeName }} - {{- if .Values.deployment.annotations }} - annotations: -{{ toYaml .Values.deployment.annotations | indent 8 }} - {{- end }} - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.nodeName }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - {{- include "labels.custom" . | nindent 2 }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - strategy: - type: Recreate - rollingUpdate: null - template: - metadata: - labels: - app: {{ .Values.nodeName }} - app.kubernetes.io/name: {{ .Values.nodeName }} - app.kubernetes.io/instance: {{ .Release.Name }} - spec: - serviceAccountName: {{ $.Values.vault.serviceaccountname }} - hostname: {{ .Values.nodeName }} - securityContext: - fsGroup: 1000 - containers: - - name: notary - image: {{ .Values.image.containerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - - # Setting up enviroment variables required for corda jar - {{- range $.Values.nodeConf.env }} - export {{ .name }}="{{ .value }}" - {{- end }} - - # import self signed tls certificate of doorman and networkmap, since java only trusts certificate signed by well known CA - {{- if .Values.image.privateCertificate }} - yes | keytool -importcert -file {{ $.Values.volume.baseDir }}/certificates/networkmap/networkmap.crt -storepass changeit -alias {{ $.Values.image.networkmapCertAlias }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - yes | keytool -importcert -file {{ $.Values.volume.baseDir }}/certificates/doorman/doorman.crt -storepass changeit -alias {{ $.Values.image.doormanCertAlias }} -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts - {{- end }} - - # to clean network-parameters on every restart - rm -rf ${BASE_DIR}/network-parameters - - # Run schema migration scripts for corDApps - java -Djavax.net.ssl.keyStore=${BASE_DIR}/certificates/sslkeystore.jks -Djavax.net.ssl.keyStorePassword=newpass $JAVA_OPTIONS -jar ${CORDA_HOME}/corda.jar run-migration-scripts --core-schemas --app-schemas --base-directory=${BASE_DIR} - # command to run corda jar, we are setting javax.net.ssl.keyStore as ${BASE_DIR}/certificates/sslkeystore.jks since keystore gets reset when using h2 ssl - java -Djavax.net.ssl.keyStore=${BASE_DIR}/certificates/sslkeystore.jks -Djavax.net.ssl.keyStorePassword=newpass $JAVA_OPTIONS -jar ${CORDA_HOME}/corda.jar --base-directory=${BASE_DIR} - resources: - limits: - memory: {{ .Values.resources.limits }} - requests: - memory: {{ .Values.resources.requests }} - ports: - - containerPort: {{ .Values.service.p2p.targetPort }} - name: p2p - - containerPort: {{ .Values.service.rpc.targetPort }} - name: rpc - - containerPort: {{ .Values.service.rpcadmin.targetPort }} - name: rpcadmin - volumeMounts: - - name: notary-volume - mountPath: "{{ $.Values.volume.baseDir }}" - readOnly: false - - name: certificates - mountPath: "{{ $.Values.volume.baseDir }}/certificates" - readOnly: false - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}/node.conf" - subPath: "node.conf" - readOnly: false - livenessProbe: - tcpSocket: - port: {{ .Values.service.p2p.targetPort }} - initialDelaySeconds: 65 - periodSeconds: 30 - - name: corda-logs - image: {{ .Values.image.initContainerName }} - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: VAULT_NODE_NAME - value: {{ .Values.nodeName }} - - name: SECRET_PREFIX - value: {{.Values.vault.networkmapsecretprefix}} - - name: NMS_USER_ID - value: {{.Values.credentials.dataSourceUser}} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - {{- range $.Values.nodeConf.env }} - export {{ .name }}="{{ .value }}" - {{- end }} - COUNTER=0 - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - - # save networkmap login passwoed from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${SECRET_PREFIX} | jq -r 'if .errors then . else . end') - NMS_USER_PASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["sa"]') - - STATUS=0 - - while [ "$STATUS" -ne 1 ] - do - # get node-info file name - cd ${BASE_DIR} - NOTARYNODEINFOFILENAME=$(ls ${BASE_DIR}/ | grep nodeInfo | awk '{print $1}'); - echo "NOTARYNODEINFOFILENAME=$NOTARYNODEINFOFILENAME" - if [ -z $NOTARYNODEINFOFILENAME ] - then - echo "node-info file not ready, sleeping for 10s" - sleep 10 - STATUS=0 - - else - # get url for registration - if [ -z "{{ .Values.nodeConf.compatibilityZoneURL }}" ] - then - url={{ .Values.nodeConf.networkMapURL }} - else - url={{ .Values.nodeConf.compatibilityZoneURL }} - fi - - # check if notary type is validating or non validating, and form url accordingly - if [ {{ .Values.nodeConf.notary.validating }} == "true" ] - then - section=/admin/api/notaries/validating - else - section=/admin/api/notaries/nonValidating - fi - - # get one time login token from networkmap - token=$(curl -k --silent --show-error -X POST "$url/admin/api/login" -H "accept: text/plain" -H "Content-Type: application/json" -d "{ \"user\": \"${NMS_USER_ID}\", \"password\": \"${NMS_USER_PASSWORD}\"}" | awk '{print $1}'); - - # curl command to register notary, if resonse is okay then registration is sucessfull - cd ${BASE_DIR} - - response=$(curl -k --silent --show-error -X POST -H "Authorization: Bearer ${token}" -H "accept: text/plain" -H "Content-Type: application/octet-stream" --data-binary @${NOTARYNODEINFOFILENAME} ${url}${section} | awk '{print $1}') - echo "responsevar=$response" - if [ $response = "OK" ] - then - echo "Response is OK"; - echo "Registered notary with Networkmap successfully" - else - echo "Response from NMS is not ok"; - echo "Something went wrong" - fi - - STATUS=1 - break - fi - done - if [ -e ${BASE_DIR}/logs/node-{{ .Values.nodeName }}.log ] - then - clear - tail -f ${BASE_DIR}/logs/node-{{ .Values.nodeName }}.log - else - echo "waiting for corda to generate log, sleeping for 10s" - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - fi - volumeMounts: - - name: notary-volume - mountPath: "{{ $.Values.volume.baseDir }}" - readOnly: false - initContainers: - - name: init-checkregistration - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: CERTS_SECRET_PREFIX - value: {{ .Values.vault.certsecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - - # setting up env to get secrets from vault - echo "Getting secrets from Vault Server" - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - echo "logged into vault" - - COUNTER=1 - while [ "$COUNTER" -lt {{ $.Values.healthcheck.readinessthreshold }} ] - do - # get truststore from vault to see if registration is done or not - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore | jq -r 'if .errors then . else . end') - if echo ${LOOKUP_SECRET_RESPONSE} | grep "errors" - then - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - break - fi - COUNTER=`expr "$COUNTER" + 1` - done - - if [ "$COUNTER" -ge {{ $.Values.healthcheck.readinessthreshold }} ] - then - # printing number of trial done before giving up - echo "$COUNTER" - echo "Node registration might not have been done." - exit 1 - fi - echo "Done" - - name: init-nodeconf - image : {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: KS_SECRET_PREFIX - value: {{ .Values.vault.keystoresecretprefix }} - - name: DB_SECRET_PREFIX - value: {{ .Values.vault.dbsecretprefix }} - - name: RPCUSER_SECRET_PREFIX - value: {{ .Values.vault.rpcusersecretprefix }} - command: ["/bin/sh","-c"] - args: - - |- - #!/bin/bash - # delete previously created node.conf, and create a new node.conf - rm -f ${BASE_DIR}/node.conf; - touch ${BASE_DIR}/node.conf; - - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - - # save keyStorePassword & trustStorePassword from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - CONF_KEYSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["keyStorePassword"]') - CONF_TRUSTSTOREPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["trustStorePassword"]') - - # save dataSourceUserPassword from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${DB_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - CONF_DATASOURCEPASSWORD=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["{{ .Values.credentials.dataSourceUser }}"]') - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${RPCUSER_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - - #For more information for node.Conf fields please refer to: https://docs.corda.r3.com/releases/4.0/corda-configuration-file.html - cat << EOF > ${BASE_DIR}/node.conf - p2pAddress : "{{ .Values.nodeConf.p2p.url }}:{{ .Values.nodeConf.p2p.port }}" - myLegalName : "{{ .Values.nodeConf.legalName }}" - keyStorePassword : "${CONF_KEYSTOREPASSWORD}" - trustStorePassword : "${CONF_TRUSTSTOREPASSWORD}" - transactionCacheSizeMegaBytes : {{ .Values.nodeConf.transactionCacheSizeMegaBytes }} - attachmentContentCacheSizeMegaBytes : {{ .Values.nodeConf.attachmentContentCacheSizeMegaBytes }} - notary : { - serviceLegalName : "{{ .Values.nodeConf.notary.serviceLegalName }}" - validating : {{ .Values.nodeConf.notary.validating }} - } - detectPublicIp = {{ .Values.nodeConf.detectPublicIp }} - additionalP2PAddresses = ["{{ .Values.nodeConf.ambassadorAddress }}"] - devMode : {{ .Values.nodeConf.devMode }} - dataSourceProperties = { - dataSourceClassName = "{{ .Values.nodeConf.dataSourceClassName }}" - dataSource.url = "{{ .Values.nodeConf.dataSourceUrl }}" - dataSource.user = {{ .Values.credentials.dataSourceUser }} - dataSource.password = "${CONF_DATASOURCEPASSWORD}" - } - database = { - exportHibernateJMXStatistics = {{ .Values.nodeConf.database.exportHibernateJMXStatistics }} - } - jarDirs = [{{ .Values.nodeConf.jarPath }}] - EOF - if [ -z "{{ .Values.nodeConf.compatibilityZoneURL }}" ] - then - echo 'networkServices = { - doormanURL = "{{ .Values.nodeConf.doormanURL }}" - networkMapURL = "{{ .Values.nodeConf.networkMapURL }}" - }' >> ${BASE_DIR}/node.conf - else - echo 'compatibilityZoneURL : "{{ .Values.nodeConf.compatibilityZoneURL }}"' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.jvmArgs }}" ] - then - echo 'jvmArgs is not configured' - else - echo 'jvmArgs = "{{ .Values.nodeConf.jvmArgs }}" ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.sshd.port }}" ] - then - echo 'sshd port is not configured' - else - echo 'sshd { port = {{ .Values.nodeConf.sshd.port }} } ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.systemProperties }}" ] - then - echo 'systemProperties is not configured' - else - echo 'systemProperties = {{ .Values.nodeConf.systemProperties }} ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.exportJMXTo }}" ] - then - echo 'exportJMXTo is not configured' - else - echo 'exportJMXTo = {{ .Values.nodeConf.exportJMXTo }} ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.nodeConf.messagingServerAddress }}" ] - then - echo 'The address of the ArtemisMQ broker instance is not configured' - else - echo 'messagingServerAddress : "{{ .Values.nodeConf.messagingServerAddress }}" ' >> ${BASE_DIR}/node.conf - fi - - if [ -z "{{ .Values.credentials.rpcUser }}" ] - then - echo 'rpc useer is not configured' - else - echo 'rpcUsers : [' >> ${BASE_DIR}/node.conf - {{- range $.Values.credentials.rpcUser }} - echo '{ username={{ .name }} ,permissions={{ .permissions }}, ' >> ${BASE_DIR}/node.conf - echo " password=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["{{ .name }}"]') }" >> ${BASE_DIR}/node.conf - {{- end }} - echo ']' >> ${BASE_DIR}/node.conf - fi - - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${KS_SECRET_PREFIX} | jq -r 'if .errors then . else . end') - if [ "{{ .Values.nodeConf.rpcSettings.useSsl }}" == true ] - then - echo "rpcSettings { - standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} - address = "{{ .Values.nodeConf.rpcSettings.address }}" - adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" - useSsl = {{ .Values.nodeConf.rpcSettings.useSsl }} - ssl = { - keyStorePassword = $(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["sslkeyStorePassword"]') - trustStorePassword = $(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["ssltrustStorePassword"]') - certificatesDirectory = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }} - sslKeystore = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.sslKeystoreFileName }} - trustStoreFile = ${BASE_DIR}/{{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }}/{{ .Values.nodeConf.rpcSettings.ssl.trustStoreFileName }} - } - }" >> ${BASE_DIR}/node.conf - else - echo 'rpcSettings { - standAloneBroker = {{ .Values.nodeConf.rpcSettings.standAloneBroker }} - address = "{{ .Values.nodeConf.rpcSettings.address }}" - adminAddress = "{{ .Values.nodeConf.rpcSettings.adminAddress }}" - }' >> ${BASE_DIR}/node.conf - fi - echo "node.conf created in ${BASE_DIR}" - volumeMounts: - - name: nodeconf - mountPath: "{{ $.Values.volume.baseDir }}" - - name: init-certificates - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: VAULT_APP_ROLE - value: {{ $.Values.vault.role }} - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: CERTS_SECRET_PREFIX - value: {{ .Values.vault.certsecretprefix }} - - name: GIT_SECRET_PREFIX - value: {{ .Values.vault.gitsecretprefix }} - - name: AWS_SECRET_PREFIX - value: {{ .Values.vault.awssecretprefix }} - - name: H2SSL_SECRET_PREFIX - value: {{ .Values.vault.h2sslsecretprefix }} - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - validateVaultResponse () { - if echo ${2} | grep "errors"; then - echo "ERROR: unable to retrieve ${1}: ${2}" - exit 1 - fi - if [ "$3" == "LOOKUPSECRETRESPONSE" ] - then - http_code=$(curl -sS -o /dev/null -w "%{http_code}" \ - --header "X-Vault-Token: ${VAULT_TOKEN}" \ - ${VAULT_ADDR}/v1/${1}) - curl_response=$? - if test "$http_code" != "200" ; then - echo "Http response code from Vault - $http_code" - if test "$curl_response" != "0"; then - echo "Error: curl command failed with error code - $curl_response" - exit 1 - fi - fi - fi - } - # setting up env to get secrets from vault - echo "Getting secrets from Vault Server" - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - validateVaultResponse 'vault login token' "${VAULT_TOKEN}" - - OUTPUT_PATH=${BASE_DIR} - - # get nodekeystore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/nodekeystore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/nodekeystore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TLS_NODEKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["nodekeystore.jks"]') - echo "${TLS_NODEKEYSTORE}" | base64 -d > ${OUTPUT_PATH}/nodekeystore.jks - - # get sslkeystore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/sslkeystore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/sslkeystore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TLS_SSLKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["sslkeystore.jks"]') - echo "${TLS_SSLKEYSTORE}" | base64 -d > ${OUTPUT_PATH}/sslkeystore.jks - - # get truststore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/truststore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/truststore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TLS_TRUSTSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["truststore.jks"]') - echo "${TLS_TRUSTSTORE}" | base64 -d > ${OUTPUT_PATH}/truststore.jks - - # get network-map-truststore.jks from vault - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/networkmaptruststore | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/networkmaptruststore" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TLS_NMS=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["network-map-truststore"]') - echo "${TLS_NMS}" | base64 -d > ${OUTPUT_PATH}/network-map-truststore.jks - - # when using doorman and networkmap in TLS: true, and using private certificate then download certificate - if [ "{{ .Values.image.privateCertificate }}" == true ] - then - mkdir -p ${OUTPUT_PATH}/networkmap - mkdir -p ${OUTPUT_PATH}/doorman - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/networkmap | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/networkmap" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - NETWORKMAP_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["networkmap.crt"]') - echo "${NETWORKMAP_CRT}" | base64 -d > ${OUTPUT_PATH}/networkmap/networkmap.crt - - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/doorman | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/doorman" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - DOORMAN_CRT=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["doorman.crt"]') - echo "${DOORMAN_CRT}" | base64 -d > ${OUTPUT_PATH}/doorman/doorman.crt - fi - - # when using custom sslKeystore while setting in node.conf - if [ "{{ .Values.nodeConf.rpcSettings.useSsl }}" == true ] - then - mkdir -p ${OUTPUT_PATH}/${SSL_CERT_PATH} - chmod -R ${OUTPUT_PATH}/${SSL_CERT_PATH} - SSL_CERT_PATH={{ .Values.nodeConf.rpcSettings.ssl.certificatesDirectory }} - SSL_KEYSTORE_FILE_NAME_KEY={{ .Values.nodeConf.rpcSettings.ssl.sslKeystoreFileName }} - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/${SSL_KEYSTORE_FILE_NAME_KEY} | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/${SSL_KEYSTORE_FILE_NAME_KEY}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - SSLKEYSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["SSL_KEYSTORE_FILE_NAME_KEY"]') - echo "${SSLKEYSTORE}" | base64 -d > ${OUTPUT_PATH}/${SSL_CERT_PATH}/${SSL_KEYSTORE_FILE_NAME_KEY} - TRUSTKEYSTORE_FILE_NAME_KEY={{ .Values.nodeConf.rpcSettings.ssl.sslKeystoreFileName }} - LOOKUP_SECRET_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${CERTS_SECRET_PREFIX}/${TRUSTKEYSTORE_FILE_NAME_KEY} | jq -r 'if .errors then . else . end') - validateVaultResponse "${CERTS_SECRET_PREFIX}/${TRUSTKEYSTORE_FILE_NAME_KEY}" "${LOOKUP_SECRET_RESPONSE}" "LOOKUPSECRETRESPONSE" - TRUSTSTORE=$(echo ${LOOKUP_SECRET_RESPONSE} | jq -r '.data.data["TRUSTKEYSTORE_FILE_NAME_KEY"]') - echo "${TRUSTSTORE}" | base64 -d > ${OUTPUT_PATH}/${SSL_CERT_PATH}/${TRUSTKEYSTORE_FILE_NAME_KEY} - else - echo "" - fi - echo "Done" - volumeMounts: - - name: certificates - mountPath: {{ $.Values.volume.baseDir }} - - name: db-healthcheck - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - command: ["sh", "-c"] - args: - - |- - #!/usr/bin/env sh - COUNTER=1 - FLAG=true - # perform health check if db is up and running before starting corda node - while [ "$COUNTER" -le {{ $.Values.healthcheck.readinessthreshold }} ] - do - DB_NODE={{ .Values.nodeConf.dbUrl }}:{{ .Values.nodeConf.dbPort }} - STATUS=$(nc -vz $DB_NODE 2>&1 | grep -c open ) - if [ "$STATUS" == 0 ] - then - FLAG=false - else - FLAG=true - echo "DB up and running" - fi - if [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, retrying after {{ $.Values.healthcheck.readinesscheckinterval }} seconds" - COUNTER=`expr "$COUNTER" + 1` - sleep {{ $.Values.healthcheck.readinesscheckinterval }} - else - echo "SUCCESS!" - echo "DB up and running!" - exit 0 - break - fi - done - if [ "$COUNTER" -gt {{ $.Values.healthcheck.readinessthreshold }} ] || [ "$FLAG" == false ] - then - echo "Retry attempted $COUNTER times, no DB up and running. Giving up!" - exit 1 - break - fi - - name: init-cordapps - image: {{ .Values.image.initContainerName }} - imagePullPolicy: Always - env: - - name: BASE_DIR - value: {{ $.Values.volume.baseDir }} - - name: VAULT_APP_ROLE - value: {{.Values.vault.role}} - - name: VAULT_ADDR - value: {{ $.Values.vault.address }} - - name: KUBERNETES_AUTH_PATH - value: {{ $.Values.vault.authpath }} - - name: SECRET_PREFIX - value: {{ $.Values.vault.cordappsreposecretprefix }} - command: ["sh", "-c"] - args: - - |- - # crearting cordapps dir in volume to keep jars - mkdir -p {{ .Values.volume.baseDir }}/cordapps - {{- if .Values.cordapps.getcordapps }} - mkdir -p /tmp/downloaded-jars - # setting up env to get secrets from vault - KUBE_SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) - echo "Getting secrets from Vault Server" - VAULT_TOKEN=$(curl -sS --request POST ${VAULT_ADDR}/v1/auth/${KUBERNETES_AUTH_PATH}/login -H "Content-Type: application/json" -d '{"role":"'"${VAULT_APP_ROLE}"'","jwt":"'"${KUBE_SA_TOKEN}"'"}' | jq -r 'if .errors then . else .auth.client_token end') - - # save cordapps repository login password from vault - LOOKUP_PWD_RESPONSE=$(curl -sS --header "X-Vault-Token: ${VAULT_TOKEN}" ${VAULT_ADDR}/v1/${SECRET_PREFIX} | jq -r 'if .errors then . else . end') - REPO_USER_PASS=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["repo_password"]') - REPO_USER=$(echo ${LOOKUP_PWD_RESPONSE} | jq -r '.data.data["repo_username"]') - - # Downloading official corda provided jars using curl - {{- range .Values.cordapps.jars }} - cd /tmp/downloaded-jars && curl -u $REPO_USER:$REPO_USER_PASS -O -L {{ .url }} - {{- end }} - cp -ar /tmp/downloaded-jars/* {{ $.Values.volume.baseDir }}/cordapps - {{- end }} - volumeMounts: - - name: notary-volume - mountPath: "{{ $.Values.volume.baseDir }}" - imagePullSecrets: - - name: {{ .Values.image.imagePullSecret }} - volumes: - - name: notary-volume - persistentVolumeClaim: - claimName: {{ .Values.pvc.name }} - - name: certificates - emptyDir: - medium: Memory - - name: nodeconf - emptyDir: - medium: Memory diff --git a/platforms/r3-corda/charts/corda-notary/templates/pvc.yaml b/platforms/r3-corda/charts/corda-notary/templates/pvc.yaml deleted file mode 100644 index 5e240c5faee..00000000000 --- a/platforms/r3-corda/charts/corda-notary/templates/pvc.yaml +++ /dev/null @@ -1,29 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ .Values.pvc.name }} - {{- if .Values.pvc.annotations }} - annotations: -{{ toYaml .Values.pvc.annotations | indent 8 }} - {{- end }} - namespace: {{ .Values.metadata.namespace }} - labels: - app.kubernetes.io/name: {{ .Values.pvc.name }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - {{- include "labels.custom" . | nindent 2 }} -spec: - storageClassName: {{ .Values.pvc.storageClassName }} - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.pvc.memory }} \ No newline at end of file diff --git a/platforms/r3-corda/charts/corda-notary/templates/service.yaml b/platforms/r3-corda/charts/corda-notary/templates/service.yaml deleted file mode 100644 index 27e8ee8d056..00000000000 --- a/platforms/r3-corda/charts/corda-notary/templates/service.yaml +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.service.name }} - annotations: - namespace: {{ .Values.metadata.namespace }} - labels: - run: {{ .Values.service.name }} - app.kubernetes.io/name: {{ .Values.service.name }} - helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - {{- include "labels.custom" . | nindent 2 }} -spec: - type: {{ .Values.service.type }} - {{- if .Values.service.clusterIP }} - clusterIP: "{{ .Values.service.clusterIP }}" - {{- end }} - selector: - app: {{ .Values.nodeName }} - ports: - # for p2p communication among corda node - - name: p2p - protocol: TCP - port: {{ .Values.service.p2p.port }} - targetPort: {{ .Values.service.p2p.targetPort }} - {{- if .Values.service.p2p.nodePort }} - nodePort: {{ .Values.service.p2p.nodePort}} - {{- end }} - # for rpc communication between corda node and webserver - - name: rpc - protocol: TCP - port: {{ .Values.service.rpc.port }} - targetPort: {{ .Values.service.rpc.targetPort }} - {{- if .Values.service.rpc.nodePort }} - nodePort: {{ .Values.service.rpc.nodePort}} - {{- end }} - # for rpc admin communication - - name: rpcadmin - protocol: TCP - port: {{ .Values.service.rpcadmin.port }} - targetPort: {{ .Values.service.rpcadmin.targetPort }} - {{- if .Values.service.rpcadmin.nodePort }} - nodePort: {{ .Values.service.rpcadmin.nodePort}} - {{- end }} -{{- if $.Values.ambassador }} ---- -apiVersion: getambassador.io/v3alpha1 -kind: Host -metadata: - name: {{ .Values.ambassador.component_name }}-host - namespace: {{ .Values.metadata.namespace }} -spec: - hostname: {{ .Values.ambassador.component_name }}.{{ .Values.ambassador.external_url_suffix }} - acmeProvider: - authority: none - requestPolicy: - insecure: - action: Route - tlsSecret: - name: {{ .Values.ambassador.component_name }}-ambassador-certs - namespace: {{ .Values.metadata.namespace }} ---- -apiVersion: getambassador.io/v3alpha1 -kind: TLSContext -metadata: - name: {{ .Values.ambassador.component_name }}-context - namespace: {{ .Values.metadata.namespace }} -spec: - hosts: - - {{ .Values.ambassador.component_name }}.{{ .Values.ambassador.external_url_suffix }} - secret: {{ .Values.ambassador.component_name }}-ambassador-certs.{{ .Values.metadata.namespace }} - secret_namespacing: true - min_tls_version: v1.2 ---- -apiVersion: getambassador.io/v3alpha1 -kind: Mapping -metadata: - name: {{ .Values.ambassador.component_name }}-p2p-mapping - namespace: {{ .Values.metadata.namespace }} -spec: - host: {{ .Values.ambassador.component_name }}.{{ .Values.ambassador.external_url_suffix }} - prefix: / - service: https://{{ .Values.ambassador.component_name }}.{{ .Values.metadata.namespace }}:{{ .Values.nodeConf.p2p.port }} - tls: {{ .Values.ambassador.component_name }}-context -{{- end }} - diff --git a/platforms/r3-corda/charts/corda-notary/values.yaml b/platforms/r3-corda/charts/corda-notary/values.yaml deleted file mode 100644 index 6b7bd230c19..00000000000 --- a/platforms/r3-corda/charts/corda-notary/values.yaml +++ /dev/null @@ -1,247 +0,0 @@ -############################################################################################## -# Copyright Accenture. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -############################################################################################## - -#Provide the nodeName for node -#Eg. nodeName: bank1 -nodeName: bank1 - -#Provide the replica set for node deployed -#Eg. replicas: 1 -replicas: 1 - -metadata: - #Provide the namespace - #Eg. namespace: default - namespace: default - #Provide the custom labels - #NOTE: Provide labels other than name, release name , release service, chart version , chart name , app. - #Eg. labels: - # role: create_channel - labels: - -image: - #Provide the containerName of image - #Eg. containerName: ghcr.io/hyperledger/bevel-corda:4.9 - containerName: ghcr.io/hyperledger/bevel-corda:4.9 - #Provide the name of image for init container - #Eg. name: ghcr.io/hyperledger/bevel-alpine:latest - initContainerName: ghcr.io/hyperledger/bevel-alpine:latest - #Provide the image pull secret of image - #Eg. pullSecret: regcred - imagePullSecret: "" - #Provide true or false if private certificate to be added - #Eg. privateCertificate: true - privateCertificate: true - #Provide doorman domain alias - #Eg. doormanCertAlias: doorman.fracordakubetest7.com - doormanCertAlias: doorman.fracordakubetest7.com - #Provide netwrokmap domain alias - #Eg. networkmapCertAlias: networkmap.fracordakubetest7.com - networkmapCertAlias: networkmap.fracordakubetest7.com - - -#For more information for node.Conf fields please refer to: https://docs.corda.net/releases/release-V3.3/corda-configuration-file.html -nodeConf: - #The host and port on which the node is available for protocol operations over ArtemisMQ. - p2p: - url: - port: - #Specify the ambassador host:port which will be advertised in addition to p2paddress - ambassadorAddress: - rpcSettings: - useSsl: - standAloneBroker: - address: - adminAddress: - ssl: - certificatesDirectory: - sslKeystorePath: - trustStoreFilePath: - #Provide the legalName for node - #Eg. legalName: "O=Bank1,L=London,C=GB,CN=Bank1" - legalName: - messagingServerAddress: - jvmArgs: - systemProperties: - sshd: - port: - exportJMXTo: - transactionCacheSizeMegaBytes: - attachmentContentCacheSizeMegaBytes: - notary: - validating: - serviceLegalName: - detectPublicIp: - database: - exportHibernateJMXStatistics: - #Provide the h2Url for node - #Eg. h2Url: bank1h2 - dbUrl: bank1h2 - #Provide the h2Port for node - #Eg. h2Port: 9101 - dbPort: 9101 - dataSourceClassName: - dataSourceUrl: - jarPath: - #Provide the nms for node - #Eg. nms: "http://rp-elb-fra-corda-kube-cluster7-2016021309.us-west-1.elb.amazonaws.com:30050" - networkMapURL: - doormanURL: - compatibilityZoneURL: - #Provide the jar Version for corda jar and finanace jar - #Eg. jarVersion: 3.3-corda - jarVersion: 3.3-corda - #Provide the devMode for corda node - #Eg. devMode: true - devMode: true - #Provide the enviroment variables to be set - env: - - name: JAVA_OPTIONS - value: - - name: CORDA_HOME - value: - - name: BASE_DIR - value: - -credentials: - #Provide the dataSourceUser for corda node - #Eg. dataSourceUser: - dataSourceUser: - #Provide the rpcUser for corda node - rpcUser: - - name: bank1operations - permissions: [ALL] -cordapps: - #Provide if you want to provide jars in cordapps - #Eg. getcordapps: true or false - getcordapps: true - repository: - jars: - #Provide url to download the jar using wget cmd - #Eg. url: https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases/net/corda/corda-finance/3.3-corda/corda-finance-3.3-corda.jar - - url: - - url: - -volume: - #Provide the base path - #Eg. mountPath: "/opt/h2-data" - baseDir: - -resources: - #Provide the limit memory for node - #Eg. limits: "1Gi" - limits: "1Gi" - #Provide the requests memory for node - #Eg. requests: "1Gi" - requests: "1Gi" - -pvc: - # annotations: - # key: "value" - annotations: - #Provide the name for pvc - #Eg. name: bank1-pvc - name: bank1-pvc - #Provide the memory for node - #Eg. memory: 4Gi - memory: 4Gi - #Provide the name for the storageclass - #Eg. name: bank1nodesc - storageClassName: bank1nodesc - - -service: - #Provide the service - #Eg. name: bank1 - name: bank1 -# Note: Target ports are dependent on image being used. Please change them accordingly -# nodePort should be kept empty while using service type as ClusterIP ( Values.service.type ) - #Provide the type of service - #Eg. type: NodePort or LoadBalancer etc - type: NodePort - p2p: - #Provide the p2p port for node - #Eg. port: 10007 - port: 10007 - #Provide the p2p node port for node - #Eg. port: 30007 - nodePort: - #Provide the p2p targetPort for node - #Eg. targetPort: 30007 - targetPort: 30007 - rpc: - #Provide the rpc port for node - #Eg. port: 10008 - port: 10008 - #Provide the rpc targetPort for node - #Eg. targetPort: 10003 - targetPort: 10003 - #Provide the rpc node port for node - #Eg. nodePort: 30007 - nodePort: - rpcadmin: - #Provide the rpcadmin port for node - #Eg. port: 10108 - port: 10108 - #Provide the rpcadmin targetPort for node - #Eg. targetPort: 10005 - targetPort: 10005 - #Provide the rpcadmin node port for node - #Eg. nodePort: 30007 - nodePort: - -deployment: - annotations: -# annotations: -# key: "value" - -vault: - #Provide the vault server address - #Eg. address: http://54.226.163.39:8200 - address: - #Provide the vaultrole - #Eg. role: vault-role - role: vault-role - #Provide the authpath - #Eg. authpath: cordabank1 - authpath: cordabank1 - #Provide the serviceaccountname - #Eg. serviceaccountname: vault-auth-issuer - serviceaccountname: vault-auth-issuer - #Provide the secretprefix - #Eg. dbsecretprefix: bank1/credentials/database - dbsecretprefix: bank1/credentials/database - #Provide the secretprefix - #Eg. rpcusersecretprefix: bank1/credentials/rpcusers - rpcusersecretprefix: bank1/credentials/rpcusers - #Provide the secretprefix - #Eg. keystoresecretprefix: bank1/credentials/keystore - keystoresecretprefix: bank1/credentials/keystore - #Provide the secretprefix - #Eg. certsecretprefix: bank1/certs - certsecretprefix: bank1/certs - #Provide the secretprefix - #Eg. cordappsreposecretprefix: bank1/credentials/cordapps - cordappsreposecretprefix: bank1/credentials/cordapps - -healthcheck: - #Provide the interval in seconds you want to iterate till db to be ready - #Eg. readinesscheckinterval: 5 - readinesscheckinterval: 5 - #Provide the threshold till you want to check if specified db up and running - #Eg. readinessthreshold: 2 - readinessthreshold: 2 - -ambassador: - #Provides component name - #Eg. component_name: node - component_name: node - #Provides the suffix to be used in external URL - #Eg. external_url_suffix: org1.blockchaincloudpoc.com - external_url_suffix: org1.blockchaincloudpoc.com - #Provide the p2p port for ambassador - #Eg. p2p_ambassador: 10007 - p2p_ambassador: diff --git a/platforms/r3-corda/charts/values/noproxy-and-novault/init.yaml b/platforms/r3-corda/charts/values/noproxy-and-novault/init.yaml new file mode 100644 index 00000000000..ab17c9b6ad0 --- /dev/null +++ b/platforms/r3-corda/charts/values/noproxy-and-novault/init.yaml @@ -0,0 +1,9 @@ +#helm install init -f values/noproxy-and-novault/init.yaml -n supplychain-ns corda-init +global: + serviceAccountName: bevel-auth + vault: + type: kubernetes + network: corda + cluster: + provider: aws + cloudNativeServices: false diff --git a/platforms/r3-corda/charts/values/noproxy-and-novault/network-service.yaml b/platforms/r3-corda/charts/values/noproxy-and-novault/network-service.yaml new file mode 100644 index 00000000000..4ab3eaad295 --- /dev/null +++ b/platforms/r3-corda/charts/values/noproxy-and-novault/network-service.yaml @@ -0,0 +1,37 @@ +--- +#helm install supplychain -f values/noproxy-and-novault/network-service.yaml -n supplychain-ns corda-network-service +#helm upgrade supplychain -f values/noproxy-and-novault/network-service.yaml -n supplychain-ns corda-network-service +global: + serviceAccountName: bevel-auth + cluster: + provider: aws + cloudNativeServices: false + vault: + type: kubernetes + proxy: + provider: none + externalUrlSuffix: svc.cluster.local + +storage: + size: "1Gi" + dbSize: 1Gi + +settings: + removeKeysOnDelete: true # this will erase keys + rootSubject: "CN=DLT Root CA,OU=DLT,O=DLT,L=New York,C=US" + mongoSubject: "C=US,ST=New York,L=New York,O=Lite,OU=DBA,CN=mongoDB" + +doorman: + subject: "CN=Corda Doorman CA,OU=DOORMAN,O=DOORMAN,L=New York,C=US" + username: doorman + authPassword: admin + dbPassword: newdbnm + +nms: + subject: "CN=Network Map,OU=FRA,O=FRA,L=Berlin,C=DE" + username: networkmap + authPassword: admin + dbPassword: newdbnm + +tls: + enabled: false diff --git a/platforms/r3-corda/charts/values/noproxy-and-novault/node.yaml b/platforms/r3-corda/charts/values/noproxy-and-novault/node.yaml new file mode 100644 index 00000000000..0c163c84168 --- /dev/null +++ b/platforms/r3-corda/charts/values/noproxy-and-novault/node.yaml @@ -0,0 +1,33 @@ +--- +#helm install manufacturer -f values/noproxy-and-novault/node.yaml -n manufacturer-ns corda-node +#helm upgrade manufacturer -f values/noproxy-and-novault/node.yaml -n manufacturer-ns corda-node +global: + serviceAccountName: bevel-auth + cluster: + provider: aws + cloudNativeServices: false + vault: + type: kubernetes + proxy: + provider: none + externalUrlSuffix: svc.cluster.local + +storage: + size: "1Gi" + dbSize: 1Gi + +tls: + enabled: false + +image: + corda: + repository: ghcr.io/hyperledger/bevel-corda + tag: 4.9 + +nodeConf: + removeKeysOnDelete: true + legalName: "O=Manufacturer,OU=Manufacturer,L=47.38/8.54/Zurich,C=CH" + notary: + enabled: false + networkMapURL: http://supplychain-nms.supplychain-ns:8080 + doormanURL: http://supplychain-doorman.supplychain-ns:8080 diff --git a/platforms/r3-corda/charts/values/noproxy-and-novault/notary.yaml b/platforms/r3-corda/charts/values/noproxy-and-novault/notary.yaml new file mode 100644 index 00000000000..31564efb56e --- /dev/null +++ b/platforms/r3-corda/charts/values/noproxy-and-novault/notary.yaml @@ -0,0 +1,36 @@ +--- +#helm install notary -f values/noproxy-and-novault/notary.yaml -n supplychain-ns corda-node +#helm upgrade notary -f values/noproxy-and-novault/notary.yaml -n supplychain-ns corda-node +global: + serviceAccountName: bevel-auth + cluster: + provider: aws + cloudNativeServices: false + vault: + type: kubernetes + proxy: + provider: none + externalUrlSuffix: svc.cluster.local + +storage: + size: "1Gi" + dbSize: 1Gi + +tls: + enabled: false + nameOverride: notary + +image: + corda: + repository: ghcr.io/hyperledger/bevel-corda + tag: 4.9 + +nodeConf: + removeKeysOnDelete: true + legalName: "O=Notary,OU=Notary,L=London,C=GB" + notary: + enabled: true + validating: true + serviceLegalName: "O=Notary Service,OU=Notary,L=London,C=GB" + networkMapURL: http://supplychain-nms.supplychain-ns:8080 + doormanURL: http://supplychain-doorman.supplychain-ns:8080 diff --git a/platforms/r3-corda/charts/values/proxy-and-vault/init-sec.yaml b/platforms/r3-corda/charts/values/proxy-and-vault/init-sec.yaml new file mode 100644 index 00000000000..2ddab47b55a --- /dev/null +++ b/platforms/r3-corda/charts/values/proxy-and-vault/init-sec.yaml @@ -0,0 +1,18 @@ +#helm install init -f values/noproxy-and-novault/init-sec.yaml -n manufacturer-ns corda-init +global: + serviceAccountName: vault-auth + vault: + type: hashicorp + role: vault-role + address: http://vault.url:8200 + authPath: manufacturer + secretEngine: secretsv2 + secretPrefix: "data/manufacturer" + cluster: + provider: aws + cloudNativeServices: false + kubernetesUrl: "https://yourkubernetes.com" + +settings: + # Flag to copy doorman and nms certs only when tls: true + secondaryInit: true diff --git a/platforms/r3-corda/charts/values/proxy-and-vault/init.yaml b/platforms/r3-corda/charts/values/proxy-and-vault/init.yaml new file mode 100644 index 00000000000..729ba1cf7a5 --- /dev/null +++ b/platforms/r3-corda/charts/values/proxy-and-vault/init.yaml @@ -0,0 +1,14 @@ +#helm install init -f values/noproxy-and-novault/init.yaml -n supplychain-ns corda-init +global: + serviceAccountName: vault-auth + vault: + type: hashicorp + role: vault-role + address: http://vault.url:8200 + authPath: supplychain + secretEngine: secretsv2 + secretPrefix: "data/supplychain" + cluster: + provider: aws + cloudNativeServices: false + kubernetesUrl: "https://yourkubernetes.com" diff --git a/platforms/r3-corda/charts/values/proxy-and-vault/network-service.yaml b/platforms/r3-corda/charts/values/proxy-and-vault/network-service.yaml new file mode 100644 index 00000000000..3a70704d5e4 --- /dev/null +++ b/platforms/r3-corda/charts/values/proxy-and-vault/network-service.yaml @@ -0,0 +1,44 @@ +--- +#helm install supplychain -f values/noproxy-and-novault/network-service.yaml -n supplychain-ns corda-network-service +#helm upgrade supplychain -f values/noproxy-and-novault/network-service.yaml -n supplychain-ns corda-network-service +global: + serviceAccountName: vault-auth + cluster: + provider: aws + cloudNativeServices: false + vault: + type: hashicorp + role: vault-role + address: http://vault.url:8200 + authPath: supplychain + secretEngine: secretsv2 + secretPrefix: "data/supplychain" + proxy: + provider: "ambassador" + externalUrlSuffix: test.blockchaincloud.com + +storage: + size: "1Gi" + dbSize: 1Gi + +settings: + removeKeysOnDelete: true # this will erase keys + rootSubject: "CN=DLT Root CA,OU=DLT,O=DLT,L=New York,C=US" + mongoSubject: "C=US,ST=New York,L=New York,O=Lite,OU=DBA,CN=mongoDB" + +doorman: + subject: "CN=Corda Doorman CA,OU=DOORMAN,O=DOORMAN,L=New York,C=US" + username: doorman + authPassword: admin + dbPassword: newdbnm + +nms: + subject: "CN=Network Map,OU=FRA,O=FRA,L=Berlin,C=DE" + username: networkmap + authPassword: admin + dbPassword: newdbnm + +tls: + enabled: true + settings: + networkServices: true diff --git a/platforms/r3-corda/charts/values/proxy-and-vault/node.yaml b/platforms/r3-corda/charts/values/proxy-and-vault/node.yaml new file mode 100644 index 00000000000..12b43c012f0 --- /dev/null +++ b/platforms/r3-corda/charts/values/proxy-and-vault/node.yaml @@ -0,0 +1,39 @@ +--- +#helm install manufacturer -f values/noproxy-and-novault/node.yaml -n manufacturer-ns corda-node +#helm upgrade manufacturer -f values/noproxy-and-novault/node.yaml -n manufacturer-ns corda-node +global: + serviceAccountName: vault-auth + cluster: + provider: aws + cloudNativeServices: false + vault: + type: hashicorp + role: vault-role + address: http://vault.url:8200 + authPath: manufacturer + secretEngine: secretsv2 + secretPrefix: "data/manufacturer" + proxy: + provider: "ambassador" + externalUrlSuffix: test.blockchaincloud.com + p2p: 15010 + +storage: + size: "1Gi" + dbSize: 1Gi + +tls: + enabled: true + +image: + corda: + repository: ghcr.io/hyperledger/bevel-corda + tag: 4.9 + +nodeConf: + removeKeysOnDelete: true + legalName: "O=Manufacturer,OU=Manufacturer,L=47.38/8.54/Zurich,C=CH" + notary: + enabled: false + networkMapURL: https://supplychain-nms.test.blockchaincloud.com + doormanURL: https://supplychain-doorman.test.blockchaincloud.com diff --git a/platforms/r3-corda/charts/values/proxy-and-vault/notary.yaml b/platforms/r3-corda/charts/values/proxy-and-vault/notary.yaml new file mode 100644 index 00000000000..df49e13a59c --- /dev/null +++ b/platforms/r3-corda/charts/values/proxy-and-vault/notary.yaml @@ -0,0 +1,42 @@ +--- +#helm install notary -f values/noproxy-and-novault/notary.yaml -n supplychain-ns corda-node +#helm upgrade notary -f values/noproxy-and-novault/notary.yaml -n supplychain-ns corda-node +global: + serviceAccountName: vault-auth + cluster: + provider: aws + cloudNativeServices: false + vault: + type: hashicorp + role: vault-role + address: http://vault.url:8200 + authPath: supplychain + secretEngine: secretsv2 + secretPrefix: "data/supplychain" + proxy: + provider: "ambassador" + externalUrlSuffix: test.blockchaincloud.com + p2p: 15010 + +storage: + size: "1Gi" + dbSize: 1Gi + +tls: + enabled: true + nameOverride: notary + +image: + corda: + repository: ghcr.io/hyperledger/bevel-corda + tag: 4.9 + +nodeConf: + removeKeysOnDelete: true + legalName: "O=Notary,OU=Notary,L=London,C=GB" + notary: + enabled: true + validating: true + serviceLegalName: "O=Notary Service,OU=Notary,L=London,C=GB" + networkMapURL: https://supplychain-nms.test.blockchaincloud.com + doormanURL: https://supplychain-doorman.test.blockchaincloud.com diff --git a/platforms/r3-corda/configuration/roles/create/k8_component/templates/create_mongodb.tpl b/platforms/r3-corda/configuration/roles/create/k8_component/templates/create_mongodb.tpl index 50e15440f6f..864a4c9ccfd 100644 --- a/platforms/r3-corda/configuration/roles/create/k8_component/templates/create_mongodb.tpl +++ b/platforms/r3-corda/configuration/roles/create/k8_component/templates/create_mongodb.tpl @@ -39,8 +39,8 @@ spec: certsecretprefix: {{ vault.secret_path | default(org_name) }}/data/{{ org_name }}/{{ nodename }}/certs service: tcp: - port: 27017 - targetPort: 27017 + port: 27017 + targetPort: 27017 type: NodePort annotations: {} deployment: