Move fabric-kube-test-network from Hyperledgendary -> samples

Signed-off-by: Josh Kneubuhl <jkneubuh@us.ibm.com>
This commit is contained in:
Josh Kneubuhl 2023-02-09 11:19:30 -05:00
parent cb886be466
commit 05e4b03283
54 changed files with 3891 additions and 2 deletions

View file

@ -12,7 +12,7 @@ inputs:
default: v0.25.3 default: v0.25.3
fabric-version: fabric-version:
description: Version of Hyperledger Fabric description: Version of Hyperledger Fabric
default: 2.5.0-alpha3 default: 2.5.0-beta
ca-version: ca-version:
description: Version of Hyperledger Fabric CA description: Version of Hyperledger Fabric CA
default: 1.5.6-beta3 default: 1.5.6-beta3

View file

@ -64,3 +64,14 @@ jobs:
CHAINCODE_NAME: basic CHAINCODE_NAME: basic
CHAINCODE_LANGUAGE: java CHAINCODE_LANGUAGE: java
CHAINCODE_BUILDER: k8s CHAINCODE_BUILDER: k8s
fabric-operator:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Full Stack Runtime
uses: ./.github/actions/fsat-setup
- name: Test the network
working-directory: test-network-k8s-operator
run: ../ci/scripts/run-k8s-test-network-operator.sh

View file

@ -0,0 +1,121 @@
#!/usr/bin/env bash
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
set -euo pipefail
function print() {
GREEN='\033[0;32m'
NC='\033[0m'
echo
echo -e "${GREEN}${1}${NC}"
}
function touteSuite() {
createCluster
}
function quitterLaScene() {
destroyCluster
}
function createCluster() {
print "Initializing KIND Kubernetes cluster"
just kind
}
function destroyCluster() {
print "Destroying KIND Kubernetes cluster"
just destroy
just unkind
}
# fabric CLI binaries + config
FABRIC_VERSION=2.5.0-beta
FABRIC_CA_VERSION=1.5.6-beta3
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
export PATH=${PWD}/bin:$PATH
export FABRIC_CFG_PATH=${PWD}/config
# Set The Stage: a local KIND cluster
touteSuite
trap "quitterLaScene" EXIT
# Act I: launch Fabric services
#export FABRIC_CFG_PATH=${PWD}/config
just start org0
just start org1
just start org2
just enroll org0
just enroll org1
just enroll org2
just check-network
# Act II: Build a Consortium
just export-msp org0
just export-msp org1
just export-msp org2
just create-genesis-block
just inspect-genesis-block
just join org0
just join org1
just join org2
# Act III: Chaincode and application
just install-cc org1
just install-cc org2
# org1:
export ORG=org1
export MSP_ID=Org1MSP
export $(just show-context $MSP_ID $ORG peer1)
print "env context:"
export
print "querying cc as org1"
peer chaincode query \
-n asset-transfer \
-C mychannel \
-c '{"Args":["org.hyperledger.fabric:GetMetadata"]}'
# org2:
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"]}'
# Client application: (still org2 context)
export USER_MSP_DIR=$PWD/organizations/$ORG/enrollments/${ORG}user/msp
export PRIVATE_KEY=$USER_MSP_DIR/keystore/key.pem
export CERTIFICATE=$USER_MSP_DIR/signcerts/cert.pem
export TLS_CERT=$CORE_PEER_TLS_ROOTCERT_FILE
export ENDPOINT=${ORG}-peer-gateway.${ORG}.localho.st:443
( pushd ../full-stack-asset-transfer-guide/applications/trader-typescript \
&& npm install
&& npm start getAllAssets
&& npm start create banana bananaman yellow
&& npm start getAllAssets )

View file

@ -19,7 +19,6 @@
"author": "Hyperledger", "author": "Hyperledger",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@grpc/grpc-js": "~1.6.7",
"@hyperledger/fabric-gateway": "^1.1.0", "@hyperledger/fabric-gateway": "^1.1.0",
"@hyperledger/fabric-protos": "^0.1.0-dev.2300102001.1" "@hyperledger/fabric-protos": "^0.1.0-dev.2300102001.1"
}, },

View file

@ -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.

View file

@ -0,0 +1,197 @@
# 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/fabric-samples.git
cd test-network-k8s-operator
```
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
pushd ../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
```

View file

@ -0,0 +1,3 @@
organizations/
mychannel_genesis_block.pb
mychannel_genesis_block.json

View file

@ -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`
-

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -0,0 +1 @@
ca-issuer-secret.yaml

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,7 @@
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: root-tls-cert-issuer
spec:
selfSigned: {}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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:
- '*'

View file

@ -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

View file

@ -0,0 +1,3 @@
enrollments/
chaincode/

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: ConfigMap
metadata:
name: local-registry-hosting
namespace: kube-public
data:
localRegistryHosting.v1: |
host: "localhost:${CONTAINER_REGISTRY_PORT}"
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF
}
kind_with_nginx

View file

@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail
. scripts/utils.sh
# Create the namespace, ignoring an error if it previously was created.
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: ${NAMESPACE}
EOF
print "Launching ${NAMESPACE} fabric-operator"
# Substitute just/env variables into the kustomization before applying to k8s
kubectl kustomize kind/operator | envsubst | kubectl -n ${NAMESPACE} apply -f -
kubectl -n ${NAMESPACE} rollout status deploy fabric-operator

View file

@ -0,0 +1,158 @@
#!/bin/bash
function print() {
GREEN='\033[0;32m'
NC='\033[0m'
echo
echo -e "${GREEN}${1}${NC}"
}
SUCCESS="✅"
WARN="⚠️ "
# tests if varname is defined in the env AND it's an existing directory
function must_declare() {
local varname=$1
if [[ ${!varname+x} ]]
then
printf "\r%s %-30s%s\n" $SUCCESS $varname ${!varname}
else
printf "\r%s %-30s %s\n" $WARN $varname
EXIT=1
fi
}
function check() {
local name=$1
local message=$2
printf "🤔 %s" $name
if $name &>/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
}