From 93db272669f7e9486155cb59c01d9b46f1075bfb Mon Sep 17 00:00:00 2001 From: Josh Kneubuhl Date: Fri, 10 Feb 2023 05:40:00 -0500 Subject: [PATCH] Move hyperledgendary sample to fabric-operator Signed-off-by: Josh Kneubuhl Signed-off-by: asararatnakar --- README.md | 4 +- sample-network-multi-org/LICENSE | 201 +++++ sample-network-multi-org/README.md | 198 +++++ .../channel-config/.gitignore | 3 + .../channel-config/README.md | 16 + .../channel-config/config/configtx.yaml | 428 ++++++++++ .../channel-config/config/core.yaml | 775 +++++++++++++++++ .../channel-config/create_genesis_block.sh | 46 + sample-network-multi-org/cloud-config.yaml | 61 ++ sample-network-multi-org/config/configtx.yaml | 640 ++++++++++++++ sample-network-multi-org/config/core.yaml | 800 ++++++++++++++++++ sample-network-multi-org/config/orderer.yaml | 427 ++++++++++ sample-network-multi-org/justfile | 189 +++++ .../kind/cert-manager/.gitignore | 1 + .../kind/cert-manager/ca-issuer-secret.yaml | 22 + .../kind/cert-manager/ca-issuer.yaml | 34 + .../kind/cert-manager/kustomization.yaml | 11 + .../kind/cert-manager/root-tls-issuer.yaml | 7 + .../kind/nginx/ingress-nginx-controller.yaml | 39 + .../kind/nginx/kustomization.yaml | 26 + .../kind/operator/kustomization.yaml | 27 + .../kind/operator/operator-clusterrole.yaml | 205 +++++ .../operator/operator-clusterrolebinding.yaml | 42 + .../kind/operator/operator-manager.yaml | 66 ++ .../kind/operator/operator-psp.yaml | 48 ++ .../operator/operator-serviceaccount.yaml | 22 + .../organizations/.gitignore | 3 + .../organizations/org0/enroll.sh | 44 + .../organizations/org0/export_msp.sh | 46 + .../organizations/org0/join_channel.sh | 54 ++ .../organizations/org0/org0-ca.yaml | 135 +++ .../organizations/org0/org0-orderer.yaml | 151 ++++ .../organizations/org0/start.sh | 55 ++ .../organizations/org1/enroll.sh | 53 ++ .../organizations/org1/export_msp.sh | 37 + .../organizations/org1/install_chaincode.sh | 89 ++ .../organizations/org1/join_channel.sh | 39 + .../organizations/org1/org1-ca.yaml | 115 +++ .../organizations/org1/org1-peer-gateway.yaml | 59 ++ .../organizations/org1/org1-peer1.yaml | 103 +++ .../organizations/org1/org1-peer2.yaml | 103 +++ .../organizations/org1/start.sh | 65 ++ .../organizations/org2/enroll.sh | 53 ++ .../organizations/org2/export_msp.sh | 37 + .../organizations/org2/install_chaincode.sh | 89 ++ .../organizations/org2/join_channel.sh | 39 + .../organizations/org2/org2-ca.yaml | 113 +++ .../organizations/org2/org2-peer-gateway.yaml | 59 ++ .../organizations/org2/org2-peer1.yaml | 103 +++ .../organizations/org2/org2-peer2.yaml | 103 +++ .../organizations/org2/start.sh | 63 ++ .../scripts/check-kube.sh | 49 ++ .../scripts/check-network.sh | 130 +++ sample-network-multi-org/scripts/check.sh | 131 +++ .../scripts/kind_with_nginx.sh | 220 +++++ .../scripts/start_operator.sh | 19 + sample-network-multi-org/scripts/test-e2e.sh | 124 +++ sample-network-multi-org/scripts/utils.sh | 158 ++++ 58 files changed, 6977 insertions(+), 2 deletions(-) create mode 100644 sample-network-multi-org/LICENSE create mode 100644 sample-network-multi-org/README.md create mode 100644 sample-network-multi-org/channel-config/.gitignore create mode 100644 sample-network-multi-org/channel-config/README.md create mode 100644 sample-network-multi-org/channel-config/config/configtx.yaml create mode 100644 sample-network-multi-org/channel-config/config/core.yaml create mode 100755 sample-network-multi-org/channel-config/create_genesis_block.sh create mode 100644 sample-network-multi-org/cloud-config.yaml create mode 100644 sample-network-multi-org/config/configtx.yaml create mode 100644 sample-network-multi-org/config/core.yaml create mode 100644 sample-network-multi-org/config/orderer.yaml create mode 100644 sample-network-multi-org/justfile create mode 100644 sample-network-multi-org/kind/cert-manager/.gitignore create mode 100644 sample-network-multi-org/kind/cert-manager/ca-issuer-secret.yaml create mode 100644 sample-network-multi-org/kind/cert-manager/ca-issuer.yaml create mode 100644 sample-network-multi-org/kind/cert-manager/kustomization.yaml create mode 100644 sample-network-multi-org/kind/cert-manager/root-tls-issuer.yaml create mode 100644 sample-network-multi-org/kind/nginx/ingress-nginx-controller.yaml create mode 100644 sample-network-multi-org/kind/nginx/kustomization.yaml create mode 100644 sample-network-multi-org/kind/operator/kustomization.yaml create mode 100644 sample-network-multi-org/kind/operator/operator-clusterrole.yaml create mode 100644 sample-network-multi-org/kind/operator/operator-clusterrolebinding.yaml create mode 100644 sample-network-multi-org/kind/operator/operator-manager.yaml create mode 100644 sample-network-multi-org/kind/operator/operator-psp.yaml create mode 100644 sample-network-multi-org/kind/operator/operator-serviceaccount.yaml create mode 100644 sample-network-multi-org/organizations/.gitignore create mode 100755 sample-network-multi-org/organizations/org0/enroll.sh create mode 100755 sample-network-multi-org/organizations/org0/export_msp.sh create mode 100755 sample-network-multi-org/organizations/org0/join_channel.sh create mode 100644 sample-network-multi-org/organizations/org0/org0-ca.yaml create mode 100644 sample-network-multi-org/organizations/org0/org0-orderer.yaml create mode 100755 sample-network-multi-org/organizations/org0/start.sh create mode 100755 sample-network-multi-org/organizations/org1/enroll.sh create mode 100755 sample-network-multi-org/organizations/org1/export_msp.sh create mode 100755 sample-network-multi-org/organizations/org1/install_chaincode.sh create mode 100755 sample-network-multi-org/organizations/org1/join_channel.sh create mode 100644 sample-network-multi-org/organizations/org1/org1-ca.yaml create mode 100644 sample-network-multi-org/organizations/org1/org1-peer-gateway.yaml create mode 100644 sample-network-multi-org/organizations/org1/org1-peer1.yaml create mode 100644 sample-network-multi-org/organizations/org1/org1-peer2.yaml create mode 100755 sample-network-multi-org/organizations/org1/start.sh create mode 100755 sample-network-multi-org/organizations/org2/enroll.sh create mode 100755 sample-network-multi-org/organizations/org2/export_msp.sh create mode 100755 sample-network-multi-org/organizations/org2/install_chaincode.sh create mode 100755 sample-network-multi-org/organizations/org2/join_channel.sh create mode 100644 sample-network-multi-org/organizations/org2/org2-ca.yaml create mode 100644 sample-network-multi-org/organizations/org2/org2-peer-gateway.yaml create mode 100644 sample-network-multi-org/organizations/org2/org2-peer1.yaml create mode 100644 sample-network-multi-org/organizations/org2/org2-peer2.yaml create mode 100755 sample-network-multi-org/organizations/org2/start.sh create mode 100755 sample-network-multi-org/scripts/check-kube.sh create mode 100755 sample-network-multi-org/scripts/check-network.sh create mode 100755 sample-network-multi-org/scripts/check.sh create mode 100755 sample-network-multi-org/scripts/kind_with_nginx.sh create mode 100755 sample-network-multi-org/scripts/start_operator.sh create mode 100755 sample-network-multi-org/scripts/test-e2e.sh create mode 100755 sample-network-multi-org/scripts/utils.sh diff --git a/README.md b/README.md index 3f5ab833..3ea04a90 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ _Fabric, Ahoy!_ - [x] It configures Fabric networks with native Fabric CLI binaries - [x] It configures Fabric networks with CI/CD and git-ops best-practices - [x] It deploys _Chaincode Now!!!_ (integrated `ccaas` and `k8s` external builders) -- [x] It detects expiring and expired x509 certificates +- [x] It detects and automatically re-enrolls TLS certificates - [x] It will provide migration and future LTS revision support - [x] It manages hybrid cloud, multi-org, and multi-cluster Fabric networks - [x] It runs on pure containerd _and_ mobyd (no dependencies on Docker/DIND) @@ -48,7 +48,6 @@ _Fabric, Ahoy!_ - [x] Metrics and observability with [Prometheus and Grafana](./docs/prometheus.md) - [ ] Operational management: Log aggregation, monitoring, alerting - [ ] Modular CAs (Fabric CA, cert-manager.io, Vault, letsencrypt, ...) -- [ ] Automatic x509 certificate renewal - [ ] Backup / Recovery / Upgrade - [ ] Idemixer, Token SDK, BFT Orderer - [ ] Layer II blockchain integration (Cactus, Weaver, Token SDK, ...) @@ -57,6 +56,7 @@ _Fabric, Ahoy!_ ## Build a Fabric Network +- Build a [multi-org](sample-network-multi-org) network on a local KIND development cluster. - Build a [sample-network](sample-network) with Kube APIs. - [Build a Network](https://cloud.ibm.com/docs/blockchain?topic=blockchain-ibp-console-build-network) with the [Fabric Operations Console](https://github.com/hyperledger-labs/fabric-operations-console). - Automate your network with [Ansible Playbooks](https://cloud.ibm.com/docs/blockchain?topic=blockchain-ansible) and the Console REST APIs. diff --git a/sample-network-multi-org/LICENSE b/sample-network-multi-org/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/sample-network-multi-org/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/sample-network-multi-org/README.md b/sample-network-multi-org/README.md new file mode 100644 index 00000000..537b9f0b --- /dev/null +++ b/sample-network-multi-org/README.md @@ -0,0 +1,198 @@ +# Hyperledger Fabric Kubernetes Test Network + +Create a +Hyperledger Fabric [test-network](https://github.com/hyperledger/fabric-samples/tree/main/test-network) +on [KIND](https://kind.sigs.k8s.io) +with [fabric-operator](https://github.com/hyperledger-labs/fabric-operator). + +Objective: provide _crystal clarity_ to Fabric's _MSP_ and certificate structures, +focusing on the inductive construction of a multi-organization network. + +![Dark Side of the Moon](https://upload.wikimedia.org/wikipedia/en/3/3b/Dark_Side_of_the_Moon.png) +###### The Dark Side of the Moon - Pink Floyd ([From Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/File:Dark_Side_of_the_Moon.png) ) + + +## The Venue: + +To run this sample locally, clone the git repo and follow the dependency checklist: +```shell +./scripts/check.sh +``` + +This scenario is _slow_ but _predictable_. The focus in this example is not efficiency, but to +demonstrate the construction of a multi-org network, highlighting a production-realistic scenario +of running a Fabric network spanning multiple Kubernetes clusters, namespaces, or cloud-vendors. + +In typical examples of constructing a fabric test network, the use of `cryptogen` is highlighted as +an efficient and convenient mechanism to avoid complexities of CA bootstrap, node enrollments, and +the exchange of consortium MSP certificates as part of the channel configuration. + +By contrast, this scenario sets up a multi-org Fabric network, illustrating a _correct_ ordering of +CA initialization, node / admin enrollments, MSP certificate exchange, and channel construction +without the assumption of a central file system or volume mount. With minor modifications, this +example can be extended to use `rsync` or an SSH protocol to exchange channel MSP for a network +spanning multiple, independent Kubernetes clusters. For convenience, this example allocates a +dedicated k8s namespace for each organization, running on a shared virtual KIND cluster. + +For best results, start a new terminal for each organization in the consortium. (Imagine that each +shell is running commands on behalf of the org's Fabric administrator.) + + +## The Stage: + +```shell +git clone https://github.com/hyperledger-labs/fabric-operator.git +cd sample-network-multi-org +``` + +Create a KIND kubernetes cluster, *.localho.st ingress, and local container registry: +```shell +just kind +``` + + +## Act I: Launch CAs, peers, and orderers + +Start the nodes in the network: +```shell +just start org0 +just start org1 +just start org2 +``` + +Enroll admin, rcaadmin, and gateway users at the org CAs: +```shell +just enroll org0 +just enroll org1 +just enroll org2 +``` + +```shell +just check-network +``` + +## Act II: Build a Consortium + +```shell +just export-msp org0 +just export-msp org1 +just export-msp org2 +``` + +```shell +just create-genesis-block + +just inspect-genesis-block +``` + +```shell +just join org0 +just join org1 +just join org2 +``` + + +## Act III: Chaincode and Gateway Application + +Install [asset-transfer](https://github.com/hyperledger/fabric-samples/tree/main/full-stack-asset-transfer-guide/contracts/asset-transfer-typescript) +version [0.1.4](https://github.com/hyperledgendary/full-stack-asset-transfer-guide/releases/tag/v0.1.4) with the +Kubernetes [chaincode builder](https://github.com/hyperledger-labs/fabric-builder-k8s): + +```shell +just install-cc org1 +just install-cc org2 +``` + +### Ad Hoc peer CLI: + +org1: +```shell +export ORG=org1 +export MSP_ID=Org1MSP + +export $(just show-context $MSP_ID $ORG peer1) + +peer chaincode query \ + -n asset-transfer \ + -C mychannel \ + -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' +``` + +org2: +```shell +export ORG=org2 +export MSP_ID=Org2MSP + +export $(just show-context $MSP_ID $ORG peer1) + +peer chaincode query \ + -n asset-transfer \ + -C mychannel \ + -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' +``` + + +### Gateway Client + +When the org1 and org2 CAs are created, they include a bootstrap [registration](organizations/org1/org1-ca.yaml#L50-L52) +and [enrollment](organizations/org1/enroll.sh#L48) of a client identity for use in gateway application development. + +If the `just show-context` commands (above) have been loaded into the terminal, the peer, orderer, and +CA certificate paths have been loaded into the environment. + +In an org admin shell, load the gateway client environment for [trader-typescript](https://github.com/hyperledger/fabric-samples/tree/main/full-stack-asset-transfer-guide/applications/trader-typescript): +```shell +# local MSP enrollment folder for the org client user +export USER_MSP_DIR=$PWD/organizations/$ORG/enrollments/${ORG}user/msp + +# Path to private key file +export PRIVATE_KEY=$USER_MSP_DIR/keystore/key.pem + +# Path to user certificate file +export CERTIFICATE=$USER_MSP_DIR/signcerts/cert.pem + +# Path to CA certificate +export TLS_CERT=$CORE_PEER_TLS_ROOTCERT_FILE + +# Connect client applications to the load-balancing gateway peer alias: +export ENDPOINT=${ORG}-peer-gateway.${ORG}.localho.st:443 +``` + +- Compile the trader-typescript application: +```shell +git clone https://github.com/hyperledger/fabric-samples.git /tmp/fabric-samples +pushd /tmp/fabric-samples/full-stack-asset-transfer-guide/applications/trader-typescript + +npm install +``` + +```shell +# Create a yellow banana token +npm start create banana bananaman yellow + +npm start getAllAssets + +# Transfer the banana among users / orgs +npm start transfer banana appleman Org1MSP + +npm start getAllAssets + +# Transfer the banana among users / orgs +npm start transfer banana bananaman Org2MSP + +# Error! Which org owns the banana? +npm start transfer banana bananaman Org1MSP +``` + + +## Teardown + +```shell +# Tear down the network +just destroy +``` +or +```shell +# Tear down the kubernetes cluster +just unkind +``` diff --git a/sample-network-multi-org/channel-config/.gitignore b/sample-network-multi-org/channel-config/.gitignore new file mode 100644 index 00000000..c41bb5a9 --- /dev/null +++ b/sample-network-multi-org/channel-config/.gitignore @@ -0,0 +1,3 @@ +organizations/ +mychannel_genesis_block.pb +mychannel_genesis_block.json \ No newline at end of file diff --git a/sample-network-multi-org/channel-config/README.md b/sample-network-multi-org/channel-config/README.md new file mode 100644 index 00000000..57c5dc6e --- /dev/null +++ b/sample-network-multi-org/channel-config/README.md @@ -0,0 +1,16 @@ +# Channel Configuration + +TODO : this guide / notes. + + +Notes : + +- [ ] describe how `organizations/` folder is populated by the export_msp.sh scripts +- [ ] configtx uses the internal k8s `$service.svc.cluster.local` DNS domain to communicate between nodes. +- [ ] describe configtx.yaml assumes / enforces working dir is FABRIC_CFG_PATH + +TODOs: + +- [ ] Deploy org nodes across multiple namespaces. Use kube DNS to resolve in the channel config. `$service.$namespace.svc.cluster.local` +- [ ] Deploy org nodes across multiple k8s clusters. Use INGRESS URLs to resolve services. `$ingress-hostname.$org.localho.st:443` +- \ No newline at end of file diff --git a/sample-network-multi-org/channel-config/config/configtx.yaml b/sample-network-multi-org/channel-config/config/configtx.yaml new file mode 100644 index 00000000..aa7b6efb --- /dev/null +++ b/sample-network-multi-org/channel-config/config/configtx.yaml @@ -0,0 +1,428 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# + +--- +################################################################################ +# +# Section: Organizations +# +# - This section defines the different organizational identities which will +# be referenced later in the configuration. +# +################################################################################ +Organizations: + + # SampleOrg defines an MSP using the sampleconfig. It should never be used + # in production but may be used as a template for other definitions + - &OrdererOrg + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: OrdererOrg + + # ID to load the MSP definition as + ID: OrdererMSP + + # MSPDir is the filesystem path which contains the MSP configuration + MSPDir: ../organizations/ordererOrganizations/org0.localho.st/msp + + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: + Readers: + Type: Signature + Rule: "OR('OrdererMSP.member')" + Writers: + Type: Signature + Rule: "OR('OrdererMSP.member')" + Admins: + Type: Signature + Rule: "OR('OrdererMSP.admin')" + + OrdererEndpoints: + - orderernode1.org0.svc.cluster.local:7050 + - orderernode2.org0.svc.cluster.local:7050 + - orderernode3.org0.svc.cluster.local:7050 + + - &Org1 + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: Org1MSP + + # ID to load the MSP definition as + ID: Org1MSP + + MSPDir: ../organizations/peerOrganizations/org1.localho.st/msp + + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: + Readers: + Type: Signature + Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')" + Writers: + Type: Signature + Rule: "OR('Org1MSP.admin', 'Org1MSP.client')" + Admins: + Type: Signature + Rule: "OR('Org1MSP.admin')" + Endorsement: + Type: Signature + Rule: "OR('Org1MSP.peer')" + + # leave this flag set to true. + AnchorPeers: + # AnchorPeers defines the location of peers which can be used + # for cross org gossip communication. Note, this value is only + # encoded in the genesis block in the Application section context + - Host: peer1.org1.svc.cluster.local + Port: 7051 + + - &Org2 + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: Org2MSP + + # ID to load the MSP definition as + ID: Org2MSP + + MSPDir: ../organizations/peerOrganizations/org2.localho.st/msp + + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: + Readers: + Type: Signature + Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')" + Writers: + Type: Signature + Rule: "OR('Org2MSP.admin', 'Org2MSP.client')" + Admins: + Type: Signature + Rule: "OR('Org2MSP.admin')" + Endorsement: + Type: Signature + Rule: "OR('Org2MSP.peer')" + + AnchorPeers: + # AnchorPeers defines the location of peers which can be used + # for cross org gossip communication. Note, this value is only + # encoded in the genesis block in the Application section context + - Host: peer1.org2.svc.cluster.local + Port: 7051 + +################################################################################ +# +# SECTION: Capabilities +# +# - This section defines the capabilities of fabric network. This is a new +# concept as of v1.1.0 and should not be utilized in mixed networks with +# v1.0.x peers and orderers. Capabilities define features which must be +# present in a fabric binary for that binary to safely participate in the +# fabric network. For instance, if a new MSP type is added, newer binaries +# might recognize and validate the signatures from this type, while older +# binaries without this support would be unable to validate those +# transactions. This could lead to different versions of the fabric binaries +# having different world states. Instead, defining a capability for a channel +# informs those binaries without this capability that they must cease +# processing transactions until they have been upgraded. For v1.0.x if any +# capabilities are defined (including a map with all capabilities turned off) +# then the v1.0.x peer will deliberately crash. +# +################################################################################ +Capabilities: + # Channel capabilities apply to both the orderers and the peers and must be + # supported by both. + # Set the value of the capability to true to require it. + Channel: &ChannelCapabilities + # V2_0 capability ensures that orderers and peers behave according + # to v2.0 channel capabilities. Orderers and peers from + # prior releases would behave in an incompatible way, and are therefore + # not able to participate in channels at v2.0 capability. + # Prior to enabling V2.0 channel capabilities, ensure that all + # orderers and peers on a channel are at v2.0.0 or later. + V2_0: true + + # Orderer capabilities apply only to the orderers, and may be safely + # used with prior release peers. + # Set the value of the capability to true to require it. + Orderer: &OrdererCapabilities + # V2_0 orderer capability ensures that orderers behave according + # to v2.0 orderer capabilities. Orderers from + # prior releases would behave in an incompatible way, and are therefore + # not able to participate in channels at v2.0 orderer capability. + # Prior to enabling V2.0 orderer capabilities, ensure that all + # orderers on channel are at v2.0.0 or later. + V2_0: true + + # Application capabilities apply only to the peer network, and may be safely + # used with prior release orderers. + # Set the value of the capability to true to require it. + Application: &ApplicationCapabilities + # V2_0 application capability ensures that peers behave according + # to v2.0 application capabilities. Peers from + # prior releases would behave in an incompatible way, and are therefore + # not able to participate in channels at v2.0 application capability. + # Prior to enabling V2.0 application capabilities, ensure that all + # peers on channel are at v2.0.0 or later. + V2_0: true + +################################################################################ +# +# SECTION: Application +# +# - This section defines the values to encode into a config transaction or +# genesis block for application related parameters +# +################################################################################ +Application: &ApplicationDefaults + + # Organizations is the list of orgs which are defined as participants on + # the application side of the network + Organizations: + + # Policies defines the set of policies at this level of the config tree + # For Application policies, their canonical path is + # /Channel/Application/ + Policies: + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + LifecycleEndorsement: + Type: Signature + Rule: "OR('Org1MSP.peer','Org2MSP.peer')" + Endorsement: + Type: Signature + Rule: "OR('Org1MSP.peer','Org2MSP.peer')" + + Capabilities: + <<: *ApplicationCapabilities +################################################################################ +# +# SECTION: Orderer +# +# - This section defines the values to encode into a config transaction or +# genesis block for orderer related parameters +# +################################################################################ +Orderer: &OrdererDefaults + + # Orderer Type: The orderer implementation to start + OrdererType: etcdraft + + EtcdRaft: + Consenters: + - Host: orderernode1.org0.svc.cluster.local + Port: 7050 + ClientTLSCert: ../organizations/ordererOrganizations/org0.localho.st/orderers/orderernode1/tls/signcerts/tls-cert.pem + ServerTLSCert: ../organizations/ordererOrganizations/org0.localho.st/orderers/orderernode1/tls/signcerts/tls-cert.pem + - Host: orderernode2.org0.svc.cluster.local + Port: 7050 + ClientTLSCert: ../organizations/ordererOrganizations/org0.localho.st/orderers/orderernode2/tls/signcerts/tls-cert.pem + ServerTLSCert: ../organizations/ordererOrganizations/org0.localho.st/orderers/orderernode2/tls/signcerts/tls-cert.pem + - Host: orderernode3.org0.svc.cluster.local + Port: 7050 + ClientTLSCert: ../organizations/ordererOrganizations/org0.localho.st/orderers/orderernode3/tls/signcerts/tls-cert.pem + ServerTLSCert: ../organizations/ordererOrganizations/org0.localho.st/orderers/orderernode3/tls/signcerts/tls-cert.pem + + + # Options to be specified for all the etcd/raft nodes. The values here + # are the defaults for all new channels and can be modified on a + # per-channel basis via configuration updates. + Options: + # TickInterval is the time interval between two Node.Tick invocations. + #TickInterval: 500ms default + TickInterval: 2500ms + + # ElectionTick is the number of Node.Tick invocations that must pass + # between elections. That is, if a follower does not receive any + # message from the leader of current term before ElectionTick has + # elapsed, it will become candidate and start an election. + # ElectionTick must be greater than HeartbeatTick. + # ElectionTick: 10 default + ElectionTick: 5 + + # HeartbeatTick is the number of Node.Tick invocations that must + # pass between heartbeats. That is, a leader sends heartbeat + # messages to maintain its leadership every HeartbeatTick ticks. + HeartbeatTick: 1 + + # MaxInflightBlocks limits the max number of in-flight append messages + # during optimistic replication phase. + MaxInflightBlocks: 5 + + # SnapshotIntervalSize defines number of bytes per which a snapshot is taken + SnapshotIntervalSize: 16 MB + + # Batch Timeout: The amount of time to wait before creating a batch + BatchTimeout: 2s + + # Batch Size: Controls the number of messages batched into a block + BatchSize: + + # Max Message Count: The maximum number of messages to permit in a batch + MaxMessageCount: 10 + + # Absolute Max Bytes: The absolute maximum number of bytes allowed for + # the serialized messages in a batch. + AbsoluteMaxBytes: 99 MB + + # Preferred Max Bytes: The preferred maximum number of bytes allowed for + # the serialized messages in a batch. A message larger than the preferred + # max bytes will result in a batch larger than preferred max bytes. + PreferredMaxBytes: 512 KB + + # Organizations is the list of orgs which are defined as participants on + # the orderer side of the network + Organizations: + + # Policies defines the set of policies at this level of the config tree + # For Orderer policies, their canonical path is + # /Channel/Orderer/ + Policies: + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + # BlockValidation specifies what signatures must be included in the block + # from the orderer for the peer to validate it. + BlockValidation: + Type: ImplicitMeta + Rule: "ANY Writers" + +################################################################################ +# +# CHANNEL +# +# This section defines the values to encode into a config transaction or +# genesis block for channel related parameters. +# +################################################################################ +Channel: &ChannelDefaults + # Policies defines the set of policies at this level of the config tree + # For Channel policies, their canonical path is + # /Channel/ + Policies: + # Who may invoke the 'Deliver' API + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + # Who may invoke the 'Broadcast' API + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + # By default, who may modify elements at this config level + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + + # Capabilities describes the channel level capabilities, see the + # dedicated Capabilities section elsewhere in this file for a full + # description + Capabilities: + <<: *ChannelCapabilities + +################################################################################ +# +# Profile +# +# - Different configuration profiles may be encoded here to be specified +# as parameters to the configtxgen tool +# +################################################################################ +Profiles: + + # test network profile with application (not system) channel. + TwoOrgsApplicationGenesis: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + Organizations: + - *OrdererOrg + Capabilities: *OrdererCapabilities + Application: + <<: *ApplicationDefaults + Organizations: + - *Org1 + - *Org2 + Capabilities: *ApplicationCapabilities + + + # + # Unclear lineage for these profiles: nano-fab? + # + # TwoOrgsOrdererGenesis will construct a system channel as it has a Consortiums stanza, which is not + # compatible with osnadmin. + # + # @enyeart - which profile should be used for the kube test network? + # + TwoOrgsOrdererGenesis: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + OrdererType: etcdraft + Organizations: + - *OrdererOrg + Capabilities: + <<: *OrdererCapabilities + Consortiums: + SampleConsortium: + Organizations: + - *Org1 + - *Org2 + TwoOrgsChannel: + Consortium: SampleConsortium + <<: *ChannelDefaults + Application: + <<: *ApplicationDefaults + Organizations: + - *Org1 + - *Org2 + Capabilities: + <<: *ApplicationCapabilities + Org1Channel: + Consortium: SampleConsortium + <<: *ChannelDefaults + Application: + <<: *ApplicationDefaults + Organizations: + - *Org1 + Capabilities: + <<: *ApplicationCapabilities + Org2Channel: + Consortium: SampleConsortium + <<: *ChannelDefaults + Application: + <<: *ApplicationDefaults + Organizations: + - *Org2 + Capabilities: + <<: *ApplicationCapabilities diff --git a/sample-network-multi-org/channel-config/config/core.yaml b/sample-network-multi-org/channel-config/config/core.yaml new file mode 100644 index 00000000..fa5eeeb3 --- /dev/null +++ b/sample-network-multi-org/channel-config/config/core.yaml @@ -0,0 +1,775 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# + +############################################################################### +# +# Peer section +# +############################################################################### +peer: + + # The peer id provides a name for this peer instance and is used when + # naming docker resources. + id: jdoe + + # The networkId allows for logical separation of networks and is used when + # naming docker resources. + networkId: dev + + # The Address at local network interface this Peer will listen on. + # By default, it will listen on all network interfaces + listenAddress: 0.0.0.0:7051 + + # The endpoint this peer uses to listen for inbound chaincode connections. + # If this is commented-out, the listen address is selected to be + # the peer's address (see below) with port 7052 + # chaincodeListenAddress: 0.0.0.0:7052 + + # The endpoint the chaincode for this peer uses to connect to the peer. + # If this is not specified, the chaincodeListenAddress address is selected. + # And if chaincodeListenAddress is not specified, address is selected from + # peer address (see below). If specified peer address is invalid then it + # will fallback to the auto detected IP (local IP) regardless of the peer + # addressAutoDetect value. + # chaincodeAddress: 0.0.0.0:7052 + + # When used as peer config, this represents the endpoint to other peers + # in the same organization. For peers in other organization, see + # gossip.externalEndpoint for more info. + # When used as CLI config, this means the peer's endpoint to interact with + address: 0.0.0.0:7051 + + # Whether the Peer should programmatically determine its address + # This case is useful for docker containers. + # When set to true, will override peer address. + addressAutoDetect: false + + # Keepalive settings for peer server and clients + keepalive: + # Interval is the duration after which if the server does not see + # any activity from the client it pings the client to see if it's alive + interval: 7200s + # Timeout is the duration the server waits for a response + # from the client after sending a ping before closing the connection + timeout: 20s + # MinInterval is the minimum permitted time between client pings. + # If clients send pings more frequently, the peer server will + # disconnect them + minInterval: 60s + # Client keepalive settings for communicating with other peer nodes + client: + # Interval is the time between pings to peer nodes. This must + # greater than or equal to the minInterval specified by peer + # nodes + interval: 60s + # Timeout is the duration the client waits for a response from + # peer nodes before closing the connection + timeout: 20s + # DeliveryClient keepalive settings for communication with ordering + # nodes. + deliveryClient: + # Interval is the time between pings to ordering nodes. This must + # greater than or equal to the minInterval specified by ordering + # nodes. + interval: 60s + # Timeout is the duration the client waits for a response from + # ordering nodes before closing the connection + timeout: 20s + + + # Gossip related configuration + gossip: + # Bootstrap set to initialize gossip with. + # This is a list of other peers that this peer reaches out to at startup. + # Important: The endpoints here have to be endpoints of peers in the same + # organization, because the peer would refuse connecting to these endpoints + # unless they are in the same organization as the peer. + bootstrap: 127.0.0.1:7051 + + # NOTE: orgLeader and useLeaderElection parameters are mutual exclusive. + # Setting both to true would result in the termination of the peer + # since this is undefined state. If the peers are configured with + # useLeaderElection=false, make sure there is at least 1 peer in the + # organization that its orgLeader is set to true. + + # Defines whenever peer will initialize dynamic algorithm for + # "leader" selection, where leader is the peer to establish + # connection with ordering service and use delivery protocol + # to pull ledger blocks from ordering service. + useLeaderElection: false + # Statically defines peer to be an organization "leader", + # where this means that current peer will maintain connection + # with ordering service and disseminate block across peers in + # its own organization. Multiple peers or all peers in an organization + # may be configured as org leaders, so that they all pull + # blocks directly from ordering service. + orgLeader: true + + # Interval for membershipTracker polling + membershipTrackerInterval: 5s + + # Overrides the endpoint that the peer publishes to peers + # in its organization. For peers in foreign organizations + # see 'externalEndpoint' + endpoint: + # Maximum count of blocks stored in memory + maxBlockCountToStore: 10 + # Max time between consecutive message pushes(unit: millisecond) + maxPropagationBurstLatency: 10ms + # Max number of messages stored until a push is triggered to remote peers + maxPropagationBurstSize: 10 + # Number of times a message is pushed to remote peers + propagateIterations: 1 + # Number of peers selected to push messages to + propagatePeerNum: 3 + # Determines frequency of pull phases(unit: second) + # Must be greater than digestWaitTime + responseWaitTime + pullInterval: 4s + # Number of peers to pull from + pullPeerNum: 3 + # Determines frequency of pulling state info messages from peers(unit: second) + requestStateInfoInterval: 4s + # Determines frequency of pushing state info messages to peers(unit: second) + publishStateInfoInterval: 4s + # Maximum time a stateInfo message is kept until expired + stateInfoRetentionInterval: + # Time from startup certificates are included in Alive messages(unit: second) + publishCertPeriod: 10s + # Should we skip verifying block messages or not (currently not in use) + skipBlockVerification: false + # Dial timeout(unit: second) + dialTimeout: 3s + # Connection timeout(unit: second) + connTimeout: 2s + # Buffer size of received messages + recvBuffSize: 20 + # Buffer size of sending messages + sendBuffSize: 200 + # Time to wait before pull engine processes incoming digests (unit: second) + # Should be slightly smaller than requestWaitTime + digestWaitTime: 1s + # Time to wait before pull engine removes incoming nonce (unit: milliseconds) + # Should be slightly bigger than digestWaitTime + requestWaitTime: 1500ms + # Time to wait before pull engine ends pull (unit: second) + responseWaitTime: 2s + # Alive check interval(unit: second) + aliveTimeInterval: 5s + # Alive expiration timeout(unit: second) + aliveExpirationTimeout: 25s + # Reconnect interval(unit: second) + reconnectInterval: 25s + # Max number of attempts to connect to a peer + maxConnectionAttempts: 120 + # Message expiration factor for alive messages + msgExpirationFactor: 20 + # This is an endpoint that is published to peers outside of the organization. + # If this isn't set, the peer will not be known to other organizations. + externalEndpoint: + # Leader election service configuration + election: + # Longest time peer waits for stable membership during leader election startup (unit: second) + startupGracePeriod: 15s + # Interval gossip membership samples to check its stability (unit: second) + membershipSampleInterval: 1s + # Time passes since last declaration message before peer decides to perform leader election (unit: second) + leaderAliveThreshold: 10s + # Time between peer sends propose message and declares itself as a leader (sends declaration message) (unit: second) + leaderElectionDuration: 5s + + pvtData: + # pullRetryThreshold determines the maximum duration of time private data corresponding for a given block + # would be attempted to be pulled from peers until the block would be committed without the private data + pullRetryThreshold: 60s + # As private data enters the transient store, it is associated with the peer's ledger's height at that time. + # transientstoreMaxBlockRetention defines the maximum difference between the current ledger's height upon commit, + # and the private data residing inside the transient store that is guaranteed not to be purged. + # Private data is purged from the transient store when blocks with sequences that are multiples + # of transientstoreMaxBlockRetention are committed. + transientstoreMaxBlockRetention: 1000 + # pushAckTimeout is the maximum time to wait for an acknowledgement from each peer + # at private data push at endorsement time. + pushAckTimeout: 3s + # Block to live pulling margin, used as a buffer + # to prevent peer from trying to pull private data + # from peers that is soon to be purged in next N blocks. + # This helps a newly joined peer catch up to current + # blockchain height quicker. + btlPullMargin: 10 + # the process of reconciliation is done in an endless loop, while in each iteration reconciler tries to + # pull from the other peers the most recent missing blocks with a maximum batch size limitation. + # reconcileBatchSize determines the maximum batch size of missing private data that will be reconciled in a + # single iteration. + reconcileBatchSize: 10 + # reconcileSleepInterval determines the time reconciler sleeps from end of an iteration until the beginning + # of the next reconciliation iteration. + reconcileSleepInterval: 1m + # reconciliationEnabled is a flag that indicates whether private data reconciliation is enable or not. + reconciliationEnabled: true + # skipPullingInvalidTransactionsDuringCommit is a flag that indicates whether pulling of invalid + # transaction's private data from other peers need to be skipped during the commit time and pulled + # only through reconciler. + skipPullingInvalidTransactionsDuringCommit: false + # implicitCollectionDisseminationPolicy specifies the dissemination policy for the peer's own implicit collection. + # When a peer endorses a proposal that writes to its own implicit collection, below values override the default values + # for disseminating private data. + # Note that it is applicable to all channels the peer has joined. The implication is that requiredPeerCount has to + # be smaller than the number of peers in a channel that has the lowest numbers of peers from the organization. + implicitCollectionDisseminationPolicy: + # requiredPeerCount defines the minimum number of eligible peers to which the peer must successfully + # disseminate private data for its own implicit collection during endorsement. Default value is 0. + requiredPeerCount: 0 + # maxPeerCount defines the maximum number of eligible peers to which the peer will attempt to + # disseminate private data for its own implicit collection during endorsement. Default value is 1. + maxPeerCount: 1 + + # Gossip state transfer related configuration + state: + # indicates whenever state transfer is enabled or not + # default value is true, i.e. state transfer is active + # and takes care to sync up missing blocks allowing + # lagging peer to catch up to speed with rest network. + # Keep in mind that when peer.gossip.useLeaderElection is true + # and there are several peers in the organization, + # or peer.gossip.useLeaderElection is false alongside with + # peer.gossip.orgleader being false, the peer's ledger may lag behind + # the rest of the peers and will never catch up due to state transfer + # being disabled. + enabled: false + # checkInterval interval to check whether peer is lagging behind enough to + # request blocks via state transfer from another peer. + checkInterval: 10s + # responseTimeout amount of time to wait for state transfer response from + # other peers + responseTimeout: 3s + # batchSize the number of blocks to request via state transfer from another peer + batchSize: 10 + # blockBufferSize reflects the size of the re-ordering buffer + # which captures blocks and takes care to deliver them in order + # down to the ledger layer. The actual buffer size is bounded between + # 0 and 2*blockBufferSize, each channel maintains its own buffer + blockBufferSize: 20 + # maxRetries maximum number of re-tries to ask + # for single state transfer request + maxRetries: 3 + + # TLS Settings + tls: + # Require server-side TLS + enabled: true + # Require client certificates / mutual TLS for inbound connections. + # Note that clients that are not configured to use a certificate will + # fail to connect to the peer. + clientAuthRequired: false + # X.509 certificate used for TLS server + cert: + file: tls/server.crt + # Private key used for TLS server + key: + file: tls/server.key + # rootcert.file represents the trusted root certificate chain used for verifying certificates + # of other nodes during outbound connections. + # It is not required to be set, but can be used to augment the set of TLS CA certificates + # available from the MSPs of each channel’s configuration. + rootcert: + file: tls/ca.crt + # If mutual TLS is enabled, clientRootCAs.files contains a list of additional root certificates + # used for verifying certificates of client connections. + # It augments the set of TLS CA certificates available from the MSPs of each channel’s configuration. + # Minimally, set your organization's TLS CA root certificate so that the peer can receive join channel requests. + clientRootCAs: + files: + - tls/ca.crt + # Private key used for TLS when making client connections. + # If not set, peer.tls.key.file will be used instead + clientKey: + file: + # X.509 certificate used for TLS when making client connections. + # If not set, peer.tls.cert.file will be used instead + clientCert: + file: + + # Authentication contains configuration parameters related to authenticating + # client messages + authentication: + # the acceptable difference between the current server time and the + # client's time as specified in a client request message + timewindow: 15m + + # Path on the file system where peer will store data (eg ledger). This + # location must be access control protected to prevent unintended + # modification that might corrupt the peer operations. + fileSystemPath: /var/hyperledger/production + + # BCCSP (Blockchain crypto provider): Select which crypto implementation or + # library to use + BCCSP: + Default: SW + # Settings for the SW crypto provider (i.e. when DEFAULT: SW) + SW: + # TODO: The default Hash and Security level needs refactoring to be + # fully configurable. Changing these defaults requires coordination + # SHA2 is hardcoded in several places, not only BCCSP + Hash: SHA2 + Security: 256 + # Location of Key Store + FileKeyStore: + # If "", defaults to 'mspConfigPath'/keystore + KeyStore: + # Settings for the PKCS#11 crypto provider (i.e. when DEFAULT: PKCS11) + PKCS11: + # Location of the PKCS11 module library + Library: + # Token Label + Label: + # User PIN + Pin: + Hash: + Security: + + # Path on the file system where peer will find MSP local configurations + mspConfigPath: msp + + # Identifier of the local MSP + # ----!!!!IMPORTANT!!!-!!!IMPORTANT!!!-!!!IMPORTANT!!!!---- + # Deployers need to change the value of the localMspId string. + # In particular, the name of the local MSP ID of a peer needs + # to match the name of one of the MSPs in each of the channel + # that this peer is a member of. Otherwise this peer's messages + # will not be identified as valid by other nodes. + localMspId: Org1MSP + + # CLI common client config options + client: + # connection timeout + connTimeout: 15s + + # Delivery service related config + deliveryclient: + # It sets the total time the delivery service may spend in reconnection + # attempts until its retry logic gives up and returns an error + reconnectTotalTimeThreshold: 3600s + + # It sets the delivery service <-> ordering service node connection timeout + connTimeout: 15s + + # It sets the delivery service maximal delay between consecutive retries + reConnectBackoffThreshold: 3600s + + # A list of orderer endpoint addresses which should be overridden + # when found in channel configurations. + addressOverrides: + # - from: + # to: + # caCertsFile: + # - from: + # to: + # caCertsFile: + + # Type for the local MSP - by default it's of type bccsp + localMspType: bccsp + + # Used with Go profiling tools only in none production environment. In + # production, it should be disabled (eg enabled: false) + profile: + enabled: false + listenAddress: 0.0.0.0:6060 + + # Handlers defines custom handlers that can filter and mutate + # objects passing within the peer, such as: + # Auth filter - reject or forward proposals from clients + # Decorators - append or mutate the chaincode input passed to the chaincode + # Endorsers - Custom signing over proposal response payload and its mutation + # Valid handler definition contains: + # - A name which is a factory method name defined in + # core/handlers/library/library.go for statically compiled handlers + # - library path to shared object binary for pluggable filters + # Auth filters and decorators are chained and executed in the order that + # they are defined. For example: + # authFilters: + # - + # name: FilterOne + # library: /opt/lib/filter.so + # - + # name: FilterTwo + # decorators: + # - + # name: DecoratorOne + # - + # name: DecoratorTwo + # library: /opt/lib/decorator.so + # Endorsers are configured as a map that its keys are the endorsement system chaincodes that are being overridden. + # Below is an example that overrides the default ESCC and uses an endorsement plugin that has the same functionality + # as the default ESCC. + # If the 'library' property is missing, the name is used as the constructor method in the builtin library similar + # to auth filters and decorators. + # endorsers: + # escc: + # name: DefaultESCC + # library: /etc/hyperledger/fabric/plugin/escc.so + handlers: + authFilters: + - + name: DefaultAuth + - + name: ExpirationCheck # This filter checks identity x509 certificate expiration + decorators: + - + name: DefaultDecorator + endorsers: + escc: + name: DefaultEndorsement + library: + validators: + vscc: + name: DefaultValidation + library: + + # library: /etc/hyperledger/fabric/plugin/escc.so + # Number of goroutines that will execute transaction validation in parallel. + # By default, the peer chooses the number of CPUs on the machine. Set this + # variable to override that choice. + # NOTE: overriding this value might negatively influence the performance of + # the peer so please change this value only if you know what you're doing + validatorPoolSize: + + # The discovery service is used by clients to query information about peers, + # such as - which peers have joined a certain channel, what is the latest + # channel config, and most importantly - given a chaincode and a channel, + # what possible sets of peers satisfy the endorsement policy. + discovery: + enabled: true + # Whether the authentication cache is enabled or not. + authCacheEnabled: true + # The maximum size of the cache, after which a purge takes place + authCacheMaxSize: 1000 + # The proportion (0 to 1) of entries that remain in the cache after the cache is purged due to overpopulation + authCachePurgeRetentionRatio: 0.75 + # Whether to allow non-admins to perform non channel scoped queries. + # When this is false, it means that only peer admins can perform non channel scoped queries. + orgMembersAllowedAccess: false + + # Limits is used to configure some internal resource limits. + limits: + # Concurrency limits the number of concurrently running requests to a service on each peer. + # Currently this option is only applied to endorser service and deliver service. + # When the property is missing or the value is 0, the concurrency limit is disabled for the service. + concurrency: + # endorserService limits concurrent requests to endorser service that handles chaincode deployment, query and invocation, + # including both user chaincodes and system chaincodes. + endorserService: 2500 + # deliverService limits concurrent event listeners registered to deliver service for blocks and transaction events. + deliverService: 2500 + +############################################################################### +# +# VM section +# +############################################################################### +vm: + + # Endpoint of the vm management system. For docker can be one of the following in general + # unix:///var/run/docker.sock + # http://localhost:2375 + # https://localhost:2376 + # endpoint: unix:///var/run/docker.sock + + # DISABLE the docker daemon endpoint to prevent /healthz from checking for docker in "External Builder" mode. + endpoint: + + # settings for docker vms + docker: + tls: + enabled: false + ca: + file: docker/ca.crt + cert: + file: docker/tls.crt + key: + file: docker/tls.key + + # Enables/disables the standard out/err from chaincode containers for + # debugging purposes + attachStdout: false + + # Parameters on creating docker container. + # Container may be efficiently created using ipam & dns-server for cluster + # NetworkMode - sets the networking mode for the container. Supported + # standard values are: `host`(default),`bridge`,`ipvlan`,`none`. + # Dns - a list of DNS servers for the container to use. + # Note: `Privileged` `Binds` `Links` and `PortBindings` properties of + # Docker Host Config are not supported and will not be used if set. + # LogConfig - sets the logging driver (Type) and related options + # (Config) for Docker. For more info, + # https://docs.docker.com/engine/admin/logging/overview/ + # Note: Set LogConfig using Environment Variables is not supported. + hostConfig: + NetworkMode: host + Dns: + # - 192.168.0.1 + LogConfig: + Type: json-file + Config: + max-size: "50m" + max-file: "5" + Memory: 2147483648 + +############################################################################### +# +# Chaincode section +# +############################################################################### +chaincode: + + # The id is used by the Chaincode stub to register the executing Chaincode + # ID with the Peer and is generally supplied through ENV variables + # the `path` form of ID is provided when installing the chaincode. + # The `name` is used for all other requests and can be any string. + id: + path: + name: + + # Generic builder environment, suitable for most chaincode types + builder: $(DOCKER_NS)/fabric-ccenv:$(TWO_DIGIT_VERSION) + + # Enables/disables force pulling of the base docker images (listed below) + # during user chaincode instantiation. + # Useful when using moving image tags (such as :latest) + pull: false + + golang: + # golang will never need more than baseos + runtime: $(DOCKER_NS)/fabric-baseos:$(TWO_DIGIT_VERSION) + + # whether or not golang chaincode should be linked dynamically + dynamicLink: false + + java: + # This is an image based on java:openjdk-8 with addition compiler + # tools added for java shim layer packaging. + # This image is packed with shim layer libraries that are necessary + # for Java chaincode runtime. + runtime: $(DOCKER_NS)/fabric-javaenv:$(TWO_DIGIT_VERSION) + + node: + # This is an image based on node:$(NODE_VER)-alpine + runtime: $(DOCKER_NS)/fabric-nodeenv:$(TWO_DIGIT_VERSION) + + # List of directories to treat as external builders and launchers for + # chaincode. The external builder detection processing will iterate over the + # builders in the order specified below. + externalBuilders: + - path: /var/hyperledger/fabric/chaincode/ccs-builder + name: ccs-builder + propagateEnvironment: + - HOME + - CORE_PEER_ID + - CORE_PEER_LOCALMSPID + + # The maximum duration to wait for the chaincode build and install process + # to complete. + installTimeout: 300s + + # Timeout duration for starting up a container and waiting for Register + # to come through. + startuptimeout: 300s + + # Timeout duration for Invoke and Init calls to prevent runaway. + # This timeout is used by all chaincodes in all the channels, including + # system chaincodes. + # Note that during Invoke, if the image is not available (e.g. being + # cleaned up when in development environment), the peer will automatically + # build the image, which might take more time. In production environment, + # the chaincode image is unlikely to be deleted, so the timeout could be + # reduced accordingly. + executetimeout: 30s + + # There are 2 modes: "dev" and "net". + # In dev mode, user runs the chaincode after starting peer from + # command line on local machine. + # In net mode, peer will run chaincode in a docker container. + mode: net + + # keepalive in seconds. In situations where the communication goes through a + # proxy that does not support keep-alive, this parameter will maintain connection + # between peer and chaincode. + # A value <= 0 turns keepalive off + keepalive: 0 + + # enabled system chaincodes + system: + _lifecycle: enable + cscc: enable + lscc: enable + qscc: enable + + # Logging section for the chaincode container + logging: + # Default level for all loggers within the chaincode container + level: info + # Override default level for the 'shim' logger + shim: warning + # Format for the chaincode container logs + format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' + +############################################################################### +# +# Ledger section - ledger configuration encompasses both the blockchain +# and the state +# +############################################################################### +ledger: + + blockchain: + + state: + # stateDatabase - options are "goleveldb", "CouchDB" + # goleveldb - default state database stored in goleveldb. + # CouchDB - store state database in CouchDB + stateDatabase: goleveldb + # Limit on the number of records to return per query + totalQueryLimit: 100000 + couchDBConfig: + # It is recommended to run CouchDB on the same server as the peer, and + # not map the CouchDB container port to a server port in docker-compose. + # Otherwise proper security must be provided on the connection between + # CouchDB client (on the peer) and server. + couchDBAddress: 127.0.0.1:5984 + # This username must have read and write authority on CouchDB + username: + # The password is recommended to pass as an environment variable + # during start up (eg CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD). + # If it is stored here, the file must be access control protected + # to prevent unintended users from discovering the password. + password: + # Number of retries for CouchDB errors + maxRetries: 3 + # Number of retries for CouchDB errors during peer startup. + # The delay between retries doubles for each attempt. + # Default of 10 retries results in 11 attempts over 2 minutes. + maxRetriesOnStartup: 10 + # CouchDB request timeout (unit: duration, e.g. 20s) + requestTimeout: 35s + # Limit on the number of records per each CouchDB query + # Note that chaincode queries are only bound by totalQueryLimit. + # Internally the chaincode may execute multiple CouchDB queries, + # each of size internalQueryLimit. + internalQueryLimit: 1000 + # Limit on the number of records per CouchDB bulk update batch + maxBatchUpdateSize: 1000 + # Warm indexes after every N blocks. + # This option warms any indexes that have been + # deployed to CouchDB after every N blocks. + # A value of 1 will warm indexes after every block commit, + # to ensure fast selector queries. + # Increasing the value may improve write efficiency of peer and CouchDB, + # but may degrade query response time. + warmIndexesAfterNBlocks: 1 + # Create the _global_changes system database + # This is optional. Creating the global changes database will require + # additional system resources to track changes and maintain the database + createGlobalChangesDB: false + # CacheSize denotes the maximum mega bytes (MB) to be allocated for the in-memory state + # cache. Note that CacheSize needs to be a multiple of 32 MB. If it is not a multiple + # of 32 MB, the peer would round the size to the next multiple of 32 MB. + # To disable the cache, 0 MB needs to be assigned to the cacheSize. + cacheSize: 64 + + history: + # enableHistoryDatabase - options are true or false + # Indicates if the history of key updates should be stored. + # All history 'index' will be stored in goleveldb, regardless if using + # CouchDB or alternate database for the state. + enableHistoryDatabase: true + + pvtdataStore: + # the maximum db batch size for converting + # the ineligible missing data entries to eligible missing data entries + collElgProcMaxDbBatchSize: 5000 + # the minimum duration (in milliseconds) between writing + # two consecutive db batches for converting the ineligible missing data entries to eligible missing data entries + collElgProcDbBatchesInterval: 1000 + # The missing data entries are classified into two categories: + # (1) prioritized + # (2) deprioritized + # Initially, all missing data are in the prioritized list. When the + # reconciler is unable to fetch the missing data from other peers, + # the unreconciled missing data would be moved to the deprioritized list. + # The reconciler would retry deprioritized missing data after every + # deprioritizedDataReconcilerInterval (unit: minutes). Note that the + # interval needs to be greater than the reconcileSleepInterval + deprioritizedDataReconcilerInterval: 60m + + snapshots: + # Path on the file system where peer will store ledger snapshots + rootDir: /var/hyperledger/production/snapshots + +############################################################################### +# +# Operations section +# +############################################################################### +operations: + # host and port for the operations server + listenAddress: 127.0.0.1:9443 + + # TLS configuration for the operations endpoint + tls: + # TLS enabled + enabled: false + + # path to PEM encoded server certificate for the operations server + cert: + file: + + # path to PEM encoded server key for the operations server + key: + file: + + # most operations service endpoints require client authentication when TLS + # is enabled. clientAuthRequired requires client certificate authentication + # at the TLS layer to access all resources. + clientAuthRequired: false + + # paths to PEM encoded ca certificates to trust for client authentication + clientRootCAs: + files: [] + +############################################################################### +# +# Metrics section +# +############################################################################### +metrics: + # metrics provider is one of statsd, prometheus, or disabled + provider: disabled + + # statsd configuration + statsd: + # network type: tcp or udp + network: udp + + # statsd server address + address: 127.0.0.1:8125 + + # the interval at which locally cached counters and gauges are pushed + # to statsd; timings are pushed immediately + writeInterval: 10s + + # prefix is prepended to all emitted statsd metrics + prefix: diff --git a/sample-network-multi-org/channel-config/create_genesis_block.sh b/sample-network-multi-org/channel-config/create_genesis_block.sh new file mode 100755 index 00000000..c882e4dc --- /dev/null +++ b/sample-network-multi-org/channel-config/create_genesis_block.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +GENESIS_BLOCK=${CHANNEL_NAME}_genesis_block.pb +CHANNEL_CONFIG=channel-config/config/configtx-multi-namespace.yaml + +print "Creating channel-config/$GENESIS_BLOCK from $CHANNEL_CONFIG" + +# +# The working directories and environment for configtxgen are confusing. +# +# Run configtxgen from the channel-config folder. This instructs the +# routine to read configtxgen.yaml from the local configuration, not the +# default config created when the Fabric binaries were downloaded. +# +# In configtx.yaml, path references will be relative to the config folder, +# not the current working directory. +# +cd channel-config +export FABRIC_CFG_PATH=$PWD/config + +configtxgen \ + -profile TwoOrgsApplicationGenesis \ + -channelID $CHANNEL_NAME \ + -outputBlock $GENESIS_BLOCK + + +#configtxgen -inspectBlock $GENESIS_BLOCK | tee ${CHANNEL_NAME}_genesis_block.json | jq diff --git a/sample-network-multi-org/cloud-config.yaml b/sample-network-multi-org/cloud-config.yaml new file mode 100644 index 00000000..7f429311 --- /dev/null +++ b/sample-network-multi-org/cloud-config.yaml @@ -0,0 +1,61 @@ +#cloud-config +users: + - name: ubuntu + groups: + - sudo + - docker + +write_files: + - path: /config/provision-root.sh + permissions: '0744' + content: | + #!/usr/bin/env bash + set -ex + # set -o errexit + # set -o pipefail + + # Install kind + KIND_VERSION=0.17.0 + if [ ! -x "/usr/local/bin/kind" ]; then + KIND_ARCH=$(dpkg --print-architecture) + curl --fail --silent --show-error -L "https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-linux-${KIND_ARCH}" -o /usr/local/bin/kind + chmod 755 /usr/local/bin/kind + fi + + # Install just + JUST_VERSION=1.5.0 + if [ ! -x "/usr/local/bin/just" ]; then + curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --tag ${JUST_VERSION} --to /usr/local/bin + chown root:root /usr/local/bin/just + chmod 755 /usr/local/bin/just + fi + + snap install kubectl --classic + snap install k9s --classic + snap install yq --classic + snap install jq --classic + snap install docker + + - path: /config/provision-user.sh + permissions: '0777' + owner: ubuntu:ubuntu + content: | + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] || curl --fail --silent --show-error -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.3/install.sh | bash + . "$NVM_DIR/nvm.sh" + + # Install latest node v16.x, latest typescript, weft + nvm install 16 + npm install -g typescript + npm install -g @hyperledger-labs/weft + +# Use Google DNS as the mac resolvers are not 100% reliable for the npm dependency builds in Docker +bootcmd: + - printf "[Resolve]\nDNS=8.8.8.8" > /etc/systemd/resolved.conf + - [systemctl, restart, systemd-resolved] + +runcmd: + - /config/provision-root.sh + - su -c /config/provision-user.sh ubuntu + +final_message: "The system is finally up, after $UPTIME seconds" \ No newline at end of file diff --git a/sample-network-multi-org/config/configtx.yaml b/sample-network-multi-org/config/configtx.yaml new file mode 100644 index 00000000..9bc4e1fc --- /dev/null +++ b/sample-network-multi-org/config/configtx.yaml @@ -0,0 +1,640 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +--- +################################################################################ +# +# ORGANIZATIONS +# +# This section defines the organizational identities that can be referenced +# in the configuration profiles. +# +################################################################################ +Organizations: + + # SampleOrg defines an MSP using the sampleconfig. It should never be used + # in production but may be used as a template for other definitions. + - &SampleOrg + # Name is the key by which this org will be referenced in channel + # configuration transactions. + # Name can include alphanumeric characters as well as dots and dashes. + Name: SampleOrg + + # SkipAsForeign can be set to true for org definitions which are to be + # inherited from the orderer system channel during channel creation. This + # is especially useful when an admin of a single org without access to the + # MSP directories of the other orgs wishes to create a channel. Note + # this property must always be set to false for orgs included in block + # creation. + SkipAsForeign: false + + # ID is the key by which this org's MSP definition will be referenced. + # ID can include alphanumeric characters as well as dots and dashes. + ID: SampleOrg + + # MSPDir is the filesystem path which contains the MSP configuration. + MSPDir: msp + + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: &SampleOrgPolicies + Readers: + Type: Signature + Rule: "OR('SampleOrg.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('SampleOrg.admin', 'SampleOrg.peer', 'SampleOrg.client')" + Writers: + Type: Signature + Rule: "OR('SampleOrg.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('SampleOrg.admin', 'SampleOrg.client')" + Admins: + Type: Signature + Rule: "OR('SampleOrg.admin')" + Endorsement: + Type: Signature + Rule: "OR('SampleOrg.member')" + + # OrdererEndpoints is a list of all orderers this org runs which clients + # and peers may to connect to to push transactions and receive blocks respectively. + OrdererEndpoints: + - "127.0.0.1:7050" + + # AnchorPeers defines the location of peers which can be used for + # cross-org gossip communication. + # + # NOTE: this value should only be set when using the deprecated + # `configtxgen --outputAnchorPeersUpdate` command. It is recommended + # to instead use the channel configuration update process to set the + # anchor peers for each organization. + AnchorPeers: + - Host: 127.0.0.1 + Port: 7051 + +################################################################################ +# +# CAPABILITIES +# +# This section defines the capabilities of fabric network. This is a new +# concept as of v1.1.0 and should not be utilized in mixed networks with +# v1.0.x peers and orderers. Capabilities define features which must be +# present in a fabric binary for that binary to safely participate in the +# fabric network. For instance, if a new MSP type is added, newer binaries +# might recognize and validate the signatures from this type, while older +# binaries without this support would be unable to validate those +# transactions. This could lead to different versions of the fabric binaries +# having different world states. Instead, defining a capability for a channel +# informs those binaries without this capability that they must cease +# processing transactions until they have been upgraded. For v1.0.x if any +# capabilities are defined (including a map with all capabilities turned off) +# then the v1.0.x peer will deliberately crash. +# +################################################################################ +Capabilities: + # Channel capabilities apply to both the orderers and the peers and must be + # supported by both. + # Set the value of the capability to true to require it. + Channel: &ChannelCapabilities + # V2.0 for Channel is a catchall flag for behavior which has been + # determined to be desired for all orderers and peers running at the v2.0.0 + # level, but which would be incompatible with orderers and peers from + # prior releases. + # Prior to enabling V2.0 channel capabilities, ensure that all + # orderers and peers on a channel are at v2.0.0 or later. + V2_0: true + + # Orderer capabilities apply only to the orderers, and may be safely + # used with prior release peers. + # Set the value of the capability to true to require it. + Orderer: &OrdererCapabilities + # V1.1 for Orderer is a catchall flag for behavior which has been + # determined to be desired for all orderers running at the v1.1.x + # level, but which would be incompatible with orderers from prior releases. + # Prior to enabling V2.0 orderer capabilities, ensure that all + # orderers on a channel are at v2.0.0 or later. + V2_0: true + + # Application capabilities apply only to the peer network, and may be safely + # used with prior release orderers. + # Set the value of the capability to true to require it. + Application: &ApplicationCapabilities + # V2.5 for Application enables the new non-backwards compatible + # features of fabric v2.5, namely the ability to purge private data. + # Prior to enabling V2.5 application capabilities, ensure that all + # peers on a channel are at v2.5.0 or later. + V2_5: true + +################################################################################ +# +# APPLICATION +# +# This section defines the values to encode into a config transaction or +# genesis block for application-related parameters. +# +################################################################################ +Application: &ApplicationDefaults + ACLs: &ACLsDefault + # This section provides defaults for policies for various resources + # in the system. These "resources" could be functions on system chaincodes + # (e.g., "GetBlockByNumber" on the "qscc" system chaincode) or other resources + # (e.g.,who can receive Block events). This section does NOT specify the resource's + # definition or API, but just the ACL policy for it. + # + # Users can override these defaults with their own policy mapping by defining the + # mapping under ACLs in their channel definition + + #---New Lifecycle System Chaincode (_lifecycle) function to policy mapping for access control--# + + # ACL policy for _lifecycle's "CheckCommitReadiness" function + _lifecycle/CheckCommitReadiness: /Channel/Application/Writers + + # ACL policy for _lifecycle's "CommitChaincodeDefinition" function + _lifecycle/CommitChaincodeDefinition: /Channel/Application/Writers + + # ACL policy for _lifecycle's "QueryChaincodeDefinition" function + _lifecycle/QueryChaincodeDefinition: /Channel/Application/Writers + + # ACL policy for _lifecycle's "QueryChaincodeDefinitions" function + _lifecycle/QueryChaincodeDefinitions: /Channel/Application/Writers + + #---Lifecycle System Chaincode (lscc) function to policy mapping for access control---# + + # ACL policy for lscc's "getid" function + lscc/ChaincodeExists: /Channel/Application/Readers + + # ACL policy for lscc's "getdepspec" function + lscc/GetDeploymentSpec: /Channel/Application/Readers + + # ACL policy for lscc's "getccdata" function + lscc/GetChaincodeData: /Channel/Application/Readers + + # ACL Policy for lscc's "getchaincodes" function + lscc/GetInstantiatedChaincodes: /Channel/Application/Readers + + #---Query System Chaincode (qscc) function to policy mapping for access control---# + + # ACL policy for qscc's "GetChainInfo" function + qscc/GetChainInfo: /Channel/Application/Readers + + # ACL policy for qscc's "GetBlockByNumber" function + qscc/GetBlockByNumber: /Channel/Application/Readers + + # ACL policy for qscc's "GetBlockByHash" function + qscc/GetBlockByHash: /Channel/Application/Readers + + # ACL policy for qscc's "GetTransactionByID" function + qscc/GetTransactionByID: /Channel/Application/Readers + + # ACL policy for qscc's "GetBlockByTxID" function + qscc/GetBlockByTxID: /Channel/Application/Readers + + #---Configuration System Chaincode (cscc) function to policy mapping for access control---# + + # ACL policy for cscc's "GetConfigBlock" function + cscc/GetConfigBlock: /Channel/Application/Readers + + # ACL policy for cscc's "GetChannelConfig" function + cscc/GetChannelConfig: /Channel/Application/Readers + + #---Miscellaneous peer function to policy mapping for access control---# + + # ACL policy for invoking chaincodes on peer + peer/Propose: /Channel/Application/Writers + + # ACL policy for chaincode to chaincode invocation + peer/ChaincodeToChaincode: /Channel/Application/Writers + + #---Events resource to policy mapping for access control###---# + + # ACL policy for sending block events + event/Block: /Channel/Application/Readers + + # ACL policy for sending filtered block events + event/FilteredBlock: /Channel/Application/Readers + + # Organizations lists the orgs participating on the application side of the + # network. + Organizations: + + # Policies defines the set of policies at this level of the config tree + # For Application policies, their canonical path is + # /Channel/Application/ + Policies: &ApplicationDefaultPolicies + LifecycleEndorsement: + Type: ImplicitMeta + Rule: "MAJORITY Endorsement" + Endorsement: + Type: ImplicitMeta + Rule: "MAJORITY Endorsement" + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + + # Capabilities describes the application level capabilities, see the + # dedicated Capabilities section elsewhere in this file for a full + # description + Capabilities: + <<: *ApplicationCapabilities + +################################################################################ +# +# ORDERER +# +# This section defines the values to encode into a config transaction or +# genesis block for orderer related parameters. +# +################################################################################ +Orderer: &OrdererDefaults + + # Orderer Type: The orderer implementation to start. + # Available types are "solo", "kafka" and "etcdraft". + OrdererType: solo + + # Addresses used to be the list of orderer addresses that clients and peers + # could connect to. However, this does not allow clients to associate orderer + # addresses and orderer organizations which can be useful for things such + # as TLS validation. The preferred way to specify orderer addresses is now + # to include the OrdererEndpoints item in your org definition + Addresses: + # - 127.0.0.1:7050 + + # Batch Timeout: The amount of time to wait before creating a batch. + BatchTimeout: 2s + + # Batch Size: Controls the number of messages batched into a block. + # The orderer views messages opaquely, but typically, messages may + # be considered to be Fabric transactions. The 'batch' is the group + # of messages in the 'data' field of the block. Blocks will be a few kb + # larger than the batch size, when signatures, hashes, and other metadata + # is applied. + BatchSize: + + # Max Message Count: The maximum number of messages to permit in a + # batch. No block will contain more than this number of messages. + MaxMessageCount: 500 + + # Absolute Max Bytes: The absolute maximum number of bytes allowed for + # the serialized messages in a batch. The maximum block size is this value + # plus the size of the associated metadata (usually a few KB depending + # upon the size of the signing identities). Any transaction larger than + # this value will be rejected by ordering. + # It is recommended not to exceed 49 MB, given the default grpc max message size of 100 MB + # configured on orderer and peer nodes (and allowing for message expansion during communication). + AbsoluteMaxBytes: 10 MB + + # Preferred Max Bytes: The preferred maximum number of bytes allowed + # for the serialized messages in a batch. Roughly, this field may be considered + # the best effort maximum size of a batch. A batch will fill with messages + # until this size is reached (or the max message count, or batch timeout is + # exceeded). If adding a new message to the batch would cause the batch to + # exceed the preferred max bytes, then the current batch is closed and written + # to a block, and a new batch containing the new message is created. If a + # message larger than the preferred max bytes is received, then its batch + # will contain only that message. Because messages may be larger than + # preferred max bytes (up to AbsoluteMaxBytes), some batches may exceed + # the preferred max bytes, but will always contain exactly one transaction. + PreferredMaxBytes: 2 MB + + # Max Channels is the maximum number of channels to allow on the ordering + # network. When set to 0, this implies no maximum number of channels. + MaxChannels: 0 + + Kafka: + # Brokers: A list of Kafka brokers to which the orderer connects. Edit + # this list to identify the brokers of the ordering service. + # NOTE: Use IP:port notation. + Brokers: + - kafka0:9092 + - kafka1:9092 + - kafka2:9092 + + # EtcdRaft defines configuration which must be set when the "etcdraft" + # orderertype is chosen. + EtcdRaft: + # The set of Raft replicas for this network. For the etcd/raft-based + # implementation, we expect every replica to also be an OSN. Therefore, + # a subset of the host:port items enumerated in this list should be + # replicated under the Orderer.Addresses key above. + Consenters: + - Host: raft0.example.com + Port: 7050 + ClientTLSCert: path/to/ClientTLSCert0 + ServerTLSCert: path/to/ServerTLSCert0 + - Host: raft1.example.com + Port: 7050 + ClientTLSCert: path/to/ClientTLSCert1 + ServerTLSCert: path/to/ServerTLSCert1 + - Host: raft2.example.com + Port: 7050 + ClientTLSCert: path/to/ClientTLSCert2 + ServerTLSCert: path/to/ServerTLSCert2 + + # Options to be specified for all the etcd/raft nodes. The values here + # are the defaults for all new channels and can be modified on a + # per-channel basis via configuration updates. + Options: + # TickInterval is the time interval between two Node.Tick invocations. + TickInterval: 500ms + + # ElectionTick is the number of Node.Tick invocations that must pass + # between elections. That is, if a follower does not receive any + # message from the leader of current term before ElectionTick has + # elapsed, it will become candidate and start an election. + # ElectionTick must be greater than HeartbeatTick. + ElectionTick: 10 + + # HeartbeatTick is the number of Node.Tick invocations that must + # pass between heartbeats. That is, a leader sends heartbeat + # messages to maintain its leadership every HeartbeatTick ticks. + HeartbeatTick: 1 + + # MaxInflightBlocks limits the max number of in-flight append messages + # during optimistic replication phase. + MaxInflightBlocks: 5 + + # SnapshotIntervalSize defines number of bytes per which a snapshot is taken + SnapshotIntervalSize: 16 MB + + # Organizations lists the orgs participating on the orderer side of the + # network. + Organizations: + + # Policies defines the set of policies at this level of the config tree + # For Orderer policies, their canonical path is + # /Channel/Orderer/ + Policies: + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + # BlockValidation specifies what signatures must be included in the block + # from the orderer for the peer to validate it. + BlockValidation: + Type: ImplicitMeta + Rule: "ANY Writers" + + # Capabilities describes the orderer level capabilities, see the + # dedicated Capabilities section elsewhere in this file for a full + # description + Capabilities: + <<: *OrdererCapabilities + +################################################################################ +# +# CHANNEL +# +# This section defines the values to encode into a config transaction or +# genesis block for channel related parameters. +# +################################################################################ +Channel: &ChannelDefaults + # Policies defines the set of policies at this level of the config tree + # For Channel policies, their canonical path is + # /Channel/ + Policies: + # Who may invoke the 'Deliver' API + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + # Who may invoke the 'Broadcast' API + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + # By default, who may modify elements at this config level + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + + + # Capabilities describes the channel level capabilities, see the + # dedicated Capabilities section elsewhere in this file for a full + # description + Capabilities: + <<: *ChannelCapabilities + +################################################################################ +# +# PROFILES +# +# Different configuration profiles may be encoded here to be specified as +# parameters to the configtxgen tool. The profiles which specify consortiums +# are to be used for generating the orderer genesis block. With the correct +# consortium members defined in the orderer genesis block, channel creation +# requests may be generated with only the org member names and a consortium +# name. +# +################################################################################ +Profiles: + + # SampleSingleMSPSolo defines a configuration which uses the Solo orderer, + # and contains a single MSP definition (the MSP sampleconfig). + # The Consortium SampleConsortium has only a single member, SampleOrg. + SampleSingleMSPSolo: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + Organizations: + - *SampleOrg + Consortiums: + SampleConsortium: + Organizations: + - *SampleOrg + + # SampleSingleMSPKafka defines a configuration that differs from the + # SampleSingleMSPSolo one only in that it uses the Kafka-based orderer. + SampleSingleMSPKafka: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + OrdererType: kafka + Organizations: + - *SampleOrg + Consortiums: + SampleConsortium: + Organizations: + - *SampleOrg + + # SampleInsecureSolo defines a configuration which uses the Solo orderer, + # contains no MSP definitions, and allows all transactions and channel + # creation requests for the consortium SampleConsortium. + SampleInsecureSolo: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + Consortiums: + SampleConsortium: + Organizations: + + # SampleInsecureKafka defines a configuration that differs from the + # SampleInsecureSolo one only in that it uses the Kafka-based orderer. + SampleInsecureKafka: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + OrdererType: kafka + Consortiums: + SampleConsortium: + Organizations: + + # SampleDevModeSolo defines a configuration which uses the Solo orderer, + # contains the sample MSP as both orderer and consortium member, and + # requires only basic membership for admin privileges. It also defines + # an Application on the ordering system channel, which should usually + # be avoided. + SampleDevModeSolo: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + Application: + <<: *ApplicationDefaults + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + Consortiums: + SampleConsortium: + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + + # SampleDevModeKafka defines a configuration that differs from the + # SampleDevModeSolo one only in that it uses the Kafka-based orderer. + SampleDevModeKafka: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + OrdererType: kafka + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + Application: + <<: *ApplicationDefaults + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + Consortiums: + SampleConsortium: + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + + # SampleSingleMSPChannel defines a channel with only the sample org as a + # member. It is designed to be used in conjunction with SampleSingleMSPSolo + # and SampleSingleMSPKafka orderer profiles. Note, for channel creation + # profiles, only the 'Application' section and consortium # name are + # considered. + SampleSingleMSPChannel: + <<: *ChannelDefaults + Consortium: SampleConsortium + Application: + <<: *ApplicationDefaults + Organizations: + - <<: *SampleOrg + + # SampleDevModeEtcdRaft defines a configuration that differs from the + # SampleDevModeSolo one only in that it uses the etcd/raft-based orderer. + SampleDevModeEtcdRaft: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + OrdererType: etcdraft + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + Application: + <<: *ApplicationDefaults + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + Consortiums: + SampleConsortium: + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + + # SampleAppChannelInsecureSolo defines an application channel configuration + # which uses the Solo orderer and contains no MSP definitions. + SampleAppChannelInsecureSolo: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + Application: + <<: *ApplicationDefaults + + # SampleAppChannelEtcdRaft defines an application channel configuration + # that uses the etcd/raft-based orderer. + SampleAppChannelEtcdRaft: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + OrdererType: etcdraft + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" + Application: + <<: *ApplicationDefaults + Organizations: + - <<: *SampleOrg + Policies: + <<: *SampleOrgPolicies + Admins: + Type: Signature + Rule: "OR('SampleOrg.member')" diff --git a/sample-network-multi-org/config/core.yaml b/sample-network-multi-org/config/core.yaml new file mode 100644 index 00000000..7809b001 --- /dev/null +++ b/sample-network-multi-org/config/core.yaml @@ -0,0 +1,800 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################### +# +# Peer section +# +############################################################################### +peer: + + # The peer id provides a name for this peer instance and is used when + # naming docker resources. + id: jdoe + + # The networkId allows for logical separation of networks and is used when + # naming docker resources. + networkId: dev + + # The Address at local network interface this Peer will listen on. + # By default, it will listen on all network interfaces + listenAddress: 0.0.0.0:7051 + + # The endpoint this peer uses to listen for inbound chaincode connections. + # If this is commented-out, the listen address is selected to be + # the peer's address (see below) with port 7052 + # chaincodeListenAddress: 0.0.0.0:7052 + + # The endpoint the chaincode for this peer uses to connect to the peer. + # If this is not specified, the chaincodeListenAddress address is selected. + # And if chaincodeListenAddress is not specified, address is selected from + # peer address (see below). If specified peer address is invalid then it + # will fallback to the auto detected IP (local IP) regardless of the peer + # addressAutoDetect value. + # chaincodeAddress: 0.0.0.0:7052 + + # When used as peer config, this represents the endpoint to other peers + # in the same organization. For peers in other organization, see + # gossip.externalEndpoint for more info. + # When used as CLI config, this means the peer's endpoint to interact with + address: 0.0.0.0:7051 + + # Whether the Peer should programmatically determine its address + # This case is useful for docker containers. + # When set to true, will override peer address. + addressAutoDetect: false + + # Settings for the Peer's gateway server. + gateway: + # Whether the gateway is enabled for this Peer. + enabled: true + # endorsementTimeout is the duration the gateway waits for a response + # from other endorsing peers before returning a timeout error to the client. + endorsementTimeout: 30s + # broadcastTimeout is the duration the gateway waits for a response + # from ordering nodes before returning a timeout error to the client. + broadcastTimeout: 30s + # dialTimeout is the duration the gateway waits for a connection + # to other network nodes. + dialTimeout: 2m + + + # Keepalive settings for peer server and clients + keepalive: + # Interval is the duration after which if the server does not see + # any activity from the client it pings the client to see if it's alive + interval: 7200s + # Timeout is the duration the server waits for a response + # from the client after sending a ping before closing the connection + timeout: 20s + # MinInterval is the minimum permitted time between client pings. + # If clients send pings more frequently, the peer server will + # disconnect them + minInterval: 60s + # Client keepalive settings for communicating with other peer nodes + client: + # Interval is the time between pings to peer nodes. This must + # greater than or equal to the minInterval specified by peer + # nodes + interval: 60s + # Timeout is the duration the client waits for a response from + # peer nodes before closing the connection + timeout: 20s + # DeliveryClient keepalive settings for communication with ordering + # nodes. + deliveryClient: + # Interval is the time between pings to ordering nodes. This must + # greater than or equal to the minInterval specified by ordering + # nodes. + interval: 60s + # Timeout is the duration the client waits for a response from + # ordering nodes before closing the connection + timeout: 20s + + + # Gossip related configuration + gossip: + # Bootstrap set to initialize gossip with. + # This is a list of other peers that this peer reaches out to at startup. + # Important: The endpoints here have to be endpoints of peers in the same + # organization, because the peer would refuse connecting to these endpoints + # unless they are in the same organization as the peer. + bootstrap: 127.0.0.1:7051 + + # NOTE: orgLeader and useLeaderElection parameters are mutual exclusive. + # Setting both to true would result in the termination of the peer + # since this is undefined state. If the peers are configured with + # useLeaderElection=false, make sure there is at least 1 peer in the + # organization that its orgLeader is set to true. + + # Defines whenever peer will initialize dynamic algorithm for + # "leader" selection, where leader is the peer to establish + # connection with ordering service and use delivery protocol + # to pull ledger blocks from ordering service. + useLeaderElection: false + # Statically defines peer to be an organization "leader", + # where this means that current peer will maintain connection + # with ordering service and disseminate block across peers in + # its own organization. Multiple peers or all peers in an organization + # may be configured as org leaders, so that they all pull + # blocks directly from ordering service. + orgLeader: true + + # Interval for membershipTracker polling + membershipTrackerInterval: 5s + + # Overrides the endpoint that the peer publishes to peers + # in its organization. For peers in foreign organizations + # see 'externalEndpoint' + endpoint: + # Maximum count of blocks stored in memory + maxBlockCountToStore: 10 + # Max time between consecutive message pushes(unit: millisecond) + maxPropagationBurstLatency: 10ms + # Max number of messages stored until a push is triggered to remote peers + maxPropagationBurstSize: 10 + # Number of times a message is pushed to remote peers + propagateIterations: 1 + # Number of peers selected to push messages to + propagatePeerNum: 3 + # Determines frequency of pull phases(unit: second) + # Must be greater than digestWaitTime + responseWaitTime + pullInterval: 4s + # Number of peers to pull from + pullPeerNum: 3 + # Determines frequency of pulling state info messages from peers(unit: second) + requestStateInfoInterval: 4s + # Determines frequency of pushing state info messages to peers(unit: second) + publishStateInfoInterval: 4s + # Maximum time a stateInfo message is kept until expired + stateInfoRetentionInterval: + # Time from startup certificates are included in Alive messages(unit: second) + publishCertPeriod: 10s + # Should we skip verifying block messages or not (currently not in use) + skipBlockVerification: false + # Dial timeout(unit: second) + dialTimeout: 3s + # Connection timeout(unit: second) + connTimeout: 2s + # Buffer size of received messages + recvBuffSize: 20 + # Buffer size of sending messages + sendBuffSize: 200 + # Time to wait before pull engine processes incoming digests (unit: second) + # Should be slightly smaller than requestWaitTime + digestWaitTime: 1s + # Time to wait before pull engine removes incoming nonce (unit: milliseconds) + # Should be slightly bigger than digestWaitTime + requestWaitTime: 1500ms + # Time to wait before pull engine ends pull (unit: second) + responseWaitTime: 2s + # Alive check interval(unit: second) + aliveTimeInterval: 5s + # Alive expiration timeout(unit: second) + aliveExpirationTimeout: 25s + # Reconnect interval(unit: second) + reconnectInterval: 25s + # Max number of attempts to connect to a peer + maxConnectionAttempts: 120 + # Message expiration factor for alive messages + msgExpirationFactor: 20 + # This is an endpoint that is published to peers outside of the organization. + # If this isn't set, the peer will not be known to other organizations and will not be exposed via service discovery. + externalEndpoint: + # Leader election service configuration + election: + # Longest time peer waits for stable membership during leader election startup (unit: second) + startupGracePeriod: 15s + # Interval gossip membership samples to check its stability (unit: second) + membershipSampleInterval: 1s + # Time passes since last declaration message before peer decides to perform leader election (unit: second) + leaderAliveThreshold: 10s + # Time between peer sends propose message and declares itself as a leader (sends declaration message) (unit: second) + leaderElectionDuration: 5s + + pvtData: + # pullRetryThreshold determines the maximum duration of time private data corresponding for a given block + # would be attempted to be pulled from peers until the block would be committed without the private data + pullRetryThreshold: 60s + # As private data enters the transient store, it is associated with the peer's ledger's height at that time. + # transientstoreMaxBlockRetention defines the maximum difference between the current ledger's height upon commit, + # and the private data residing inside the transient store that is guaranteed not to be purged. + # Private data is purged from the transient store when blocks with sequences that are multiples + # of transientstoreMaxBlockRetention are committed. + transientstoreMaxBlockRetention: 1000 + # pushAckTimeout is the maximum time to wait for an acknowledgement from each peer + # at private data push at endorsement time. + pushAckTimeout: 3s + # Block to live pulling margin, used as a buffer + # to prevent peer from trying to pull private data + # from peers that is soon to be purged in next N blocks. + # This helps a newly joined peer catch up to current + # blockchain height quicker. + btlPullMargin: 10 + # the process of reconciliation is done in an endless loop, while in each iteration reconciler tries to + # pull from the other peers the most recent missing blocks with a maximum batch size limitation. + # reconcileBatchSize determines the maximum batch size of missing private data that will be reconciled in a + # single iteration. + reconcileBatchSize: 10 + # reconcileSleepInterval determines the time reconciler sleeps from end of an iteration until the beginning + # of the next reconciliation iteration. + reconcileSleepInterval: 1m + # reconciliationEnabled is a flag that indicates whether private data reconciliation is enable or not. + reconciliationEnabled: true + # skipPullingInvalidTransactionsDuringCommit is a flag that indicates whether pulling of invalid + # transaction's private data from other peers need to be skipped during the commit time and pulled + # only through reconciler. + skipPullingInvalidTransactionsDuringCommit: false + # implicitCollectionDisseminationPolicy specifies the dissemination policy for the peer's own implicit collection. + # When a peer endorses a proposal that writes to its own implicit collection, below values override the default values + # for disseminating private data. + # Note that it is applicable to all channels the peer has joined. The implication is that requiredPeerCount has to + # be smaller than the number of peers in a channel that has the lowest numbers of peers from the organization. + implicitCollectionDisseminationPolicy: + # requiredPeerCount defines the minimum number of eligible peers to which the peer must successfully + # disseminate private data for its own implicit collection during endorsement. Default value is 0. + requiredPeerCount: 0 + # maxPeerCount defines the maximum number of eligible peers to which the peer will attempt to + # disseminate private data for its own implicit collection during endorsement. Default value is 1. + maxPeerCount: 1 + + # Gossip state transfer related configuration + state: + # indicates whenever state transfer is enabled or not + # default value is false, i.e. state transfer is active + # and takes care to sync up missing blocks allowing + # lagging peer to catch up to speed with rest network. + # Keep in mind that when peer.gossip.useLeaderElection is true + # and there are several peers in the organization, + # or peer.gossip.useLeaderElection is false alongside with + # peer.gossip.orgleader being false, the peer's ledger may lag behind + # the rest of the peers and will never catch up due to state transfer + # being disabled. + enabled: false + # checkInterval interval to check whether peer is lagging behind enough to + # request blocks via state transfer from another peer. + checkInterval: 10s + # responseTimeout amount of time to wait for state transfer response from + # other peers + responseTimeout: 3s + # batchSize the number of blocks to request via state transfer from another peer + batchSize: 10 + # blockBufferSize reflects the size of the re-ordering buffer + # which captures blocks and takes care to deliver them in order + # down to the ledger layer. The actual buffer size is bounded between + # 0 and 2*blockBufferSize, each channel maintains its own buffer + blockBufferSize: 20 + # maxRetries maximum number of re-tries to ask + # for single state transfer request + maxRetries: 3 + + # TLS Settings + tls: + # Require server-side TLS + enabled: false + # Require client certificates / mutual TLS for inbound connections. + # Note that clients that are not configured to use a certificate will + # fail to connect to the peer. + clientAuthRequired: false + # X.509 certificate used for TLS server + cert: + file: tls/server.crt + # Private key used for TLS server + key: + file: tls/server.key + # rootcert.file represents the trusted root certificate chain used for verifying certificates + # of other nodes during outbound connections. + # It is not required to be set, but can be used to augment the set of TLS CA certificates + # available from the MSPs of each channel’s configuration. + rootcert: + file: tls/ca.crt + # If mutual TLS is enabled, clientRootCAs.files contains a list of additional root certificates + # used for verifying certificates of client connections. + # It augments the set of TLS CA certificates available from the MSPs of each channel’s configuration. + # Minimally, set your organization's TLS CA root certificate so that the peer can receive join channel requests. + clientRootCAs: + files: + - tls/ca.crt + # Private key used for TLS when making client connections. + # If not set, peer.tls.key.file will be used instead + clientKey: + file: + # X.509 certificate used for TLS when making client connections. + # If not set, peer.tls.cert.file will be used instead + clientCert: + file: + + # Authentication contains configuration parameters related to authenticating + # client messages + authentication: + # the acceptable difference between the current server time and the + # client's time as specified in a client request message + timewindow: 15m + + # Path on the file system where peer will store data (eg ledger). This + # location must be access control protected to prevent unintended + # modification that might corrupt the peer operations. + # The path may be relative to FABRIC_CFG_PATH or an absolute path. + fileSystemPath: /var/hyperledger/production + + # BCCSP (Blockchain crypto provider): Select which crypto implementation or + # library to use + BCCSP: + Default: SW + # Settings for the SW crypto provider (i.e. when DEFAULT: SW) + SW: + # TODO: The default Hash and Security level needs refactoring to be + # fully configurable. Changing these defaults requires coordination + # SHA2 is hardcoded in several places, not only BCCSP + Hash: SHA2 + Security: 256 + # Location of Key Store + FileKeyStore: + # If "", defaults to 'mspConfigPath'/keystore + KeyStore: + # Settings for the PKCS#11 crypto provider (i.e. when DEFAULT: PKCS11) + PKCS11: + # Location of the PKCS11 module library + Library: + # Token Label + Label: + # User PIN + Pin: + Hash: + Security: + SoftwareVerify: + Immutable: + AltID: + KeyIds: + + # Path on the file system where peer will find MSP local configurations + # The path may be relative to FABRIC_CFG_PATH or an absolute path. + mspConfigPath: msp + + # Identifier of the local MSP + # ----!!!!IMPORTANT!!!-!!!IMPORTANT!!!-!!!IMPORTANT!!!!---- + # Deployers need to change the value of the localMspId string. + # In particular, the name of the local MSP ID of a peer needs + # to match the name of one of the MSPs in each of the channel + # that this peer is a member of. Otherwise this peer's messages + # will not be identified as valid by other nodes. + localMspId: SampleOrg + + # CLI common client config options + client: + # connection timeout + connTimeout: 3s + + # Delivery service related config + deliveryclient: + # Enables this peer to disseminate blocks it pulled from the ordering service + # via gossip. + # Note that 'gossip.state.enabled' controls point to point block replication + # of blocks committed in the past. + blockGossipEnabled: true + # It sets the total time the delivery service may spend in reconnection + # attempts until its retry logic gives up and returns an error, + # ignored if peer is a static leader + reconnectTotalTimeThreshold: 3600s + + # It sets the delivery service <-> ordering service node connection timeout + connTimeout: 3s + + # It sets the delivery service maximal delay between consecutive retries. + # Time between retries will have exponential backoff until hitting this threshold. + reConnectBackoffThreshold: 3600s + + # A list of orderer endpoint addresses which should be overridden + # when found in channel configurations. + addressOverrides: + # - from: + # to: + # caCertsFile: + # - from: + # to: + # caCertsFile: + + # Type for the local MSP - by default it's of type bccsp + localMspType: bccsp + + # Used with Go profiling tools only in none production environment. In + # production, it should be disabled (eg enabled: false) + profile: + enabled: false + listenAddress: 0.0.0.0:6060 + + # Handlers defines custom handlers that can filter and mutate + # objects passing within the peer, such as: + # Auth filter - reject or forward proposals from clients + # Decorators - append or mutate the chaincode input passed to the chaincode + # Endorsers - Custom signing over proposal response payload and its mutation + # Valid handler definition contains: + # - A name which is a factory method name defined in + # core/handlers/library/library.go for statically compiled handlers + # - library path to shared object binary for pluggable filters + # Auth filters and decorators are chained and executed in the order that + # they are defined. For example: + # authFilters: + # - + # name: FilterOne + # library: /opt/lib/filter.so + # - + # name: FilterTwo + # decorators: + # - + # name: DecoratorOne + # - + # name: DecoratorTwo + # library: /opt/lib/decorator.so + # Endorsers are configured as a map that its keys are the endorsement system chaincodes that are being overridden. + # Below is an example that overrides the default ESCC and uses an endorsement plugin that has the same functionality + # as the default ESCC. + # If the 'library' property is missing, the name is used as the constructor method in the builtin library similar + # to auth filters and decorators. + # endorsers: + # escc: + # name: DefaultESCC + # library: /etc/hyperledger/fabric/plugin/escc.so + handlers: + authFilters: + - + name: DefaultAuth + - + name: ExpirationCheck # This filter checks identity x509 certificate expiration + decorators: + - + name: DefaultDecorator + endorsers: + escc: + name: DefaultEndorsement + library: + validators: + vscc: + name: DefaultValidation + library: + + # library: /etc/hyperledger/fabric/plugin/escc.so + # Number of goroutines that will execute transaction validation in parallel. + # By default, the peer chooses the number of CPUs on the machine. Set this + # variable to override that choice. + # NOTE: overriding this value might negatively influence the performance of + # the peer so please change this value only if you know what you're doing + validatorPoolSize: + + # The discovery service is used by clients to query information about peers, + # such as - which peers have joined a certain channel, what is the latest + # channel config, and most importantly - given a chaincode and a channel, + # what possible sets of peers satisfy the endorsement policy. + discovery: + enabled: true + # Whether the authentication cache is enabled or not. + authCacheEnabled: true + # The maximum size of the cache, after which a purge takes place + authCacheMaxSize: 1000 + # The proportion (0 to 1) of entries that remain in the cache after the cache is purged due to overpopulation + authCachePurgeRetentionRatio: 0.75 + # Whether to allow non-admins to perform non channel scoped queries. + # When this is false, it means that only peer admins can perform non channel scoped queries. + orgMembersAllowedAccess: false + + # Limits is used to configure some internal resource limits. + limits: + # Concurrency limits the number of concurrently running requests to a service on each peer. + # Currently this option is only applied to endorser service and deliver service. + # When the property is missing or the value is 0, the concurrency limit is disabled for the service. + concurrency: + # endorserService limits concurrent requests to endorser service that handles chaincode deployment, query and invocation, + # including both user chaincodes and system chaincodes. + endorserService: 2500 + # deliverService limits concurrent event listeners registered to deliver service for blocks and transaction events. + deliverService: 2500 + # gatewayService limits concurrent requests to gateway service that handles the submission and evaluation of transactions. + gatewayService: 500 + + # Since all nodes should be consistent it is recommended to keep + # the default value of 100MB for MaxRecvMsgSize & MaxSendMsgSize + # Max message size in bytes GRPC server and client can receive + maxRecvMsgSize: 104857600 + # Max message size in bytes GRPC server and client can send + maxSendMsgSize: 104857600 + +############################################################################### +# +# VM section +# +############################################################################### +vm: + + # Endpoint of the vm management system. For docker can be one of the following in general + # unix:///var/run/docker.sock + # http://localhost:2375 + # https://localhost:2376 + # If you utilize external chaincode builders and don't need the default Docker chaincode builder, + # the endpoint should be unconfigured so that the peer's Docker health checker doesn't get registered. + endpoint: unix:///var/run/docker.sock + + # settings for docker vms + docker: + tls: + enabled: false + ca: + file: docker/ca.crt + cert: + file: docker/tls.crt + key: + file: docker/tls.key + + # Enables/disables the standard out/err from chaincode containers for + # debugging purposes + attachStdout: false + + # Parameters on creating docker container. + # Container may be efficiently created using ipam & dns-server for cluster + # NetworkMode - sets the networking mode for the container. Supported + # standard values are: `host`(default),`bridge`,`ipvlan`,`none`. + # Dns - a list of DNS servers for the container to use. + # Note: `Privileged` `Binds` `Links` and `PortBindings` properties of + # Docker Host Config are not supported and will not be used if set. + # LogConfig - sets the logging driver (Type) and related options + # (Config) for Docker. For more info, + # https://docs.docker.com/engine/admin/logging/overview/ + # Note: Set LogConfig using Environment Variables is not supported. + hostConfig: + NetworkMode: host + Dns: + # - 192.168.0.1 + LogConfig: + Type: json-file + Config: + max-size: "50m" + max-file: "5" + Memory: 2147483648 + +############################################################################### +# +# Chaincode section +# +############################################################################### +chaincode: + + # The id is used by the Chaincode stub to register the executing Chaincode + # ID with the Peer and is generally supplied through ENV variables + # the `path` form of ID is provided when installing the chaincode. + # The `name` is used for all other requests and can be any string. + id: + path: + name: + + # Generic builder environment, suitable for most chaincode types + builder: $(DOCKER_NS)/fabric-ccenv:$(TWO_DIGIT_VERSION) + + # Enables/disables force pulling of the base docker images (listed below) + # during user chaincode instantiation. + # Useful when using moving image tags (such as :latest) + pull: false + + golang: + # golang will never need more than baseos + runtime: $(DOCKER_NS)/fabric-baseos:$(TWO_DIGIT_VERSION) + + # whether or not golang chaincode should be linked dynamically + dynamicLink: false + + java: + # This is an image based on java:openjdk-8 with addition compiler + # tools added for java shim layer packaging. + # This image is packed with shim layer libraries that are necessary + # for Java chaincode runtime. + runtime: $(DOCKER_NS)/fabric-javaenv:$(TWO_DIGIT_VERSION) + + node: + # This is an image based on node:$(NODE_VER)-alpine + runtime: $(DOCKER_NS)/fabric-nodeenv:$(TWO_DIGIT_VERSION) + + # List of directories to treat as external builders and launchers for + # chaincode. The external builder detection processing will iterate over the + # builders in the order specified below. + # If you don't need to fallback to the default Docker builder, also unconfigure vm.endpoint above. + # To override this property via env variable use CORE_CHAINCODE_EXTERNALBUILDERS: [{name: x, path: dir1}, {name: y, path: dir2}] + # The path must be an absolute path. + externalBuilders: + - name: ccaas_builder + path: /opt/hyperledger/ccaas_builder + propagateEnvironment: + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG + + + # The maximum duration to wait for the chaincode build and install process + # to complete. + installTimeout: 300s + + # Timeout duration for starting up a container and waiting for Register + # to come through. + startuptimeout: 300s + + # Timeout duration for Invoke and Init calls to prevent runaway. + # This timeout is used by all chaincodes in all the channels, including + # system chaincodes. + # Note that during Invoke, if the image is not available (e.g. being + # cleaned up when in development environment), the peer will automatically + # build the image, which might take more time. In production environment, + # the chaincode image is unlikely to be deleted, so the timeout could be + # reduced accordingly. + executetimeout: 30s + + # There are 2 modes: "dev" and "net". + # In dev mode, user runs the chaincode after starting peer from + # command line on local machine. + # In net mode, peer will run chaincode in a docker container. + mode: net + + # keepalive in seconds. In situations where the communication goes through a + # proxy that does not support keep-alive, this parameter will maintain connection + # between peer and chaincode. + # A value <= 0 turns keepalive off + keepalive: 0 + + # enabled system chaincodes + system: + _lifecycle: enable + cscc: enable + lscc: enable + qscc: enable + + # Logging section for the chaincode container + logging: + # Default level for all loggers within the chaincode container + level: info + # Override default level for the 'shim' logger + shim: warning + # Format for the chaincode container logs + format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' + +############################################################################### +# +# Ledger section - ledger configuration encompasses both the blockchain +# and the state +# +############################################################################### +ledger: + + blockchain: + + state: + # stateDatabase - options are "goleveldb", "CouchDB" + # goleveldb - default state database stored in goleveldb. + # CouchDB - store state database in CouchDB + stateDatabase: goleveldb + # Limit on the number of records to return per query + totalQueryLimit: 100000 + couchDBConfig: + # It is recommended to run CouchDB on the same server as the peer, and + # not map the CouchDB container port to a server port in docker-compose. + # Otherwise proper security must be provided on the connection between + # CouchDB client (on the peer) and server. + couchDBAddress: 127.0.0.1:5984 + # This username must have read and write authority on CouchDB + username: + # The password is recommended to pass as an environment variable + # during start up (eg CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD). + # If it is stored here, the file must be access control protected + # to prevent unintended users from discovering the password. + password: + # Number of retries for CouchDB errors + maxRetries: 3 + # Number of retries for CouchDB errors during peer startup. + # The delay between retries doubles for each attempt. + # Default of 10 retries results in 11 attempts over 2 minutes. + maxRetriesOnStartup: 10 + # CouchDB request timeout (unit: duration, e.g. 20s) + requestTimeout: 35s + # Limit on the number of records per each CouchDB query + # Note that chaincode queries are only bound by totalQueryLimit. + # Internally the chaincode may execute multiple CouchDB queries, + # each of size internalQueryLimit. + internalQueryLimit: 1000 + # Limit on the number of records per CouchDB bulk update batch + maxBatchUpdateSize: 1000 + # Create the _global_changes system database + # This is optional. Creating the global changes database will require + # additional system resources to track changes and maintain the database + createGlobalChangesDB: false + # CacheSize denotes the maximum mega bytes (MB) to be allocated for the in-memory state + # cache. Note that CacheSize needs to be a multiple of 32 MB. If it is not a multiple + # of 32 MB, the peer would round the size to the next multiple of 32 MB. + # To disable the cache, 0 MB needs to be assigned to the cacheSize. + cacheSize: 64 + + history: + # enableHistoryDatabase - options are true or false + # Indicates if the history of key updates should be stored. + # All history 'index' will be stored in goleveldb, regardless if using + # CouchDB or alternate database for the state. + enableHistoryDatabase: true + + pvtdataStore: + # the maximum db batch size for converting + # the ineligible missing data entries to eligible missing data entries + collElgProcMaxDbBatchSize: 5000 + # the minimum duration (in milliseconds) between writing + # two consecutive db batches for converting the ineligible missing data entries to eligible missing data entries + collElgProcDbBatchesInterval: 1000 + # The missing data entries are classified into two categories: + # (1) prioritized + # (2) deprioritized + # Initially, all missing data are in the prioritized list. When the + # reconciler is unable to fetch the missing data from other peers, + # the unreconciled missing data would be moved to the deprioritized list. + # The reconciler would retry deprioritized missing data after every + # deprioritizedDataReconcilerInterval (unit: minutes). Note that the + # interval needs to be greater than the reconcileSleepInterval + deprioritizedDataReconcilerInterval: 60m + # The frequency to purge private data (in number of blocks). + # Private data is purged from the peer's private data store based on + # the collection property blockToLive or an explicit chaincode call to PurgePrivateData(). + purgeInterval: 100 + # Whether to log private data keys purged from private data store (INFO level) when explicitly purged via chaincode + purgedKeyAuditLogging: true + + snapshots: + # Path on the file system where peer will store ledger snapshots + # The path must be an absolute path. + rootDir: /var/hyperledger/production/snapshots + +############################################################################### +# +# Operations section +# +############################################################################### +operations: + # host and port for the operations server + listenAddress: 127.0.0.1:9443 + + # TLS configuration for the operations endpoint + tls: + # TLS enabled + enabled: false + + # path to PEM encoded server certificate for the operations server + # The paths in this section may be relative to FABRIC_CFG_PATH or an absolute path. + cert: + file: + + # path to PEM encoded server key for the operations server + key: + file: + + # most operations service endpoints require client authentication when TLS + # is enabled. clientAuthRequired requires client certificate authentication + # at the TLS layer to access all resources. + clientAuthRequired: false + + # paths to PEM encoded ca certificates to trust for client authentication + clientRootCAs: + files: [] + +############################################################################### +# +# Metrics section +# +############################################################################### +metrics: + # metrics provider is one of statsd, prometheus, or disabled + provider: disabled + + # statsd configuration + statsd: + # network type: tcp or udp + network: udp + + # statsd server address + address: 127.0.0.1:8125 + + # the interval at which locally cached counters and gauges are pushed + # to statsd; timings are pushed immediately + writeInterval: 10s + + # prefix is prepended to all emitted statsd metrics + prefix: diff --git a/sample-network-multi-org/config/orderer.yaml b/sample-network-multi-org/config/orderer.yaml new file mode 100644 index 00000000..6c555f93 --- /dev/null +++ b/sample-network-multi-org/config/orderer.yaml @@ -0,0 +1,427 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +--- +################################################################################ +# +# Orderer Configuration +# +# - This controls the type and configuration of the orderer. +# +################################################################################ +General: + # Listen address: The IP on which to bind to listen. + ListenAddress: 127.0.0.1 + + # Listen port: The port on which to bind to listen. + ListenPort: 7050 + + # TLS: TLS settings for the GRPC server. + TLS: + # Require server-side TLS + Enabled: false + # PrivateKey governs the file location of the private key of the TLS certificate. + PrivateKey: tls/server.key + # Certificate governs the file location of the server TLS certificate. + Certificate: tls/server.crt + # RootCAs contains a list of additional root certificates used for verifying certificates + # of other orderer nodes during outbound connections. + # It is not required to be set, but can be used to augment the set of TLS CA certificates + # available from the MSPs of each channel’s configuration. + RootCAs: + - tls/ca.crt + # Require client certificates / mutual TLS for inbound connections. + ClientAuthRequired: false + # If mutual TLS is enabled, ClientRootCAs contains a list of additional root certificates + # used for verifying certificates of client connections. + # It is not required to be set, but can be used to augment the set of TLS CA certificates + # available from the MSPs of each channel’s configuration. + ClientRootCAs: + # Keepalive settings for the GRPC server. + Keepalive: + # ServerMinInterval is the minimum permitted time between client pings. + # If clients send pings more frequently, the server will + # disconnect them. + ServerMinInterval: 60s + # ServerInterval is the time between pings to clients. + ServerInterval: 7200s + # ServerTimeout is the duration the server waits for a response from + # a client before closing the connection. + ServerTimeout: 20s + + # Since all nodes should be consistent it is recommended to keep + # the default value of 100MB for MaxRecvMsgSize & MaxSendMsgSize + # Max message size in bytes the GRPC server and client can receive + MaxRecvMsgSize: 104857600 + # Max message size in bytes the GRPC server and client can send + MaxSendMsgSize: 104857600 + + # Cluster settings for ordering service nodes that communicate with other ordering service nodes + # such as Raft based ordering service. + Cluster: + # SendBufferSize is the maximum number of messages in the egress buffer. + # Consensus messages are dropped if the buffer is full, and transaction + # messages are waiting for space to be freed. + SendBufferSize: 100 + + # ClientCertificate governs the file location of the client TLS certificate + # used to establish mutual TLS connections with other ordering service nodes. + # If not set, the server General.TLS.Certificate is re-used. + ClientCertificate: + # ClientPrivateKey governs the file location of the private key of the client TLS certificate. + # If not set, the server General.TLS.PrivateKey is re-used. + ClientPrivateKey: + + # The below 4 properties should be either set together, or be unset together. + # If they are set, then the orderer node uses a separate listener for intra-cluster + # communication. If they are unset, then the general orderer listener is used. + # This is useful if you want to use a different TLS server certificates on the + # client-facing and the intra-cluster listeners. + + # ListenPort defines the port on which the cluster listens to connections. + ListenPort: + # ListenAddress defines the IP on which to listen to intra-cluster communication. + ListenAddress: + # ServerCertificate defines the file location of the server TLS certificate used for intra-cluster + # communication. + ServerCertificate: + # ServerPrivateKey defines the file location of the private key of the TLS certificate. + ServerPrivateKey: + + # Bootstrap method: The method by which to obtain the bootstrap block + # system channel is specified. The option can be one of: + # "file" - path to a file containing the genesis block or config block of system channel + # "none" - allows an orderer to start without a system channel configuration + BootstrapMethod: file + + # Bootstrap file: The file containing the bootstrap block to use when + # initializing the orderer system channel and BootstrapMethod is set to + # "file". The bootstrap file can be the genesis block, and it can also be + # a config block for late bootstrap of some consensus methods like Raft. + # Generate a genesis block by updating $FABRIC_CFG_PATH/configtx.yaml and + # using configtxgen command with "-outputBlock" option. + # Defaults to file "genesisblock" (in $FABRIC_CFG_PATH directory) if not specified. + BootstrapFile: + + # LocalMSPDir is where to find the private crypto material needed by the + # orderer. It is set relative here as a default for dev environments but + # should be changed to the real location in production. + LocalMSPDir: msp + + # LocalMSPID is the identity to register the local MSP material with the MSP + # manager. IMPORTANT: The local MSP ID of an orderer needs to match the MSP + # ID of one of the organizations defined in the orderer system channel's + # /Channel/Orderer configuration. The sample organization defined in the + # sample configuration provided has an MSP ID of "SampleOrg". + LocalMSPID: SampleOrg + + # Enable an HTTP service for Go "pprof" profiling as documented at: + # https://golang.org/pkg/net/http/pprof + Profile: + Enabled: false + Address: 0.0.0.0:6060 + + # BCCSP configures the blockchain crypto service providers. + BCCSP: + # Default specifies the preferred blockchain crypto service provider + # to use. If the preferred provider is not available, the software + # based provider ("SW") will be used. + # Valid providers are: + # - SW: a software based crypto provider + # - PKCS11: a CA hardware security module crypto provider. + Default: SW + + # SW configures the software based blockchain crypto provider. + SW: + # TODO: The default Hash and Security level needs refactoring to be + # fully configurable. Changing these defaults requires coordination + # SHA2 is hardcoded in several places, not only BCCSP + Hash: SHA2 + Security: 256 + # Location of key store. If this is unset, a location will be + # chosen using: 'LocalMSPDir'/keystore + FileKeyStore: + KeyStore: + + # Settings for the PKCS#11 crypto provider (i.e. when DEFAULT: PKCS11) + PKCS11: + # Location of the PKCS11 module library + Library: + # Token Label + Label: + # User PIN + Pin: + Hash: + Security: + FileKeyStore: + KeyStore: + + # Authentication contains configuration parameters related to authenticating + # client messages + Authentication: + # the acceptable difference between the current server time and the + # client's time as specified in a client request message + TimeWindow: 15m + + +################################################################################ +# +# SECTION: File Ledger +# +# - This section applies to the configuration of the file ledger. +# +################################################################################ +FileLedger: + + # Location: The directory to store the blocks in. + Location: /var/hyperledger/production/orderer + +################################################################################ +# +# SECTION: Kafka +# +# - This section applies to the configuration of the Kafka-based orderer, and +# its interaction with the Kafka cluster. +# +################################################################################ +Kafka: + + # Retry: What do if a connection to the Kafka cluster cannot be established, + # or if a metadata request to the Kafka cluster needs to be repeated. + Retry: + # When a new channel is created, or when an existing channel is reloaded + # (in case of a just-restarted orderer), the orderer interacts with the + # Kafka cluster in the following ways: + # 1. It creates a Kafka producer (writer) for the Kafka partition that + # corresponds to the channel. + # 2. It uses that producer to post a no-op CONNECT message to that + # partition + # 3. It creates a Kafka consumer (reader) for that partition. + # If any of these steps fail, they will be re-attempted every + # for a total of , and then every + # for a total of until they succeed. + # Note that the orderer will be unable to write to or read from a + # channel until all of the steps above have been completed successfully. + ShortInterval: 5s + ShortTotal: 10m + LongInterval: 5m + LongTotal: 12h + # Affects the socket timeouts when waiting for an initial connection, a + # response, or a transmission. See Config.Net for more info: + # https://godoc.org/github.com/Shopify/sarama#Config + NetworkTimeouts: + DialTimeout: 10s + ReadTimeout: 10s + WriteTimeout: 10s + # Affects the metadata requests when the Kafka cluster is in the middle + # of a leader election.See Config.Metadata for more info: + # https://godoc.org/github.com/Shopify/sarama#Config + Metadata: + RetryBackoff: 250ms + RetryMax: 3 + # What to do if posting a message to the Kafka cluster fails. See + # Config.Producer for more info: + # https://godoc.org/github.com/Shopify/sarama#Config + Producer: + RetryBackoff: 100ms + RetryMax: 3 + # What to do if reading from the Kafka cluster fails. See + # Config.Consumer for more info: + # https://godoc.org/github.com/Shopify/sarama#Config + Consumer: + RetryBackoff: 2s + # Settings to use when creating Kafka topics. Only applies when + # Kafka.Version is v0.10.1.0 or higher + Topic: + # The number of Kafka brokers across which to replicate the topic + ReplicationFactor: 3 + # Verbose: Enable logging for interactions with the Kafka cluster. + Verbose: false + + # TLS: TLS settings for the orderer's connection to the Kafka cluster. + TLS: + + # Enabled: Use TLS when connecting to the Kafka cluster. + Enabled: false + + # PrivateKey: PEM-encoded private key the orderer will use for + # authentication. + PrivateKey: + # As an alternative to specifying the PrivateKey here, uncomment the + # following "File" key and specify the file name from which to load the + # value of PrivateKey. + #File: path/to/PrivateKey + + # Certificate: PEM-encoded signed public key certificate the orderer will + # use for authentication. + Certificate: + # As an alternative to specifying the Certificate here, uncomment the + # following "File" key and specify the file name from which to load the + # value of Certificate. + #File: path/to/Certificate + + # RootCAs: PEM-encoded trusted root certificates used to validate + # certificates from the Kafka cluster. + RootCAs: + # As an alternative to specifying the RootCAs here, uncomment the + # following "File" key and specify the file name from which to load the + # value of RootCAs. + #File: path/to/RootCAs + + # SASLPlain: Settings for using SASL/PLAIN authentication with Kafka brokers + SASLPlain: + # Enabled: Use SASL/PLAIN to authenticate with Kafka brokers + Enabled: false + # User: Required when Enabled is set to true + User: + # Password: Required when Enabled is set to true + Password: + + # Kafka protocol version used to communicate with the Kafka cluster brokers + # (defaults to 0.10.2.0 if not specified) + Version: + +################################################################################ +# +# Debug Configuration +# +# - This controls the debugging options for the orderer +# +################################################################################ +Debug: + + # BroadcastTraceDir when set will cause each request to the Broadcast service + # for this orderer to be written to a file in this directory + BroadcastTraceDir: + + # DeliverTraceDir when set will cause each request to the Deliver service + # for this orderer to be written to a file in this directory + DeliverTraceDir: + +################################################################################ +# +# Operations Configuration +# +# - This configures the operations server endpoint for the orderer +# +################################################################################ +Operations: + # host and port for the operations server + ListenAddress: 127.0.0.1:8443 + + # TLS configuration for the operations endpoint + TLS: + # TLS enabled + Enabled: false + + # Certificate is the location of the PEM encoded TLS certificate + Certificate: + + # PrivateKey points to the location of the PEM-encoded key + PrivateKey: + + # Most operations service endpoints require client authentication when TLS + # is enabled. ClientAuthRequired requires client certificate authentication + # at the TLS layer to access all resources. + ClientAuthRequired: false + + # Paths to PEM encoded ca certificates to trust for client authentication + ClientRootCAs: [] + +################################################################################ +# +# Metrics Configuration +# +# - This configures metrics collection for the orderer +# +################################################################################ +Metrics: + # The metrics provider is one of statsd, prometheus, or disabled + Provider: disabled + + # The statsd configuration + Statsd: + # network type: tcp or udp + Network: udp + + # the statsd server address + Address: 127.0.0.1:8125 + + # The interval at which locally cached counters and gauges are pushed + # to statsd; timings are pushed immediately + WriteInterval: 30s + + # The prefix is prepended to all emitted statsd metrics + Prefix: + +################################################################################ +# +# Admin Configuration +# +# - This configures the admin server endpoint for the orderer +# +################################################################################ +Admin: + # host and port for the admin server + ListenAddress: 127.0.0.1:9443 + + # TLS configuration for the admin endpoint + TLS: + # TLS enabled + Enabled: false + + # Certificate is the location of the PEM encoded TLS certificate + Certificate: + + # PrivateKey points to the location of the PEM-encoded key + PrivateKey: + + # Most admin service endpoints require client authentication when TLS + # is enabled. ClientAuthRequired requires client certificate authentication + # at the TLS layer to access all resources. + # + # NOTE: When TLS is enabled, the admin endpoint requires mutual TLS. The + # orderer will panic on startup if this value is set to false. + ClientAuthRequired: true + + # Paths to PEM encoded ca certificates to trust for client authentication + ClientRootCAs: [] + +################################################################################ +# +# Channel participation API Configuration +# +# - This provides the channel participation API configuration for the orderer. +# - Channel participation uses the ListenAddress and TLS settings of the Admin +# service. +# +################################################################################ +ChannelParticipation: + # Channel participation API is enabled. + Enabled: false + + # The maximum size of the request body when joining a channel. + MaxRequestBodySize: 1 MB + + +################################################################################ +# +# Consensus Configuration +# +# - This section contains config options for a consensus plugin. It is opaque +# to orderer, and completely up to consensus implementation to make use of. +# +################################################################################ +Consensus: + # The allowed key-value pairs here depend on consensus plugin. For etcd/raft, + # we use following options: + + # WALDir specifies the location at which Write Ahead Logs for etcd/raft are + # stored. Each channel will have its own subdir named after channel ID. + WALDir: /var/hyperledger/production/orderer/etcdraft/wal + + # SnapDir specifies the location at which snapshots for etcd/raft are + # stored. Each channel will have its own subdir named after channel ID. + SnapDir: /var/hyperledger/production/orderer/etcdraft/snapshot diff --git a/sample-network-multi-org/justfile b/sample-network-multi-org/justfile new file mode 100644 index 00000000..f2ab07c8 --- /dev/null +++ b/sample-network-multi-org/justfile @@ -0,0 +1,189 @@ +# +# Copyright contributors to the Hyperledgendary Full Stack Asset Transfer project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Main justfile to run all the development scripts +# To install 'just' see https://github.com/casey/just#installation + + +############################################################################### +# +############################################################################### + +# Ensure all properties are exported as shell env-vars +set export + +# Use environment variables from the (git-ignored and hidden) .env files +set dotenv-load + +# set the current directory, and the location of the test dats +CWDIR := justfile_directory() + +_default: + @just -f {{justfile()}} --list + +# Run the check script to validate third party dependencies +check: + ${CWDIR}/scripts/check.sh + + +############################################################################### +# Environment and just parameters +############################################################################### + +CLUSTER_NAME := env_var_or_default("TEST_NETWORK_CLUSTER_NAME", "kind") +NAMESPACE := env_var_or_default("TEST_NETWORK_NAMESPACE", "test-network") +OPERATOR_IMAGE := env_var_or_default("TEST_NETWORK_OPERATOR_IMAGE", "ghcr.io/hyperledger-labs/fabric-operator:1.0") +FABRIC_VERSION := env_var_or_default("TEST_NETWORK_FABRIC_VERSION", "2.5.0-beta") +FABRIC_CA_VERSION := env_var_or_default("TEST_NETWORK_FABRIC_CA_VERSION", "1.5.6-beta3") +CA_IMAGE := env_var_or_default("TEST_NETWORK_CA_IMAGE", "hyperledger/fabric-ca") +CA_IMAGE_TAG := env_var_or_default("TEST_NETWORK_CA_IMAGE_TAG", FABRIC_CA_VERSION) +PEER_IMAGE := env_var_or_default("TEST_NETWORK_PEER_IMAGE", "ghcr.io/hyperledger-labs/k8s-fabric-peer") +PEER_IMAGE_TAG := env_var_or_default("TEST_NETWORK_PEER_IMAGE_TAG", "v0.8.0") +ORDERER_IMAGE := env_var_or_default("TEST_NETWORK_ORDERER_IMAGE", "hyperledger/fabric-orderer") +ORDERER_IMAGE_TAG := env_var_or_default("TEST_NETWORK_ORDERER_IMAGE_TAG", FABRIC_VERSION) +CHANNEL_NAME := env_var_or_default("TEST_NETWORK_CHANNEL_NAME", "mychannel") +CHAINCODE_NAME := env_var_or_default("TEST_NETWORK_CHAINCODE_NAME", "asset-transfer") +CHAINCODE_VERSION := env_var_or_default("TEST_NETWORK_CHAINCODE_VERSION", "v0.1.4") +CHAINCODE_SEQUENCE := env_var_or_default("TEST_NETWORK_CHAINCODE_SEQUENCE","1") +CHAINCODE_PKG_NAME := env_var_or_default("TEST_NETWORK_CHAINCODE_PKG_NAME","asset-transfer-typescript-v0.1.4.tgz") +CHAINCODE_PKG_URL := env_var_or_default("TEST_NETWORK_CHAINCODE_PKG_URL", "https://github.com/hyperledgendary/full-stack-asset-transfer-guide/releases/download/v0.1.4/" + CHAINCODE_PKG_NAME) + + +############################################################################### +# KIND / k8s targets +############################################################################### + +# Start a local KIND cluster with nginx ingress +kind: check unkind + scripts/kind_with_nginx.sh {{CLUSTER_NAME}} + +# Shut down the KIND cluster +unkind: + #!/usr/bin/env bash + kind delete cluster --name {{CLUSTER_NAME}} + + if docker inspect kind-registry &>/dev/null; then + echo "Stopping container registry" + docker kill kind-registry + docker rm kind-registry + fi + + +############################################################################### +# TL/DR actions. These don't exist, other than for convenience to run the +# entire flow without splitting across multiple "org" terminals. +############################################################################### + +start-network: + just start org0 + just start org1 + just start org2 + +# Shut down the test network and remove all certificates +destroy: + #!/usr/bin/env bash + rm -rf organizations/org0/enrollments && echo "org0 enrollments deleted" + rm -rf organizations/org1/enrollments && echo "org1 enrollments deleted" + rm -rf organizations/org2/enrollments && echo "org2 enrollments deleted" + rm -rf organizations/org0/chaincode && echo "org0 chaincode packages deleted" + rm -rf organizations/org1/chaincode && echo "org1 chaincode packages deleted" + rm -rf organizations/org2/chaincode && echo "org2 chaincode packages deleted" + + rm -rf channel-config/organizations && echo "consortium MSP deleted" + rm channel-config/{{CHANNEL_NAME}}_genesis_block.pb && echo {{CHANNEL_NAME}} " genesis block deleted" + + kubectl delete ns org0 --ignore-not-found=true + kubectl delete ns org1 --ignore-not-found=true + kubectl delete ns org2 --ignore-not-found=true + +# Check that all network services are running +check-network: + scripts/check-network.sh + + +############################################################################### +# Test Network +############################################################################### + +# Create the org namespace and start the operator for an org +init org: + #!/usr/bin/env bash + export NAMESPACE={{org}} # todo: move to an org directory? + scripts/start_operator.sh + +# Start the nodes for an org +start org: (init org) + organizations/{{org}}/start.sh + +# todo: clear enrollments, cc packages, etc. +# Stop the nodes for an org +stop org: + kubectl delete ns {{org}} --ignore-not-found=true + +# todo: + dependency (start org)? +# Enroll the users for an org +enroll org: + organizations/{{org}}/enroll.sh + + +############################################################################### +# Channel Construction +############################################################################### + +# Create the channel genesis block +create-genesis-block: check-network gather-msp + channel-config/create_genesis_block.sh + +# todo: include this? Which org is running the target? +# Export the MSP certificates for all orgs +gather-msp: + just export-msp org0 + just export-msp org1 + just export-msp org2 + +# Export org MSP certificates to the consortium organizer +export-msp org: + organizations/{{org}}/export_msp.sh + +# inspect the genesis block +inspect-genesis-block: + #!/usr/bin/env bash + configtxgen -inspectBlock channel-config/mychannel_genesis_block.pb | jq + +# Join an org to the channel +join org: + organizations/{{org}}/join_channel.sh + + +############################################################################### +# Chaincode and Gateway Appplication Development +############################################################################### + +# Install a smart contract on all peers in an org +install-cc org: + organizations/{{org}}/install_chaincode.sh + +# Display env for targeting a peer with the Fabric binaries +show-context msp org peer: + #!/usr/bin/env bash + . {{CWDIR}}/scripts/utils.sh + appear_as {{msp}} {{org}} {{peer}} + + # use export to load the peer context into the current environment: + # export $(just show-context Org1MSP org1 peer1) + printenv | egrep "CORE_PEER|FABRIC_|ORDERER_" | sort diff --git a/sample-network-multi-org/kind/cert-manager/.gitignore b/sample-network-multi-org/kind/cert-manager/.gitignore new file mode 100644 index 00000000..149f80c6 --- /dev/null +++ b/sample-network-multi-org/kind/cert-manager/.gitignore @@ -0,0 +1 @@ +ca-issuer-secret.yaml diff --git a/sample-network-multi-org/kind/cert-manager/ca-issuer-secret.yaml b/sample-network-multi-org/kind/cert-manager/ca-issuer-secret.yaml new file mode 100644 index 00000000..1e628a93 --- /dev/null +++ b/sample-network-multi-org/kind/cert-manager/ca-issuer-secret.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +data: + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURsakNDQW42Z0F3SUJBZ0lRSHJ4UFNoU1lJT3lraWJoV2lqRjdWakFOQmdrcWhraUc5dzBCQVFzRkFEQmwKTVRVd013WURWUVFLRXl4SmJuUmxjbTVoZEdsdmJtRnNJRUoxYzJsdVpYTnpJRTFoWTJocGJtVnpJRWx1WTI5eQpjRzl5WVhSbFpERXNNQ29HQTFVRUF3d2pLaTVzYjJOaGJHaHZMbk4wSUV0MVltVWdMeUJMU1U1RUlGUk1VeUJKCmMzTjFaWEl3SGhjTk1qSXhNVEl3TURNd016VXhXaGNOTWpNd01qRTRNRE13TXpVeFdqQmxNVFV3TXdZRFZRUUsKRXl4SmJuUmxjbTVoZEdsdmJtRnNJRUoxYzJsdVpYTnpJRTFoWTJocGJtVnpJRWx1WTI5eWNHOXlZWFJsWkRFcwpNQ29HQTFVRUF3d2pLaTVzYjJOaGJHaHZMbk4wSUV0MVltVWdMeUJMU1U1RUlGUk1VeUJKYzNOMVpYSXdnZ0VpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRGlYSDhBbmo0MXRTa21wbEg0TUhMaW43bk0KZFFtWlppbEpUVHQwakdwRzhJK2xXcTUrcDd3NDhUNVJYTGNaNElIL0d1V1VKQ09adjYrRHg3WXBzTG9SYWVaagpXNHRGT3luYWdQL3lybTRDTjFKTjBXcTdKWis4ZVRzU1JIa3JCK3hodm1abHNzeE41YmNoRmhiNVZkdm81SVF5CjNYK1o2cm1QaDlCbkppckk4UTNNRmhTLzhHVUw3YzI2VnhkRGt6dS9HR0dXdEhySVJRZ3VEc2t6Znp2SjlQbkYKemhOalYrNXVoM0hTOEY1RUoyQ0xZc2VoRGRQSW95dGdmUSt3YVA5N3JIenp1M2ZuN0lMM0p0SGtDcy9Fekh5YQp0TzdmZTlwVVR5bGVXN1F0QUFmbFpLSHdBMUVMUytQMnNwbHBzT1lYV3hjUkQ5endoWC84UVN2aE1FT05BZ01CCkFBR2pRakJBTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVcKQkJSaWNBVUQ4YkNtZmdQWTRZR1lralhiRlNxTXNEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFHbjZHblFIaAp3Qm9LdmhaTTcyT2pXUnFPYjJBWU1VaDhsclF1NGxSNUZoaFN5TXI1ejA5aUJjaXNMaFZPc1hpdTVrZWtsbHNoCkN5Nm94QTd4TnFHV1d6VCtqb2tGYUEzdzM0eFpDLzN5Mnh4c1dnMGZ6Z3BEc3QyK05Gai9hVHFGSWJ2ZW5ETjYKZ2crM1lDSXRGeXI5QmNFWTh6Yk0rNlV2QWF5RlNram9lNCtybUFOMHpwRUg0M3RaMmlRY010Qy9VVER3bkV2LwpVNnI1QmEvUUlSMDh1eHpJOGd0TnVPc2RlUnRGVy9kTHk0UHhwbXp0YkgzUnczTTJTMCs2ZS8zZkRNcWRKcVdUCmJFdWFWSEtLQlFXOWwzWjluYS9xdHJKM0Qzc0FYQ0pLbHdQN2orSkpFM3dHNFdEVTZUcHJnV0ZiQTNaVC9zTlkKY0sxZG5ZSTlkTnRWN1E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURsakNDQW42Z0F3SUJBZ0lRSHJ4UFNoU1lJT3lraWJoV2lqRjdWakFOQmdrcWhraUc5dzBCQVFzRkFEQmwKTVRVd013WURWUVFLRXl4SmJuUmxjbTVoZEdsdmJtRnNJRUoxYzJsdVpYTnpJRTFoWTJocGJtVnpJRWx1WTI5eQpjRzl5WVhSbFpERXNNQ29HQTFVRUF3d2pLaTVzYjJOaGJHaHZMbk4wSUV0MVltVWdMeUJMU1U1RUlGUk1VeUJKCmMzTjFaWEl3SGhjTk1qSXhNVEl3TURNd016VXhXaGNOTWpNd01qRTRNRE13TXpVeFdqQmxNVFV3TXdZRFZRUUsKRXl4SmJuUmxjbTVoZEdsdmJtRnNJRUoxYzJsdVpYTnpJRTFoWTJocGJtVnpJRWx1WTI5eWNHOXlZWFJsWkRFcwpNQ29HQTFVRUF3d2pLaTVzYjJOaGJHaHZMbk4wSUV0MVltVWdMeUJMU1U1RUlGUk1VeUJKYzNOMVpYSXdnZ0VpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRGlYSDhBbmo0MXRTa21wbEg0TUhMaW43bk0KZFFtWlppbEpUVHQwakdwRzhJK2xXcTUrcDd3NDhUNVJYTGNaNElIL0d1V1VKQ09adjYrRHg3WXBzTG9SYWVaagpXNHRGT3luYWdQL3lybTRDTjFKTjBXcTdKWis4ZVRzU1JIa3JCK3hodm1abHNzeE41YmNoRmhiNVZkdm81SVF5CjNYK1o2cm1QaDlCbkppckk4UTNNRmhTLzhHVUw3YzI2VnhkRGt6dS9HR0dXdEhySVJRZ3VEc2t6Znp2SjlQbkYKemhOalYrNXVoM0hTOEY1RUoyQ0xZc2VoRGRQSW95dGdmUSt3YVA5N3JIenp1M2ZuN0lMM0p0SGtDcy9Fekh5YQp0TzdmZTlwVVR5bGVXN1F0QUFmbFpLSHdBMUVMUytQMnNwbHBzT1lYV3hjUkQ5endoWC84UVN2aE1FT05BZ01CCkFBR2pRakJBTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVcKQkJSaWNBVUQ4YkNtZmdQWTRZR1lralhiRlNxTXNEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFHbjZHblFIaAp3Qm9LdmhaTTcyT2pXUnFPYjJBWU1VaDhsclF1NGxSNUZoaFN5TXI1ejA5aUJjaXNMaFZPc1hpdTVrZWtsbHNoCkN5Nm94QTd4TnFHV1d6VCtqb2tGYUEzdzM0eFpDLzN5Mnh4c1dnMGZ6Z3BEc3QyK05Gai9hVHFGSWJ2ZW5ETjYKZ2crM1lDSXRGeXI5QmNFWTh6Yk0rNlV2QWF5RlNram9lNCtybUFOMHpwRUg0M3RaMmlRY010Qy9VVER3bkV2LwpVNnI1QmEvUUlSMDh1eHpJOGd0TnVPc2RlUnRGVy9kTHk0UHhwbXp0YkgzUnczTTJTMCs2ZS8zZkRNcWRKcVdUCmJFdWFWSEtLQlFXOWwzWjluYS9xdHJKM0Qzc0FYQ0pLbHdQN2orSkpFM3dHNFdEVTZUcHJnV0ZiQTNaVC9zTlkKY0sxZG5ZSTlkTnRWN1E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBNGx4L0FKNCtOYlVwSnFaUitEQnk0cCs1ekhVSm1XWXBTVTA3ZEl4cVJ2Q1BwVnF1CmZxZThPUEUrVVZ5M0dlQ0IveHJsbENRam1iK3ZnOGUyS2JDNkVXbm1ZMXVMUlRzcDJvRC84cTV1QWpkU1RkRnEKdXlXZnZIazdFa1I1S3dmc1liNW1aYkxNVGVXM0lSWVcrVlhiNk9TRU10MS9tZXE1ajRmUVp5WXF5UEVOekJZVQp2L0JsQyszTnVsY1hRNU03dnhoaGxyUjZ5RVVJTGc3Sk0zODd5ZlQ1eGM0VFkxZnVib2R4MHZCZVJDZGdpMkxICm9RM1R5S01yWUgwUHNHai9lNng4ODd0MzUreUM5eWJSNUFyUHhNeDhtclR1MzN2YVZFOHBYbHUwTFFBSDVXU2gKOEFOUkMwdmo5cktaYWJEbUYxc1hFUS9jOElWLy9FRXI0VEJEalFJREFRQUJBb0lCQUNpSkY5VXNnVWRzNGFtaQpMeHVhMFhmejBubmltNDEwMWYvaWJMczZTZTNhTmw4T0ZpRm9PRFNhUHVhakM4YitoVWtCc0FzUFRiREN1dE9HCmVBQ1BQVUxSREFqTzQrbko1bnpTalFNUWFYTE1KVmo2SDNyVUNmN2VWczIycFZ3blZ4VkoyMXhxNEZzeXY5Q1UKL0JnNlg5OGN6Tyt1NnFMTmZkMU9IT3ZiMGQyWnR0aG9yWWxlcUZ3anNjTnZBbUsveVFoc0VscDlQNE04RUhCdQpmWktlcStRWHp1SXdZcmI1dWRNMXVDWXhQUUk2WGo1dUlqTC9mcGVCenlMcEg4ZEJXRFpyUVFtRlFEcjhHbVltClZSb2xzYW5OYzlkQXBvQ3JDY1Fnekd3eFpmUm43eXFBTHN2dWtjNUIrK241dUdXenNpQmt0NHhDYno3emVSUWYKaW5sTDJxRUNnWUVBLzNQVFZGZXhjYi9td1NOd0p1QTVVdzZ0cHdjVjJrZ25LWjUybzJsc084R1FPempqUnU0Lwo1blRHbkVlWlo1Yk9XU0tic21TMmRjUVlLREhwTG9MZ0wrekRMNDNtVEJYbGxpQzlTNFB5SFFiSUNzQ3BqVDc5Ck1LVkFyTlZXMlJJR0VnMDZwVUJhMW14OFhZS2xraHNPZUpTWUZEQTF2OENuMHNQWmxFcEg4NGNDZ1lFQTR0aTEKR1FMdzZKZFRXcHpSaGJvSWdibm5RKzJ2Mi84VU1RRUw0M1B6UmNaWmd0TnU5NU1ERXEveWZyckdaeWhqVUlLQwpVRjVWUFE3VWdrc3c0RXdNWmxZZkQ5NGF3c05HSno5eTRKV2IxK3hIMnZuaGpJYlBEcEQ4VTJyZ2d3Y2crTUlFCkYwdTVSK2lMUHY1OFQ3MWJPNi83NXNMMzRNY2FaMjFFTXJUMWZVc0NnWUJpZEpiUDNCaWsrY3lMUmdoVXczajAKblNTcXlwMU9peDZrK05GSy9EZmQ5Q1dOM2NnakwzSnJkVGlUUlRsSDVxVFRUL1pvVkU3S3B2Q1VsV0FGTUNZTgo4cGZyL1NuMHl6KzRsQmZCUWpLUG8yeDRVSGRJM0MwamtaMlN2NHNBa09UTUVsTTNHODJtOVJzZHcxdmpLeEJ4Cnd2dTJWRHB6RkdMYVplZTNNc1gyZ3dLQmdRQytKamNQZ3lhYllSV08wL3JSWkpKeTQza1d1S3Q3OW9KZlhXZ3cKdmVZQzYvUG1OUU5FWmFmaXh6ZTJ3U3RFRjFmQWlkVmdOdUt1YnJyMWlMK3NsREtrcWJZWjMreUFxNTBua3dqaApkcWNPeE5HcW5XRlNJVUo1REZGbVB5VjR6OFgwbnZVODdjMmVtQy80bXV0ckQrZmt6V3lURDRVbWx0N3NLV3hNCk1PSENwd0tCZ0FVejJ2WWlVaHRET1k0TDNNV3NkaVRWeW16KzlmYXZ0d0Z1bnBCNEN5bC8xVm1ZODA0N0tvUTUKQzI3QlF0TGRmMFd5UmUvbWVQRi9EUWNtWlpKK0dDRHhpYkczZ2phMzgvdytDWlcrL3FNY3B4ckNhbUltNHZUYgoxcjNIUThDUCtNZE5TTUszaGRmNW9vMW9nUUdUdm5idkhIMjBPV0Vhazc2OFp5YUpYdmkwCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== +kind: Secret +metadata: + annotations: + cert-manager.io/alt-names: "" + cert-manager.io/certificate-name: ca-issuer + cert-manager.io/common-name: '*.localho.st Kube / KIND TLS Issuer' + cert-manager.io/ip-sans: "" + cert-manager.io/issuer-group: cert-manager.io + cert-manager.io/issuer-kind: ClusterIssuer + cert-manager.io/issuer-name: root-tls-cert-issuer + cert-manager.io/uri-sans: "" + creationTimestamp: "2022-11-20T03:03:51Z" + name: ca-issuer-secret + namespace: cert-manager + resourceVersion: "644" + uid: 493e496e-9145-444b-9463-7e87687f9536 +type: kubernetes.io/tls diff --git a/sample-network-multi-org/kind/cert-manager/ca-issuer.yaml b/sample-network-multi-org/kind/cert-manager/ca-issuer.yaml new file mode 100644 index 00000000..7abe061d --- /dev/null +++ b/sample-network-multi-org/kind/cert-manager/ca-issuer.yaml @@ -0,0 +1,34 @@ +# see https://cert-manager.io/docs/configuration/selfsigned/#bootstrapping-ca-issuers + +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: ca-issuer +spec: + isCA: true + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + commonName: "*.localho.st Kube / KIND TLS Issuer" + subject: + organizations: + - "International Business Machines Incorporated" + secretName: ca-issuer-secret + issuerRef: + name: root-tls-cert-issuer + kind: ClusterIssuer + group: cert-manager.io + +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: ca-issuer +spec: + ca: + secretName: ca-issuer-secret + + + diff --git a/sample-network-multi-org/kind/cert-manager/kustomization.yaml b/sample-network-multi-org/kind/cert-manager/kustomization.yaml new file mode 100644 index 00000000..9eab4a0c --- /dev/null +++ b/sample-network-multi-org/kind/cert-manager/kustomization.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - root-tls-issuer.yaml + - ca-issuer.yaml + + # The CA issuer secret / cert is created by the KIND setup script, rather than + # in the kustomization. This allows for a certificate created by a previously + # configured KIND cluster to be re-used as the root CA. + # - ca-issuer-secret.yaml diff --git a/sample-network-multi-org/kind/cert-manager/root-tls-issuer.yaml b/sample-network-multi-org/kind/cert-manager/root-tls-issuer.yaml new file mode 100644 index 00000000..ed9678b7 --- /dev/null +++ b/sample-network-multi-org/kind/cert-manager/root-tls-issuer.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: root-tls-cert-issuer +spec: + selfSigned: {} diff --git a/sample-network-multi-org/kind/nginx/ingress-nginx-controller.yaml b/sample-network-multi-org/kind/nginx/ingress-nginx-controller.yaml new file mode 100644 index 00000000..6408d3f2 --- /dev/null +++ b/sample-network-multi-org/kind/nginx/ingress-nginx-controller.yaml @@ -0,0 +1,39 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: ingress-nginx + name: ingress-nginx-controller +spec: + template: + spec: + containers: + - name: controller + args: + - /nginx-ingress-controller + - --election-id=ingress-controller-leader + - --controller-class=k8s.io/ingress-nginx + - --ingress-class=nginx + - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller + - --validating-webhook=:8443 + - --validating-webhook-certificate=/usr/local/certificates/cert + - --validating-webhook-key=/usr/local/certificates/key + - --watch-ingress-without-class=true + - --publish-status-address=localhost + - --enable-ssl-passthrough \ No newline at end of file diff --git a/sample-network-multi-org/kind/nginx/kustomization.yaml b/sample-network-multi-org/kind/nginx/kustomization.yaml new file mode 100644 index 00000000..8178699d --- /dev/null +++ b/sample-network-multi-org/kind/nginx/kustomization.yaml @@ -0,0 +1,26 @@ + +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - https://github.com/kubernetes/ingress-nginx.git/deploy/static/provider/kind?ref=controller-v1.1.2 + +patchesStrategicMerge: + - ingress-nginx-controller.yaml \ No newline at end of file diff --git a/sample-network-multi-org/kind/operator/kustomization.yaml b/sample-network-multi-org/kind/operator/kustomization.yaml new file mode 100644 index 00000000..a775f9a0 --- /dev/null +++ b/sample-network-multi-org/kind/operator/kustomization.yaml @@ -0,0 +1,27 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - https://github.com/hyperledger-labs/fabric-operator.git/config/crd + - operator-clusterrole.yaml + - operator-clusterrolebinding.yaml + - operator-serviceaccount.yaml + - operator-psp.yaml + - operator-manager.yaml diff --git a/sample-network-multi-org/kind/operator/operator-clusterrole.yaml b/sample-network-multi-org/kind/operator/operator-clusterrole.yaml new file mode 100644 index 00000000..3a775e76 --- /dev/null +++ b/sample-network-multi-org/kind/operator/operator-clusterrole.yaml @@ -0,0 +1,205 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: fabric-operator-role + labels: + release: "operator" + helm.sh/chart: "ibm-hlfsupport" + app.kubernetes.io/name: "ibm-hlfsupport" + app.kubernetes.io/instance: "ibm-hlfsupport" + app.kubernetes.io/managed-by: "ibm-hlfsupport-operator" +rules: + - apiGroups: + - extensions + resourceNames: + - ibm-hlfsupport-psp + resources: + - podsecuritypolicies + verbs: + - use + - apiGroups: + - apiextensions.k8s.io + resources: + - persistentvolumeclaims + - persistentvolumes + verbs: + - get + - list + - create + - update + - patch + - watch + - delete + - deletecollection + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - get + - list + - create + - update + - patch + - watch + - delete + - deletecollection + - apiGroups: + - "" + resources: + - pods + - pods/log + - persistentvolumeclaims + - persistentvolumes + - services + - endpoints + - events + - configmaps + - secrets + - nodes + - serviceaccounts + verbs: + - get + - list + - create + - update + - patch + - watch + - delete + - deletecollection + - apiGroups: + - "batch" + resources: + - jobs + verbs: + - get + - list + - create + - update + - patch + - watch + - delete + - deletecollection + - apiGroups: + - "authorization.openshift.io" + - "rbac.authorization.k8s.io" + resources: + - roles + - rolebindings + verbs: + - get + - list + - create + - update + - patch + - watch + - delete + - deletecollection + - bind + - escalate + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - apiGroups: + - apps + resources: + - deployments + - daemonsets + - replicasets + - statefulsets + verbs: + - get + - list + - create + - update + - patch + - watch + - delete + - deletecollection + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - apps + resourceNames: + - ibm-hlfsupport-operator + resources: + - deployments/finalizers + verbs: + - update + - apiGroups: + - ibp.com + resources: + - ibpcas.ibp.com + - ibppeers.ibp.com + - ibporderers.ibp.com + - ibpconsoles.ibp.com + - ibpcas + - ibppeers + - ibporderers + - ibpconsoles + - ibpcas/finalizers + - ibppeers/finalizers + - ibporderers/finalizers + - ibpconsoles/finalizers + - ibpcas/status + - ibppeers/status + - ibporderers/status + - ibpconsoles/status + verbs: + - get + - list + - create + - update + - patch + - watch + - delete + - deletecollection + - apiGroups: + - extensions + - networking.k8s.io + - config.openshift.io + resources: + - ingresses + - networkpolicies + verbs: + - get + - list + - create + - update + - patch + - watch + - delete + - deletecollection diff --git a/sample-network-multi-org/kind/operator/operator-clusterrolebinding.yaml b/sample-network-multi-org/kind/operator/operator-clusterrolebinding.yaml new file mode 100644 index 00000000..34df0b68 --- /dev/null +++ b/sample-network-multi-org/kind/operator/operator-clusterrolebinding.yaml @@ -0,0 +1,42 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: fabric-operator-rolebinding + labels: + release: "operator" + helm.sh/chart: "ibm-hlfsupport" + app.kubernetes.io/name: "ibm-hlfsupport" + app.kubernetes.io/instance: "ibm-hlfsupport" + app.kubernetes.io/managed-by: "ibm-hlfsupport-operator" +subjects: + - kind: ServiceAccount + name: fabric-operator + namespace: org0 + - kind: ServiceAccount + name: fabric-operator + namespace: org1 + - kind: ServiceAccount + name: fabric-operator + namespace: org2 +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: fabric-operator-role diff --git a/sample-network-multi-org/kind/operator/operator-manager.yaml b/sample-network-multi-org/kind/operator/operator-manager.yaml new file mode 100644 index 00000000..3a967801 --- /dev/null +++ b/sample-network-multi-org/kind/operator/operator-manager.yaml @@ -0,0 +1,66 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fabric-operator +spec: + replicas: 1 + selector: + matchLabels: + name: fabric-operator + template: + metadata: + labels: + name: fabric-operator + spec: + serviceAccountName: fabric-operator +# imagePullSecrets: +# - name: image-pull-secret + containers: + - name: fabric-operator + image: ${OPERATOR_IMAGE} + command: + - ibp-operator +# livenessProbe: +# tcpSocket: +# port: 8383 +# initialDelaySeconds: 10 +# timeoutSeconds: 5 +# failureThreshold: 5 +# readinessProbe: +# tcpSocket: +# port: 8383 +# initialDelaySeconds: 10 +# timeoutSeconds: 5 +# periodSeconds: 5 + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "fabric-operator" + - name: CLUSTERTYPE + value: K8S + diff --git a/sample-network-multi-org/kind/operator/operator-psp.yaml b/sample-network-multi-org/kind/operator/operator-psp.yaml new file mode 100644 index 00000000..dcd53c72 --- /dev/null +++ b/sample-network-multi-org/kind/operator/operator-psp.yaml @@ -0,0 +1,48 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: ibm-hlfsupport-psp +spec: + hostIPC: false + hostNetwork: false + hostPID: false + privileged: true + allowPrivilegeEscalation: true + readOnlyRootFilesystem: false + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + runAsUser: + rule: RunAsAny + fsGroup: + rule: RunAsAny + requiredDropCapabilities: + - ALL + allowedCapabilities: + - NET_BIND_SERVICE + - CHOWN + - DAC_OVERRIDE + - SETGID + - SETUID + - FOWNER + volumes: + - '*' diff --git a/sample-network-multi-org/kind/operator/operator-serviceaccount.yaml b/sample-network-multi-org/kind/operator/operator-serviceaccount.yaml new file mode 100644 index 00000000..2013b11f --- /dev/null +++ b/sample-network-multi-org/kind/operator/operator-serviceaccount.yaml @@ -0,0 +1,22 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: fabric-operator diff --git a/sample-network-multi-org/organizations/.gitignore b/sample-network-multi-org/organizations/.gitignore new file mode 100644 index 00000000..8d69b3d7 --- /dev/null +++ b/sample-network-multi-org/organizations/.gitignore @@ -0,0 +1,3 @@ +enrollments/ +chaincode/ + diff --git a/sample-network-multi-org/organizations/org0/enroll.sh b/sample-network-multi-org/organizations/org0/enroll.sh new file mode 100755 index 00000000..f1cc4c8a --- /dev/null +++ b/sample-network-multi-org/organizations/org0/enroll.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org0 services to the "org0" namespace +# +export NAMESPACE=org0 + +# +# Save all of the organization enrollments in a local folder. +# +ENROLLMENTS_DIR=${PWD}/organizations/org0/enrollments + +# +# Before we can work with the CA, extract the CA's TLS certificate and +# store in .pem format for access with client utilities. +# +write_pem ca .tls.cert $ENROLLMENTS_DIR/ca-tls-cert.pem + +# Enroll the org0 admin user. Registration is performed by the operator according +# to entries in the org0 ca CRD. +enroll org0 org0admin org0adminpw + +# When connecting to the orderers, the channel admin API requires that the HTTP client +# presents a TLS certificate that has been signed by the organization's TLS CA. +enroll_tls org0 org0admin org0adminpw diff --git a/sample-network-multi-org/organizations/org0/export_msp.sh b/sample-network-multi-org/organizations/org0/export_msp.sh new file mode 100755 index 00000000..30086e47 --- /dev/null +++ b/sample-network-multi-org/organizations/org0/export_msp.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org0 services to the "org0" namespace +# +export NAMESPACE=org0 + +print "Exporting org0 channel MSP" + +# +# Prepare a folder structure containing the organization's MSP certificates +# necessary to join the consortium. +# +ORG_DIR=channel-config/organizations/ordererOrganizations/org0.localho.st + +write_pem ca .ca.signcerts $ORG_DIR/msp/cacerts/ca-signcert.pem +write_pem ca .tlsca.signcerts $ORG_DIR/msp/tlscacerts/tlsca-signcert.pem +write_msp_config ca ca-signcert.pem $ORG_DIR/msp + + +# +# Extract the orderer TLS certificates. These will be used by osnadmin for +# TLS connections to the orderers when joining orgs to a channel. +# +write_pem orderernode1 .tls.signcerts $ORG_DIR/orderers/orderernode1/tls/signcerts/tls-cert.pem +write_pem orderernode2 .tls.signcerts $ORG_DIR/orderers/orderernode2/tls/signcerts/tls-cert.pem +write_pem orderernode3 .tls.signcerts $ORG_DIR/orderers/orderernode3/tls/signcerts/tls-cert.pem \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org0/join_channel.sh b/sample-network-multi-org/organizations/org0/join_channel.sh new file mode 100755 index 00000000..14158e97 --- /dev/null +++ b/sample-network-multi-org/organizations/org0/join_channel.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org0 services to the "org0" namespace +# +export NAMESPACE=org0 + +# +# As the consortium organizer, the org0 will use osnadmin to join the ordering +# nodes to the channel. +# +function join_orderer() { + local orderer=$1 + print "joining orderer $orderer to $CHANNEL_NAME" + + # orderer URL and TLS certificate: + local orderer_admin_endpoint=org0-${orderer}-admin.org0.localho.st + local ca_file=channel-config/organizations/ordererOrganizations/org0.localho.st/orderers/${orderer}/tls/signcerts/tls-cert.pem + + # mTLS client key pair enrolled the org0 TLS CA: + local client_cert=organizations/org0/enrollments/org0admin/tls/signcerts/cert.pem + local client_key=organizations/org0/enrollments/org0admin/tls/keystore/key.pem + + osnadmin channel join \ + --orderer-address $orderer_admin_endpoint \ + --ca-file $ca_file \ + --client-cert $client_cert \ + --client-key $client_key \ + --channelID $CHANNEL_NAME \ + --config-block channel-config/${CHANNEL_NAME}_genesis_block.pb +} + +join_orderer orderernode1 +join_orderer orderernode2 +join_orderer orderernode3 \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org0/org0-ca.yaml b/sample-network-multi-org/organizations/org0/org0-ca.yaml new file mode 100644 index 00000000..52aab212 --- /dev/null +++ b/sample-network-multi-org/organizations/org0/org0-ca.yaml @@ -0,0 +1,135 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: ibp.com/v1beta1 +kind: IBPCA +metadata: + name: ca +spec: + action: + renew: {} + configoverride: + ca: + affiliations: + org1: + - department1 + - department2 + org2: + - department1 + registry: + identities: + - name: rcaadmin + pass: rcaadminpw + type: client + attrs: + hf.Registrar.Roles: "*" + hf.Registrar.DelegateRoles: "*" + hf.Revoker: true + hf.IntermediateCA: true + hf.GenCRL: true + hf.Registrar.Attributes: "*" + hf.AffiliationMgr: true + - name: orderer1 + pass: orderer1pw + type: orderer + - name: orderer2 + pass: orderer2pw + type: orderer + - name: orderer3 + pass: orderer3pw + type: orderer + - name: org0admin + pass: org0adminpw + type: admin + debug: true + signing: + default: + expiry: 87600h0m0s + tlsca: + affiliations: + org1: + - department1 + - department2 + org0: + - department1 + registry: + identities: + - name: admin + pass: adminpw + type: client # todo: shouldn't this be an admin? + attrs: + hf.Registrar.Roles: "*" + hf.Registrar.DelegateRoles: "*" + hf.Revoker: true + hf.IntermediateCA: true + hf.GenCRL: true + hf.Registrar.Attributes: "*" + hf.AffiliationMgr: true + - name: orderer1 + pass: orderer1pw + type: orderer + - name: orderer2 + pass: orderer2pw + type: orderer + - name: orderer3 + pass: orderer3pw + type: orderer + - name: org0admin + pass: org0adminpw + type: admin + + debug: true + signing: + default: + expiry: 87600h0m0s + customNames: + pvc: {} + domain: org0.localho.st + images: + caImage: ${CA_IMAGE} + caTag: ${CA_IMAGE_TAG} + caInitImage: registry.access.redhat.com/ubi8/ubi-minimal + caInitTag: latest + ingress: + class: "" + tlsSecretName: "" + license: + accept: true + replicas: 1 + resources: + ca: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + init: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + service: + type: ClusterIP + storage: + ca: + class: standard + size: 100M + version: 1.5.5 diff --git a/sample-network-multi-org/organizations/org0/org0-orderer.yaml b/sample-network-multi-org/organizations/org0/org0-orderer.yaml new file mode 100644 index 00000000..475c54e3 --- /dev/null +++ b/sample-network-multi-org/organizations/org0/org0-orderer.yaml @@ -0,0 +1,151 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: ibp.com/v1beta1 +kind: IBPOrderer +metadata: + name: orderer +spec: + version: "${FABRIC_VERSION}" + domain: "org0.localho.st" + license: + accept: true + action: + enroll: {} + reenroll: {} + clusterSize: 3 + clusterconfigoverride: + - general: + keepalive: + serverMinInterval: 61s + - general: + keepalive: + serverMinInterval: 61s + - general: + keepalive: + serverMinInterval: 61s + clustersecret: + - enrollment: + component: + caname: ca + cahost: org0-ca-ca.org0.localho.st + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "orderer1" + enrollsecret: "orderer1pw" + tls: + caname: tlsca + cahost: org0-ca-ca.org0.localho.st + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "orderer1" + enrollsecret: "orderer1pw" + csr: + hosts: + - "orderernode1" + - "orderernode1.org0.svc.cluster.local" + - enrollment: + component: + caname: ca + cahost: org0-ca-ca.org0.localho.st + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "orderer2" + enrollsecret: "orderer2pw" + tls: + caname: tlsca + cahost: org0-ca-ca.org0.localho.st + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "orderer2" + enrollsecret: "orderer2pw" + csr: + hosts: + - "orderernode2" + - "orderernode2.org0.svc.cluster.local" + - enrollment: + component: + caname: ca + cahost: org0-ca-ca.org0.localho.st + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "orderer3" + enrollsecret: "orderer3pw" + tls: + caname: tlsca + cahost: org0-ca-ca.org0.localho.st + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "orderer3" + enrollsecret: "orderer3pw" + csr: + hosts: + - "orderernode3" + - "orderernode3.org0.svc.cluster.local" + + customNames: + pvc: {} + images: + ordererInitImage: registry.access.redhat.com/ubi8/ubi-minimal + ordererInitTag: latest + ordererImage: ${ORDERER_IMAGE} + ordererTag: ${ORDERER_IMAGE_TAG} + grpcwebImage: ghcr.io/hyperledger-labs/grpc-web + grpcwebTag: latest + ingress: + class: "" + tlsSecretName: "" + mspID: OrdererMSP + ordererType: etcdraft + orgName: OrdererOrg + useChannelLess: true + systemChannelName: testchainid + resources: + init: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + orderer: + limits: + cpu: 600m + memory: 1200M + requests: + cpu: 10m + memory: 10M + proxy: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + service: + type: ClusterIP + storage: + orderer: + class: "standard" + size: 5G diff --git a/sample-network-multi-org/organizations/org0/start.sh b/sample-network-multi-org/organizations/org0/start.sh new file mode 100755 index 00000000..d462d20d --- /dev/null +++ b/sample-network-multi-org/organizations/org0/start.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + + +# +# Bind all org0 services to the "org0" namespace +# +export NAMESPACE=org0 + + +# +# CA +# +print "starting org0 CA" + +apply_template organizations/org0/org0-ca.yaml +sleep 5 +wait_for ibpca ca + +# Retrieve the org CA certificate for the bootstrap enrollment of peers/orderers. +# This value will be substituted from the environment into the node CRDs. +export CA_CERT=$(connection_profile_cert ca .tls.cert) + + +# +# Network nodes +# +print "starting org0 orderers" +apply_template organizations/org0/org0-orderer.yaml +sleep 5 + +wait_for ibporderer orderernode1 +wait_for ibporderer orderernode2 +wait_for ibporderer orderernode3 + +print "starting org0 peers" + diff --git a/sample-network-multi-org/organizations/org1/enroll.sh b/sample-network-multi-org/organizations/org1/enroll.sh new file mode 100755 index 00000000..2bf4ab07 --- /dev/null +++ b/sample-network-multi-org/organizations/org1/enroll.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org1 services to the "org1" namespace +# +export NAMESPACE=org1 + +# +# Save all of the organization enrollments in a local folder. +# +ENROLLMENTS_DIR=${PWD}/organizations/org1/enrollments + +# +# Before we can work with the CA, extract the CA's TLS certificate and +# store in .pem format for access with client utilities. +# +write_pem ca .tls.cert $ENROLLMENTS_DIR/ca-tls-cert.pem + +# Enroll the org1 admin user. Registration is performed by the operator according +# to entries in the org2-ca CRD. +enroll org1 org1admin org1adminpw + +# create an msp config.yaml to indicate the user is an admin for the org +CA_CERT_NAME=org1-ca-ca-org1-localho-st-ca.pem +write_msp_config ca $CA_CERT_NAME $ENROLLMENTS_DIR/org1admin/msp + +# Enroll the root CA administrator such that users can later be registered and enrolled for +# identities of transactions submitted to the ledger. +enroll org1 rcaadmin rcaadminpw + +# Enroll a client user for submitting transactions through a gateway +# cliant application. This user has been registered at the CA in the +# bootstrap registrations by the operator. +enroll org1 org1user org1userpw \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org1/export_msp.sh b/sample-network-multi-org/organizations/org1/export_msp.sh new file mode 100755 index 00000000..d18ca774 --- /dev/null +++ b/sample-network-multi-org/organizations/org1/export_msp.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org1 services to the "org1" namespace +# +export NAMESPACE=org1 + +print "Exporting org1 channel MSP" + +# +# Prepare a folder structure containing the organization's MSP certificates +# necessary to join the consortium. +# +ORG_MSP_DIR=channel-config/organizations/peerOrganizations/org1.localho.st/msp + +write_pem ca .ca.signcerts $ORG_MSP_DIR/cacerts/ca-signcert.pem +write_pem ca .tlsca.signcerts $ORG_MSP_DIR/tlscacerts/tlsca-signcert.pem +write_msp_config ca ca-signcert.pem $ORG_MSP_DIR \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org1/install_chaincode.sh b/sample-network-multi-org/organizations/org1/install_chaincode.sh new file mode 100755 index 00000000..c8c656e9 --- /dev/null +++ b/sample-network-multi-org/organizations/org1/install_chaincode.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org1 services to the "org1" namespace +# +export NAMESPACE=org1 + +# +# Download the chaincode package. (Or prepare one here with pkgcc.sh, tar, etc.) +# +CHAINCODE_PACKAGE=organizations/org1/chaincode/$CHAINCODE_PKG_NAME +if [ ! -f "$CHAINCODE_PACKAGE" ]; then + print "downloading k8s chaincode package $CHAINCODE_PKG_URL" + mkdir -p $(dirname $CHAINCODE_PACKAGE) + curl -L $CHAINCODE_PKG_URL > $CHAINCODE_PACKAGE +fi + + +# +# Install the package on all of the org peers +# todo: find a reliable way to test if the chaincode PACKAGE_ID has been installed (queryinstalled, getinstalled, ...) +# + +# org1-peer1 +appear_as Org1MSP org1 peer1 +PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid $CHAINCODE_PACKAGE) + +print "installing $CHAINCODE_PKG_URL to $CORE_PEER_ADDRESS" +echo $PACKAGE_ID +peer lifecycle chaincode install $CHAINCODE_PACKAGE || true + +# org1-peer2 +appear_as Org1MSP org1 peer2 +PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid $CHAINCODE_PACKAGE) + +print "installing $CHAINCODE_PKG_URL to $CORE_PEER_ADDRESS" +echo $PACKAGE_ID +peer lifecycle chaincode install $CHAINCODE_PACKAGE || true + + +# +# Approve the chaincode for the org +# +print "approving $CHAINCODE_NAME for $org" +peer lifecycle \ + chaincode approveformyorg \ + --channelID ${CHANNEL_NAME} \ + --name ${CHAINCODE_NAME} \ + --version ${CHAINCODE_VERSION} \ + --sequence ${CHAINCODE_SEQUENCE} \ + --package-id ${PACKAGE_ID} \ + --orderer ${ORDERER_ENDPOINT} \ + --tls --cafile ${ORDERER_TLS_CERT} \ + --connTimeout 15s + +# +# Commit the chaincode package to the channel +# +# The chaincode contract will be committed to the channel by org2. +# +#print "committing $CHAINCODE_NAME to $CHANNEL_NAME" +#peer lifecycle \ +# chaincode commit \ +# --channelID ${CHANNEL_NAME} \ +# --name ${CHAINCODE_NAME} \ +# --version ${CHAINCODE_VERSION} \ +# --sequence ${CHAINCODE_SEQUENCE} \ +# --orderer ${ORDERER_ENDPOINT} \ +# --tls --cafile ${ORDERER_TLS_CERT} \ +# --connTimeout 15s \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org1/join_channel.sh b/sample-network-multi-org/organizations/org1/join_channel.sh new file mode 100755 index 00000000..49e2ef40 --- /dev/null +++ b/sample-network-multi-org/organizations/org1/join_channel.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org1 services to the "org1" namespace +# +export NAMESPACE=org1 + +# +# Join peer1 to the channel +# +print "joining org1 peer1 to $CHANNEL_NAME" +appear_as Org1MSP org1 peer1 +peer channel join --blockpath channel-config/${CHANNEL_NAME}_genesis_block.pb + +# +# Join peer2 to the channel +# +print "joining org1 peer2 to $CHANNEL_NAME" +appear_as Org1MSP org1 peer2 +peer channel join --blockpath channel-config/${CHANNEL_NAME}_genesis_block.pb diff --git a/sample-network-multi-org/organizations/org1/org1-ca.yaml b/sample-network-multi-org/organizations/org1/org1-ca.yaml new file mode 100644 index 00000000..3f5e88cd --- /dev/null +++ b/sample-network-multi-org/organizations/org1/org1-ca.yaml @@ -0,0 +1,115 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: ibp.com/v1beta1 +kind: IBPCA +metadata: + name: ca +spec: + action: + renew: {} + configoverride: + ca: + affiliations: + org1: + - department1 + - department2 + org2: + - department1 + registry: + identities: + - name: org1admin + pass: org1adminpw + type: admin + - name: rcaadmin + pass: rcaadminpw + type: client + attrs: + hf.Registrar.Roles: "*" + hf.Registrar.DelegateRoles: "*" + hf.Revoker: true + hf.IntermediateCA: true + hf.GenCRL: true + hf.Registrar.Attributes: "*" + hf.AffiliationMgr: true + - name: org1user + pass: org1userpw + type: client + - name: peer1 + pass: peer1pw + type: peer + - name: peer2 + pass: peer2pw + type: peer + debug: true + signing: + default: + expiry: 87600h0m0s + tlsca: + affiliations: + org1: + - department1 + - department2 + registry: + identities: + - name: peer1 + pass: peer1pw + type: peer + - name: peer2 + pass: peer2pw + type: peer + debug: true + signing: + default: + expiry: 87600h0m0s + customNames: + pvc: {} + domain: org1.localho.st + images: + caImage: ${CA_IMAGE} + caTag: ${CA_IMAGE_TAG} + caInitImage: registry.access.redhat.com/ubi8/ubi-minimal + caInitTag: latest + ingress: + class: "" + tlsSecretName: "" + license: + accept: true + replicas: 1 + resources: + ca: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + init: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + service: + type: ClusterIP + storage: + ca: + class: standard + size: 100M + version: 1.5.5 diff --git a/sample-network-multi-org/organizations/org1/org1-peer-gateway.yaml b/sample-network-multi-org/organizations/org1/org1-peer-gateway.yaml new file mode 100644 index 00000000..20c399ac --- /dev/null +++ b/sample-network-multi-org/organizations/org1/org1-peer-gateway.yaml @@ -0,0 +1,59 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: peer-gateway + labels: + app: peer-gateway + app.kubernetes.io/instance: fabricpeer + app.kubernetes.io/managed-by: fabric-operator + app.kubernetes.io/name: fabric + creator: fabric + orgname: Org1MSP +spec: + # This selector stanza will match on the orgname: label below, distributing connections to all + # peers matching the org MSP. + selector: + # app: peer1 + app.kubernetes.io/instance: fabricpeer + app.kubernetes.io/managed-by: fabric-operator + app.kubernetes.io/name: fabric + creator: fabric + orgname: Org1MSP + ports: + - name: peer-api + port: 7051 + protocol: TCP + targetPort: 7051 + +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: peer-gateway + annotations: + nginx.ingress.kubernetes.io/proxy-connect-timeout: 60s + nginx.ingress.kubernetes.io/ssl-passthrough: "true" + labels: + app: peer-gateway + app.kubernetes.io/instance: fabricpeer + app.kubernetes.io/managed-by: fabric-operator + app.kubernetes.io/name: fabric + creator: fabric + orgname: Org1MSP +spec: + ingressClassName: nginx + rules: + - host: org1-peer-gateway.org1.localho.st + http: + paths: + - backend: + service: + name: peer-gateway + port: + name: peer-api + path: / + pathType: ImplementationSpecific + tls: + - hosts: + - org1-peer-gateway.org1.localho.st \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org1/org1-peer1.yaml b/sample-network-multi-org/organizations/org1/org1-peer1.yaml new file mode 100644 index 00000000..8eacec85 --- /dev/null +++ b/sample-network-multi-org/organizations/org1/org1-peer1.yaml @@ -0,0 +1,103 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: ibp.com/v1beta1 +kind: IBPPeer +metadata: + name: peer1 +spec: + version: "${FABRIC_VERSION}" + domain: "org1.localho.st" + peerExternalEndpoint: "org1-peer1-peer.org1.localho.st:443" + license: + accept: true + action: + enroll: {} + reenroll: {} + configoverride: + peer: + keepalive: + minInterval: 61s + customNames: + pvc: {} + images: + peerInitImage: registry.access.redhat.com/ubi8/ubi-minimal + peerInitTag: latest + peerImage: ${PEER_IMAGE} + peerTag: ${PEER_IMAGE_TAG} + grpcwebImage: ghcr.io/hyperledger-labs/grpc-web + grpcwebTag: latest + mspID: Org1MSP + mspSecret: peer1-secret + secret: + enrollment: + component: + caname: ca + cahost: "org1-ca-ca.org1.localho.st" + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "peer1" + enrollsecret: "peer1pw" + tls: + caname: tlsca + cahost: "org1-ca-ca.org1.localho.st" + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "peer1" + enrollsecret: "peer1pw" + csr: + hosts: + - "peer1" + - "peer1.org1.svc.cluster.local" + - "org1-peer-gateway.org1.localho.st" + chaincodeBuilderConfig: + peername: org1-peer1 + service: + type: ClusterIP + stateDb: leveldb + storage: + peer: + class: "standard" + size: 5G + statedb: + class: "standard" + size: 10Gi + resources: + init: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + peer: + limits: + cpu: 500m + memory: 1G + requests: + cpu: 10m + memory: 10M + proxy: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org1/org1-peer2.yaml b/sample-network-multi-org/organizations/org1/org1-peer2.yaml new file mode 100644 index 00000000..985b23a9 --- /dev/null +++ b/sample-network-multi-org/organizations/org1/org1-peer2.yaml @@ -0,0 +1,103 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: ibp.com/v1beta1 +kind: IBPPeer +metadata: + name: peer2 +spec: + version: "${FABRIC_VERSION}" + domain: "org1.localho.st" + peerExternalEndpoint: "org1-peer2-peer.org1.localho.st:443" + license: + accept: true + action: + enroll: {} + reenroll: {} + configoverride: + peer: + keepalive: + minInterval: 61s + customNames: + pvc: {} + images: + peerInitImage: registry.access.redhat.com/ubi8/ubi-minimal + peerInitTag: latest + peerImage: ${PEER_IMAGE} + peerTag: ${PEER_IMAGE_TAG} + grpcwebImage: ghcr.io/hyperledger-labs/grpc-web + grpcwebTag: latest + mspID: Org1MSP + mspSecret: peer2-secret + secret: + enrollment: + component: + caname: ca + cahost: "org1-ca-ca.org1.localho.st" + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "peer1" + enrollsecret: "peer1pw" + tls: + caname: tlsca + cahost: "org1-ca-ca.org1.localho.st" + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "peer1" + enrollsecret: "peer1pw" + csr: + hosts: + - "peer2" + - "peer2.org1.svc.cluster.local" + - "org1-peer-gateway.org1.localho.st" + chaincodeBuilderConfig: + peername: peer2 + service: + type: ClusterIP + stateDb: leveldb + storage: + peer: + class: "standard" + size: 5G + statedb: + class: "standard" + size: 10Gi + resources: + init: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + peer: + limits: + cpu: 500m + memory: 1G + requests: + cpu: 10m + memory: 10M + proxy: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org1/start.sh b/sample-network-multi-org/organizations/org1/start.sh new file mode 100755 index 00000000..a5907598 --- /dev/null +++ b/sample-network-multi-org/organizations/org1/start.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org1 services to the "org1" namespace +# +export NAMESPACE=org1 + +# +# CA +# +print "starting org1 CA" + +apply_template organizations/org1/org1-ca.yaml +sleep 5 +wait_for ibpca ca + +# Retrieve the org CA certificate for the bootstrap enrollment of peers/orderers. +# This value will be substituted from the environment into the node CRDs. +export CA_CERT=$(connection_profile_cert ca .tls.cert) + + +# +# Network nodes +# +print "starting org1 orderers" + +print "starting org1 peers" + +apply_template organizations/org1/org1-peer1.yaml +apply_template organizations/org1/org1-peer2.yaml +sleep 5 + +wait_for ibppeer peer1 +wait_for ibppeer peer2 + + + +# +# Deploy a load-balanced gateway service URL fronting the org's peer nodes. +# When submitting transactions through the gateway, the gateway peers will +# distribute transactions across the peers in the network, maintaining a +# balanced ledger height. +# +print "creating gateway service alias org1-peer-gateway" + +apply_template organizations/org1/org1-peer-gateway.yaml \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org2/enroll.sh b/sample-network-multi-org/organizations/org2/enroll.sh new file mode 100755 index 00000000..1c4a6227 --- /dev/null +++ b/sample-network-multi-org/organizations/org2/enroll.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org2 services to the "org2" namespace +# +export NAMESPACE=org2 + +# +# Save all of the organization enrollments in a local folder. +# +ENROLLMENTS_DIR=${PWD}/organizations/org2/enrollments + +# +# Before we can work with the CA, extract the CA's TLS certificate and +# store in .pem format for access with client utilities. +# +write_pem ca .tls.cert $ENROLLMENTS_DIR/ca-tls-cert.pem + +# Enroll the org2 admin user. Registration is performed by the operator according +# to entries in the org2-ca CRD. +enroll org2 org2admin org2adminpw + +# create an msp config.yaml to indicate the user is an admin for the org +CA_CERT_NAME=org2-ca-ca-org2-localho-st-ca.pem +write_msp_config ca $CA_CERT_NAME $ENROLLMENTS_DIR/org2admin/msp + +# Enroll the root CA administrator such that users can later be registered and enrolled for +# identities of transactions submitted to the ledger. +enroll org2 rcaadmin rcaadminpw + +# Enroll a client user for submitting transactions through a gateway +# cliant application. This user has been registered at the CA in the +# bootstrap registrations by the operator. +enroll org2 org2user org2userpw \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org2/export_msp.sh b/sample-network-multi-org/organizations/org2/export_msp.sh new file mode 100755 index 00000000..f9eea5df --- /dev/null +++ b/sample-network-multi-org/organizations/org2/export_msp.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org2 services to the "org2" namespace +# +export NAMESPACE=org2 + +print "Exporting org2 channel MSP" + +# +# Prepare a folder structure containing the organization's MSP certificates +# necessary to join the consortium. +# +ORG_MSP_DIR=channel-config/organizations/peerOrganizations/org2.localho.st/msp + +write_pem ca .ca.signcerts $ORG_MSP_DIR/cacerts/ca-signcert.pem +write_pem ca .tlsca.signcerts $ORG_MSP_DIR/tlscacerts/tlsca-signcert.pem +write_msp_config ca ca-signcert.pem $ORG_MSP_DIR diff --git a/sample-network-multi-org/organizations/org2/install_chaincode.sh b/sample-network-multi-org/organizations/org2/install_chaincode.sh new file mode 100755 index 00000000..0094f7f8 --- /dev/null +++ b/sample-network-multi-org/organizations/org2/install_chaincode.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org2 services to the "org2" namespace +# +export NAMESPACE=org2 + + + +# +# Download the chaincode package. (Or prepare one here with pkgcc.sh, tar, etc.) +# +CHAINCODE_PACKAGE=organizations/org2/chaincode/$CHAINCODE_PKG_NAME +if [ ! -f "$CHAINCODE_PACKAGE" ]; then + print "downloading k8s chaincode package $CHAINCODE_PKG_URL" + mkdir -p $(dirname $CHAINCODE_PACKAGE) + curl -L $CHAINCODE_PKG_URL > $CHAINCODE_PACKAGE +fi + + +# +# Install the package on all of the org peers +# todo: find a reliable way to test if the chaincode PACKAGE_ID has been installed (queryinstalled, getinstalled, ...) +# + +# org2-peer1 +appear_as Org2MSP org2 peer1 +export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid $CHAINCODE_PACKAGE) + +print "installing $CHAINCODE_PKG_URL to $CORE_PEER_ADDRESS" +echo $PACKAGE_ID +peer lifecycle chaincode install $CHAINCODE_PACKAGE || true + +# org2-peer2 +appear_as Org2MSP org2 peer2 +export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid $CHAINCODE_PACKAGE) + +print "installing $CHAINCODE_PKG_URL to $CORE_PEER_ADDRESS" +echo $PACKAGE_ID +peer lifecycle chaincode install $CHAINCODE_PACKAGE || true + + +# +# Approve the chaincode for the org +# +print "approving $CHAINCODE_NAME for $org" +peer lifecycle \ + chaincode approveformyorg \ + --channelID ${CHANNEL_NAME} \ + --name ${CHAINCODE_NAME} \ + --version ${CHAINCODE_VERSION} \ + --sequence ${CHAINCODE_SEQUENCE} \ + --package-id ${PACKAGE_ID} \ + --orderer ${ORDERER_ENDPOINT} \ + --tls --cafile ${ORDERER_TLS_CERT} \ + --connTimeout 15s + +# +# Commit the chaincode to the channel +# +print "committing $CHAINCODE_NAME to $CHANNEL_NAME" +peer lifecycle \ + chaincode commit \ + --channelID ${CHANNEL_NAME} \ + --name ${CHAINCODE_NAME} \ + --version ${CHAINCODE_VERSION} \ + --sequence ${CHAINCODE_SEQUENCE} \ + --orderer ${ORDERER_ENDPOINT} \ + --tls --cafile ${ORDERER_TLS_CERT} \ + --connTimeout 15s \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org2/join_channel.sh b/sample-network-multi-org/organizations/org2/join_channel.sh new file mode 100755 index 00000000..ce66dcbd --- /dev/null +++ b/sample-network-multi-org/organizations/org2/join_channel.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org2 services to the "org2" namespace +# +export NAMESPACE=org2 + +# +# Join peer1 to the channel +# +print "joining org2 peer1 to $CHANNEL_NAME" +appear_as Org2MSP org2 peer1 +peer channel join --blockpath channel-config/${CHANNEL_NAME}_genesis_block.pb + +# +# Join peer2 to the channel +# +print "joining org2 peer2 to $CHANNEL_NAME" +appear_as Org2MSP org2 peer2 +peer channel join --blockpath channel-config/${CHANNEL_NAME}_genesis_block.pb diff --git a/sample-network-multi-org/organizations/org2/org2-ca.yaml b/sample-network-multi-org/organizations/org2/org2-ca.yaml new file mode 100644 index 00000000..d732f990 --- /dev/null +++ b/sample-network-multi-org/organizations/org2/org2-ca.yaml @@ -0,0 +1,113 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: ibp.com/v1beta1 +kind: IBPCA +metadata: + name: ca +spec: + action: + renew: {} + configoverride: + ca: + affiliations: + org2: + - department1 + - department2 + registry: + identities: + - name: org2admin + pass: org2adminpw + type: admin + - name: rcaadmin + pass: rcaadminpw + type: client + attrs: + hf.Registrar.Roles: "*" + hf.Registrar.DelegateRoles: "*" + hf.Revoker: true + hf.IntermediateCA: true + hf.GenCRL: true + hf.Registrar.Attributes: "*" + hf.AffiliationMgr: true + - name: org2user + pass: org2userpw + type: client + - name: peer1 + pass: peer1pw + type: peer + - name: peer2 + pass: peer2pw + type: peer + debug: true + signing: + default: + expiry: 87600h0m0s + tlsca: + affiliations: + org2: + - department1 + - department2 + registry: + identities: + - name: peer1 + pass: peer1pw + type: peer + - name: peer2 + pass: peer2pw + type: peer + debug: true + signing: + default: + expiry: 87600h0m0s + customNames: + pvc: {} + domain: org2.localho.st + images: + caImage: ${CA_IMAGE} + caTag: ${CA_IMAGE_TAG} + caInitImage: registry.access.redhat.com/ubi8/ubi-minimal + caInitTag: latest + ingress: + class: "" + tlsSecretName: "" + license: + accept: true + replicas: 1 + resources: + ca: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + init: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + service: + type: ClusterIP + storage: + ca: + class: standard + size: 100M + version: 1.5.5 diff --git a/sample-network-multi-org/organizations/org2/org2-peer-gateway.yaml b/sample-network-multi-org/organizations/org2/org2-peer-gateway.yaml new file mode 100644 index 00000000..3ac5d31c --- /dev/null +++ b/sample-network-multi-org/organizations/org2/org2-peer-gateway.yaml @@ -0,0 +1,59 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: peer-gateway + labels: + app: peer-gateway + app.kubernetes.io/instance: fabricpeer + app.kubernetes.io/managed-by: fabric-operator + app.kubernetes.io/name: fabric + creator: fabric + orgname: Org2MSP +spec: + # This selector stanza will match on the orgname: label below, distributing connections to all + # peers matching the org MSP. + selector: + # app: peer1 + app.kubernetes.io/instance: fabricpeer + app.kubernetes.io/managed-by: fabric-operator + app.kubernetes.io/name: fabric + creator: fabric + orgname: Org2MSP + ports: + - name: peer-api + port: 7051 + protocol: TCP + targetPort: 7051 + +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: peer-gateway + annotations: + nginx.ingress.kubernetes.io/proxy-connect-timeout: 60s + nginx.ingress.kubernetes.io/ssl-passthrough: "true" + labels: + app: peer-gateway + app.kubernetes.io/instance: fabricpeer + app.kubernetes.io/managed-by: fabric-operator + app.kubernetes.io/name: fabric + creator: fabric + orgname: Org2MSP +spec: + ingressClassName: nginx + rules: + - host: org2-peer-gateway.org2.localho.st + http: + paths: + - backend: + service: + name: peer-gateway + port: + name: peer-api + path: / + pathType: ImplementationSpecific + tls: + - hosts: + - org2-peer-gateway.org2.localho.st \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org2/org2-peer1.yaml b/sample-network-multi-org/organizations/org2/org2-peer1.yaml new file mode 100644 index 00000000..a12b847a --- /dev/null +++ b/sample-network-multi-org/organizations/org2/org2-peer1.yaml @@ -0,0 +1,103 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: ibp.com/v1beta1 +kind: IBPPeer +metadata: + name: peer1 +spec: + version: "${FABRIC_VERSION}" + domain: "org2.localho.st" + peerExternalEndpoint: "org2-peer1-peer.org2.localho.st:443" + license: + accept: true + action: + enroll: {} + reenroll: {} + configoverride: + peer: + keepalive: + minInterval: 61s + customNames: + pvc: {} + images: + peerInitImage: registry.access.redhat.com/ubi8/ubi-minimal + peerInitTag: latest + peerImage: ${PEER_IMAGE} + peerTag: ${PEER_IMAGE_TAG} + grpcwebImage: ghcr.io/hyperledger-labs/grpc-web + grpcwebTag: latest + mspID: Org2MSP + mspSecret: org2-peer1-secret + secret: + enrollment: + component: + caname: ca + cahost: "org2-ca-ca.org2.localho.st" + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "peer1" + enrollsecret: "peer1pw" + tls: + caname: tlsca + cahost: "org2-ca-ca.org2.localho.st" + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "peer1" + enrollsecret: "peer1pw" + csr: + hosts: + - "peer1" + - "peer1.org2.svc.cluster.local" + - "org2-peer-gateway.org2.localho.st" + chaincodeBuilderConfig: + peername: org2-peer1 + service: + type: ClusterIP + stateDb: leveldb + storage: + peer: + class: "standard" + size: 5G + statedb: + class: "standard" + size: 10Gi + resources: + init: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + peer: + limits: + cpu: 500m + memory: 1G + requests: + cpu: 10m + memory: 10M + proxy: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org2/org2-peer2.yaml b/sample-network-multi-org/organizations/org2/org2-peer2.yaml new file mode 100644 index 00000000..6902817e --- /dev/null +++ b/sample-network-multi-org/organizations/org2/org2-peer2.yaml @@ -0,0 +1,103 @@ +# +# Copyright contributors to the Hyperledger Fabric Operator project +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: ibp.com/v1beta1 +kind: IBPPeer +metadata: + name: peer2 +spec: + version: "${FABRIC_VERSION}" + domain: "org2.localho.st" + peerExternalEndpoint: "org2-peer2-peer.org2.localho.st:443" + license: + accept: true + action: + enroll: {} + reenroll: {} + configoverride: + peer: + keepalive: + minInterval: 61s + customNames: + pvc: {} + images: + peerInitImage: registry.access.redhat.com/ubi8/ubi-minimal + peerInitTag: latest + peerImage: ${PEER_IMAGE} + peerTag: ${PEER_IMAGE_TAG} + grpcwebImage: ghcr.io/hyperledger-labs/grpc-web + grpcwebTag: latest + mspID: Org2MSP + mspSecret: org2-peer2-secret + secret: + enrollment: + component: + caname: ca + cahost: "org2-ca-ca.org2.localho.st" + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "peer1" + enrollsecret: "peer1pw" + tls: + caname: tlsca + cahost: "org2-ca-ca.org2.localho.st" + caport: "443" + catls: + cacert: "${CA_CERT}" + enrollid: "peer1" + enrollsecret: "peer1pw" + csr: + hosts: + - "peer2" + - "org2-peer2.org2.svc.cluster.local" + - "org2-peer-gateway.org2.localho.st" + chaincodeBuilderConfig: + peername: org2-peer2 + service: + type: ClusterIP + stateDb: leveldb + storage: + peer: + class: "standard" + size: 5G + statedb: + class: "standard" + size: 10Gi + resources: + init: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M + peer: + limits: + cpu: 500m + memory: 1G + requests: + cpu: 10m + memory: 10M + proxy: + limits: + cpu: 100m + memory: 200M + requests: + cpu: 10m + memory: 10M \ No newline at end of file diff --git a/sample-network-multi-org/organizations/org2/start.sh b/sample-network-multi-org/organizations/org2/start.sh new file mode 100755 index 00000000..c1d44c90 --- /dev/null +++ b/sample-network-multi-org/organizations/org2/start.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +set -euo pipefail +. scripts/utils.sh + +# +# Bind all org2 services to the "org2" namespace +# +export NAMESPACE=org2 + +# +# CA +# +print "starting org2 CA" + +apply_template organizations/org2/org2-ca.yaml +sleep 5 +wait_for ibpca ca + +# Retrieve the org CA certificate for the bootstrap enrollment of peers/orderers. +# This value will be substituted from the environment into the node CRDs. +export CA_CERT=$(connection_profile_cert ca .tls.cert) + +# +# Network nodes +# +print "starting org2 orderers" + +print "starting org2 peers" + +apply_template organizations/org2/org2-peer1.yaml +apply_template organizations/org2/org2-peer2.yaml +sleep 5 + +wait_for ibppeer peer1 +wait_for ibppeer peer2 + + +# +# Deploy a load-balanced gateway service URL fronting the org's peer nodes. +# When submitting transactions through the gateway, the gateway peers will +# distribute transactions across the peers in the network, maintaining a +# balanced ledger height. +# +print "creating gateway service alias org2-peer-gateway" + +apply_template organizations/org2/org2-peer-gateway.yaml \ No newline at end of file diff --git a/sample-network-multi-org/scripts/check-kube.sh b/sample-network-multi-org/scripts/check-kube.sh new file mode 100755 index 00000000..8ea77ccf --- /dev/null +++ b/sample-network-multi-org/scripts/check-kube.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# + +# All checks run in the workshop root folder +cd "$(dirname "$0")"/.. + +. scripts/utils.sh + +EXIT=0 + + +function cluster_info() { + kubectl cluster-info &>/dev/null +} + +function nginx() { + kubectl -n ingress-nginx get all &>/dev/null + kubectl -n ingress-nginx get deployment.apps/ingress-nginx-controller &>/dev/null + curl http://localho.st &>/dev/null + curl --insecure https://localho.st:443 &>/dev/null +} + +function container_registry() { + curl --fail http://localhost2:5000/v2/_catalog &>/dev/null +} + + +check cluster_info "k8s API controller is running" +check nginx "Nginx ingress is running at https://localho.st" +check container_registry "Container registry is running at localhost:5000" + +exit $EXIT + diff --git a/sample-network-multi-org/scripts/check-network.sh b/sample-network-multi-org/scripts/check-network.sh new file mode 100755 index 00000000..af5e1d32 --- /dev/null +++ b/sample-network-multi-org/scripts/check-network.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# +# Copyright contributors to the Hyperledgendary Kubernetes Test Network project +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# + +# All checks run in the workshop root folder +cd "$(dirname "$0")"/.. + +. scripts/utils.sh + +# todo: need to check the enrollments here (just enroll org) +# todo: need to check the MSP exports here in the channel-config/organizations (just export-msp org) + + + +EXIT=0 + +function operator_crds() { + kubectl get customresourcedefinition.apiextensions.k8s.io/ibpcas.ibp.com + kubectl get customresourcedefinition.apiextensions.k8s.io/ibpconsoles.ibp.com + kubectl get customresourcedefinition.apiextensions.k8s.io/ibporderers.ibp.com + kubectl get customresourcedefinition.apiextensions.k8s.io/ibppeers.ibp.com +} + +function org0_operator_deployed() { + kubectl -n org0 get deployment fabric-operator +} + +function org1_operator_deployed() { + kubectl -n org1 get deployment fabric-operator +} + +function org2_operator_deployed() { + kubectl -n org2 get deployment fabric-operator +} + + +# Did it apply the CRDs? +function org0_custom_resources() { + kubectl -n org0 get ibpca ca + kubectl -n org0 get ibporderer orderernode1 + kubectl -n org0 get ibporderer orderernode2 + kubectl -n org0 get ibporderer orderernode3 +} + +function org1_custom_resources() { + kubectl -n org1 get ibpca ca + kubectl -n org1 get ibppeer peer1 + kubectl -n org1 get ibppeer peer2 +} + +function org2_custom_resources() { + kubectl -n org2 get ibpca ca + kubectl -n org2 get ibppeer peer1 + kubectl -n org2 get ibppeer peer2 +} + +function org0_deployments() { + kubectl -n org0 get deployment ca + kubectl -n org0 get deployment orderernode1 + kubectl -n org0 get deployment orderernode2 + kubectl -n org0 get deployment orderernode3 +} + +function org1_deployments() { + kubectl -n org1 get deployment ca + kubectl -n org1 get deployment peer1 + kubectl -n org1 get deployment peer2 +} + +function org2_deployments() { + kubectl -n org2 get deployment ca + kubectl -n org2 get deployment peer1 + kubectl -n org2 get deployment peer2 +} + +# Hit the CAs using the TLS certs, etc. +function org0_cas_ready() { + curl --fail -s --cacert organizations/org0/enrollments/ca-tls-cert.pem https://org0-ca-ca.org0.localho.st/cainfo +} + +function org1_cas_ready() { + curl --fail -s --cacert organizations/org1/enrollments/ca-tls-cert.pem https://org1-ca-ca.org1.localho.st/cainfo +} + +function org2_cas_ready() { + curl --fail -s --cacert organizations/org2/enrollments/ca-tls-cert.pem https://org2-ca-ca.org2.localho.st/cainfo +} + +function channel_msp() { + find channel-config/organizations +} + + +check operator_crds "fabric-operator CRDs have been installed" + +check org0_operator_deployed "org0 fabric-operator has been deployed" +check org1_operator_deployed "org1 fabric-operator has been deployed" +check org2_operator_deployed "org2 fabric-operator has been deployed" + +check org0_custom_resources "org0 CAs, Orderers, and Peers have been created" +check org1_custom_resources "org1 CAs, Orderers, and Peers have been created" +check org2_custom_resources "org2 CAs, Orderers, and Peers have been created" + +check org0_deployments "org0 services have been deployed" +check org1_deployments "org1 services have been deployed" +check org2_deployments "org2 services have been deployed" + +check org0_cas_ready "org0 CAs are available at ingress" +check org1_cas_ready "org1 CAs are available at ingress" +check org2_cas_ready "org2 CAs are available at ingress" + +#check channel_msp "Channel MSP has been exported" + +exit $EXIT + diff --git a/sample-network-multi-org/scripts/check.sh b/sample-network-multi-org/scripts/check.sh new file mode 100755 index 00000000..6349cda6 --- /dev/null +++ b/sample-network-multi-org/scripts/check.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash + +SUCCESS="✅" +WARN="⚠️ " +EXIT=0 + +if ! command -v docker &> /tmp/cmdpath +then + echo "${WARN} Please install Docker; suggested install commands:" + EXIT=1 +else + echo -e "${SUCCESS} Docker found:\t$(cat /tmp/cmdpath)" +fi + +KUBECTL_VERSION=v1.24.4 # $(curl -L -s https://dl.k8s.io/release/stable.txt) +if ! command -v kubectl &> /tmp/cmdpath +then + echo "${WARN} Please install kubectl if you want to use k8s; suggested install commands:" + + if [ $(uname -s) = Darwin ]; then + if [ $(uname -m) = arm64 ]; then + echo "curl -LO https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/darwin/arm64/kubectl" + echo "chmod +x ./kubectl" + echo "sudo mv ./kubectl /usr/local/bin/kubectl" + echo "sudo chown root: /usr/local/bin/kubectl" + else + echo "curl -LO https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/darwin/amd64/kubectl" + echo "chmod +x ./kubectl" + echo "sudo mv ./kubectl /usr/local/bin/kubectl" + echo "sudo chown root: /usr/local/bin/kubectl" + fi + else + echo "curl -LO https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" + echo "sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl" + fi + EXIT=1 +else + echo -e "${SUCCESS} kubectl found:\t$(cat /tmp/cmdpath)" + + KUBECTL_CLIENT_VERSION=$(kubectl version --client --output=yaml | grep gitVersion | cut -c 15-) + KUBECTL_CLIENT_MINOR_VERSION=$(kubectl version --client --output=yaml | grep minor | cut -c 11-12) + if [ "${KUBECTL_CLIENT_MINOR_VERSION}" -lt "24" ]; then + echo -e "${WARN} Found kubectl client version ${KUBECTL_CLIENT_VERSION}, which may be out of date. Please ensure client version >= ${KUBECTL_VERSION}" + EXIT=1 + fi +fi + +# Install kind +KIND_VERSION=0.14.0 +if ! command -v kind &> /tmp/cmdpath +then + echo "${WARN} Please install kind; suggested install commands:" + echo + if [ $(uname -s) = Darwin ]; then + if [ $(uname -m) = arm64 ]; then + echo "sudo curl --fail --silent --show-error -L https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-darwin-arm64 -o /usr/local/bin/kind" + else + echo "sudo curl --fail --silent --show-error -L https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-darwin-amd64 -o /usr/local/bin/kind" + fi + else + echo "sudo curl --fail --silent --show-error -L https://kind.sigs.k8s.io/dl/v${KIND_VERSION}/kind-linux-amd64 -o /usr/local/bin/kind" + fi + echo "sudo chmod 755 /usr/local/bin/kind" + echo + EXIT=1 +else + echo -e "${SUCCESS} kind found:\t\t$(cat /tmp/cmdpath)" +fi + +# Install just +JUST_VERSION=1.2.0 +if ! command -v just &> /tmp/cmdpath +then + echo "${WARN} Please install just; suggested install commands:" + echo "curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --tag ${JUST_VERSION} --to /usr/local/bin" + EXIT=1 +else + echo -e "${SUCCESS} Just found:\t\t$(cat /tmp/cmdpath)" +fi + +# Install jq +if ! command -v jq &> /tmp/cmdpath +then + echo "${WARN} Please install jq; suggested install commands:" + echo "sudo apt-update && sudo apt-install -y jq" + EXIT=1 +else + echo -e "${SUCCESS} jq found:\t\t$(cat /tmp/cmdpath)" +fi + +FABRIC_VERSION=2.5.0-beta +FABRIC_CA_VERSION=1.5.6-beta3 +if ! command -v peer &> /tmp/cmdpath +then + echo "${WARN} Please install the Fabric CLI binaries; suggested install commands:" + echo "curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary --fabric-version $FABRIC_VERSION --ca-version $FABRIC_CA_VERSION" + echo 'export PATH=${PWD}/bin:$PATH' + #echo 'export FABRIC_CFG_PATH=${PWD}/config' + EXIT=1 +else + echo -e "${SUCCESS} peer found:\t\t$(cat /tmp/cmdpath)" + + # double-check that the peer binary is compiled for the correct arch. This can occur when installing fabric + # binaries into a multipass VM, then running the Linux binaries from a Mac or windows Host OS via the volume share. + peer version &> /dev/null + rc=$? + if [ $rc -ne 0 ]; then + echo -e "${WARN} Could not execute peer. Was it compiled for the correct architecture?" + peer version + fi +fi + +# tests if varname is defined in the env AND it's an existing directory +function must_declare() { + local varname=$1 + + if [[ ! -d ${!varname} ]]; then + echo "${WARN} ${varname} must be set to a directory" + EXIT=1 + + else + echo -e "${SUCCESS} ${varname}:\t${!varname}" + fi +} + +#must_declare "FABRIC_CFG_PATH" +#must_declare "WORKSHOP_PATH" + +rm /tmp/cmdpath &> /dev/null + +exit $EXIT diff --git a/sample-network-multi-org/scripts/kind_with_nginx.sh b/sample-network-multi-org/scripts/kind_with_nginx.sh new file mode 100755 index 00000000..c90be079 --- /dev/null +++ b/sample-network-multi-org/scripts/kind_with_nginx.sh @@ -0,0 +1,220 @@ +#!/bin/bash + +# +# IBM Confidential +# OCO Source Materials +# +# Organic Growth Ventures +# (C) Copyright IBM Corp. 2022 All Rights Reserved. +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# + +set -eo pipefail +set -x + +KIND_CLUSTER_NAME=kind +KIND_CLUSTER_IMAGE=${KIND_CLUSTER_IMAGE:-kindest/node:v1.24.4} +KIND_API_SERVER_ADDRESS=${KIND_API_SERVER_ADDRESS:-127.0.0.1} +KIND_API_SERVER_PORT=${KIND_API_SERVER_PORT:-8888} +CONTAINER_REGISTRY_NAME=${CONTAINER_REGISTRY_NAME:-kind-registry} +CONTAINER_REGISTRY_ADDRESS=${CONTAINER_REGISTRY_ADDRESS:-127.0.0.1} +CONTAINER_REGISTRY_PORT=${CONTAINER_REGISTRY_PORT:-5000} + +function kind_with_nginx() { + + delete_cluster + + create_cluster + + #start_cert_manager + + start_nginx + + apply_coredns_override + + launch_docker_registry +} + +# +# Delete a kind cluster if it exists +# +function delete_cluster() { + kind delete cluster --name $KIND_CLUSTER_NAME +} + +# +# Create a local KIND cluster +# +function create_cluster() { + cat << EOF | kind create cluster --name $KIND_CLUSTER_NAME --image $KIND_CLUSTER_IMAGE --config=- +--- +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + kubeadmConfigPatches: + - | + kind: InitConfiguration + nodeRegistration: + kubeletExtraArgs: + node-labels: "ingress-ready=true" + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP +networking: + apiServerAddress: ${KIND_API_SERVER_ADDRESS} + apiServerPort: ${KIND_API_SERVER_PORT} + +# create a cluster with the local registry enabled in containerd +containerdConfigPatches: +- |- + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${CONTAINER_REGISTRY_PORT}"] + endpoint = ["http://${CONTAINER_REGISTRY_NAME}:${CONTAINER_REGISTRY_PORT}"] +EOF + + # + # Work around a bug in KIND where DNS is not always resolved correctly on machines with IPv6 + # + for node in $(kind get nodes); + do + docker exec "$node" sysctl net.ipv4.conf.all.route_localnet=1; + done +} + +# +# Install cert-manager.io +# +function start_cert_manager() { + kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.yaml + + sleep 5 + + kubectl -n cert-manager rollout status deploy/cert-manager + kubectl -n cert-manager rollout status deploy/cert-manager-cainjector + kubectl -n cert-manager rollout status deploy/cert-manager-webhook + + # Check for a root CA certificate / secret created by a previous cluster. If present, re-use the + # cert as it could have been imported into the system's keychain. + # TODO: this would be best stored outside of the project - maybe override with an ENV? + local issuer_secret_path=kind/cert-manager/ca-issuer-secret.yaml + if test -f ${issuer_secret_path}; then + echo "Overriding CA root issuer secret" ${issuer_secret_path} + kubectl -n cert-manager create -f ${issuer_secret_path} + fi + + # Apply the cert-manager cluster-issuers + kubectl -n cert-manager apply -k kind/cert-manager + + # Save the root cert for future use in future KIND clusters + if ! test -f ${issuer_secret_path}; then + # todo: use a better wait for the issuer to be ready / secret to be created + sleep 5 + kubectl -n cert-manager get secret ca-issuer-secret -o yaml > ${issuer_secret_path} + fi +} + +# +# Install an Nginx ingress controller bound to port 80 and 443. +# +function start_nginx() { + kubectl apply -k kind/nginx + + sleep 10 + + kubectl wait \ + --namespace ingress-nginx \ + --for=condition=ready pod \ + --selector=app.kubernetes.io/component=controller \ + --timeout=3m +} + +# +# Override Core DNS with a wildcard matcher for the "*.localho.st" domain, binding to the +# IP address of the Nginx ingress controller on the kubernetes internal network. Effectively this +# "steals" the domain name for *.localho.st, directing traffic to the Nginx load balancer, rather +# than to the loopback interface at 127.0.0.1. +# +function apply_coredns_override() { + CLUSTER_IP=$(kubectl -n ingress-nginx get svc ingress-nginx-controller -o json | jq -r .spec.clusterIP) + + cat << EOF | kubectl apply -f - +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: coredns + namespace: kube-system +data: + Corefile: | + .:53 { + errors + health { + lameduck 5s + } + ready + rewrite name regex (.*)\.localho\.st host.ingress.internal + hosts { + ${CLUSTER_IP} host.ingress.internal + fallthrough + } + kubernetes cluster.local in-addr.arpa ip6.arpa { + pods insecure + fallthrough in-addr.arpa ip6.arpa + ttl 30 + } + prometheus :9153 + forward . /etc/resolv.conf { + max_concurrent 1000 + } + cache 30 + loop + reload + loadbalance + } +EOF + + kubectl -n kube-system rollout restart deployment/coredns +} + +function launch_docker_registry() { + + # create registry container unless it already exists + running="$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" + if [ "${running}" != 'true' ]; then + docker run \ + --detach \ + --restart always \ + --name "${CONTAINER_REGISTRY_NAME}" \ + --publish "${CONTAINER_REGISTRY_ADDRESS}:${CONTAINER_REGISTRY_PORT}:${CONTAINER_REGISTRY_PORT}" \ + registry:2 + fi + + # connect the registry to the cluster network + # (the network may already be connected) + docker network connect "kind" "${CONTAINER_REGISTRY_NAME}" || true + + # Document the local registry + # https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry + cat </dev/null ; then + printf "\r%s %-30s" $SUCCESS $name + else + printf "\r%s %-30s" $WARN $name + EXIT=1 + fi + + echo $message +} + +function wait_for() { + local type=$1 + local name=$2 + + kubectl -n ${NAMESPACE} wait $type $name --for jsonpath='{.status.type}'=Deployed --timeout=3m + kubectl -n ${NAMESPACE} rollout status deploy $name +} + +function apply_template() { + local template=$1 + cat ${template} | envsubst | kubectl -n ${NAMESPACE} apply -f - +} + +# Read a certificate by name from a node connection-profile config map. +function connection_profile_cert() { + local node=$1 + local path=$2 + + kubectl -n ${NAMESPACE} get cm/${node}-connection-profile -o json \ + | jq -r .binaryData.\"profile.json\" \ + | base64 -d \ + | jq -r ${path} +} + +# Extract, decode, and save a certificate in .pem format to a local file +function write_pem() { + local node=$1 + local jq_path=$2 + local to_file=$3 + + mkdir -p $(dirname $to_file) + + echo $(connection_profile_cert $node $jq_path) | base64 -d >& $to_file +} + +# create an enrollment MSP config.yaml +function write_msp_config() { + local ca_name=$1 + local ca_cert_name=$2 + local msp_dir=$3 + + cat << EOF > ${msp_dir}/config.yaml +NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/${ca_cert_name} + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/${ca_cert_name} + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/${ca_cert_name} + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/${ca_cert_name} + OrganizationalUnitIdentifier: orderer +EOF +} + +# Enroll a user at an org CA. +function enroll() { + do_enroll msp ca $@ +} + +# Enroll a user at an org TLS CA +function enroll_tls() { + do_enroll tls tlsca $@ +} + +function do_enroll() { + local msp_type=$1 + local caname=$2 + local org=$3 + local user=$4 + local pazz=$5 + + # Skip the enrollment if a previous enrollment key exists. + local user_dir=$ENROLLMENTS_DIR/$user + local user_key=$user_dir/$msp_type/keystore/key.pem + + if [ -f "$user_key" ]; then + print "$user has already been enrolled at $org $caname" + return + fi + + print "enrolling $org $caname $user" + local ca_url=https://${user}:${pazz}@${org}-ca-ca.${org}.localho.st + local tls_certfile=$ENROLLMENTS_DIR/ca-tls-cert.pem + + fabric-ca-client enroll \ + --url $ca_url \ + --tls.certfiles $tls_certfile \ + --mspdir $user_dir/$msp_type \ + --caname $caname + + # Enrollment creates a key with a dynamic, hashed file name. Move this to a predictable location + mv $user_dir/$msp_type/keystore/*_sk $user_key +} + +# Set the peer CLI environment in order to run commands as an org admin +function appear_as() { + local mspid=$1 + local org=$2 + local peer=$3 + + export FABRIC_CFG_PATH=${PWD}/channel-config/config + export CORE_PEER_ADDRESS=${org}-${peer}-peer.${org}.localho.st:443 + export CORE_PEER_LOCALMSPID=${mspid} + export CORE_PEER_MSPCONFIGPATH=$PWD/organizations/${org}/enrollments/${org}admin/msp + export CORE_PEER_TLS_ENABLED=true + export CORE_PEER_TLS_ROOTCERT_FILE=$PWD/channel-config/organizations/peerOrganizations/${org}.localho.st/msp/tlscacerts/tlsca-signcert.pem + export CORE_PEER_CLIENT_CONNTIMEOUT=15s + export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s + + export ORDERER_ENDPOINT=org0-orderernode1-orderer.org0.localho.st:443 + export ORDERER_TLS_CERT=${PWD}/channel-config/organizations/ordererOrganizations/org0.localho.st/orderers/orderernode1/tls/signcerts/tls-cert.pem +}