Run E2E / CI test suite against the Ingress based k8s test network

Signed-off-by: Josh Kneubuhl <jkneubuh@us.ibm.com>
This commit is contained in:
Josh Kneubuhl 2022-03-29 11:36:51 -04:00
parent aeed596ec5
commit 9df4cdde93
9 changed files with 138 additions and 361 deletions

View file

@ -28,12 +28,12 @@ export GATEWAY_CLIENT_APPLICATION_PATH=${GATEWAY_CLIENT_APPLICATION_PATH:-../ass
export CHANNEL_NAME=${TEST_NETWORK_CHANNEL_NAME:-mychannel} export CHANNEL_NAME=${TEST_NETWORK_CHANNEL_NAME:-mychannel}
export CHAINCODE_NAME=${TEST_NETWORK_CHAINCODE_NAME:-asset-transfer-basic} export CHAINCODE_NAME=${TEST_NETWORK_CHAINCODE_NAME:-asset-transfer-basic}
export MSP_ID=${MSP_ID:-Org1MSP} export MSP_ID=${MSP_ID:-Org1MSP}
export CRYPTO_PATH=${CRYPTO_PATH:-../../test-network-k8s/build/organizations/peerOrganizations/org1.example.com} export CRYPTO_PATH=${CRYPTO_PATH:-../../test-network-k8s/build/channel-msp/peerOrganizations/org1}
export KEY_DIRECTORY_PATH=${KEY_DIRECTORY_PATH:-../../test-network-k8s/build/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore} export KEY_DIRECTORY_PATH=${KEY_DIRECTORY_PATH:-../../test-network-k8s/build/enrollments/org1/users/org1admin/msp/keystore}
export CERT_PATH=${CERT_PATH:-../../test-network-k8s/build/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/cert.pem} export CERT_PATH=${CERT_PATH:-../../test-network-k8s/build/enrollments/org1/users/org1admin/msp/signcerts/cert.pem}
export TLS_CERT_PATH=${TLS_CERT_PATH:-../../test-network-k8s/build/organizations/peerOrganizations/org1.example.com/msp/tlscacerts/org1-tls-ca.pem} export TLS_CERT_PATH=${TLS_CERT_PATH:-../../test-network-k8s/build/channel-msp/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem}
export PEER_ENDPOINT=${PEER_ENDPOINT:-localhost:7051} export PEER_ENDPOINT=${PEER_ENDPOINT:-org1-peer1.vcap.me:443}
export PEER_HOST_ALIAS=${PEER_HOST_ALIAS:-org1-peer1} export PEER_HOST_ALIAS=${PEER_HOST_ALIAS:-org1-peer1.vcap.me}
function print() { function print() {
GREEN='\033[0;32m' GREEN='\033[0;32m'
@ -80,29 +80,13 @@ function createNetwork() {
./network up ./network up
./network channel create ./network channel create
print "Opening gateway port-forward to 'localhost:7051'"
kubectl -n test-network port-forward svc/org1-peer1 7051:7051 &
print "Deploying chaincode" print "Deploying chaincode"
./network chaincode deploy ./network chaincode deploy
print "Extracting certificates"
kubectl \
-n test-network \
exec deploy/org1-peer1 \
-c main \
-- tar zcf - -C /var/hyperledger/fabric organizations/peerOrganizations/org1.example.com \
| tar zxvf - -C ../test-network-k8s/build/
} }
function stopNetwork() { function stopNetwork() {
pkill -f "port-forward"
print "Stopping network" print "Stopping network"
./network down ./network down
print "Cleaning client certificates"
rm -rf ../test-network-k8s/build/
} }
# Set up the suite with a KIND cluster # Set up the suite with a KIND cluster
@ -122,8 +106,7 @@ print "Running rest-easy test"
( ./network rest-easy \ ( ./network rest-easy \
&& sleep 5 \ && sleep 5 \
&& export SAMPLE_APIKEY='97834158-3224-4CE7-95F9-A148C886653E' \ && export SAMPLE_APIKEY='97834158-3224-4CE7-95F9-A148C886653E' \
&& curl -s --header "X-Api-Key: ${SAMPLE_APIKEY}" "http://localhost/api/assets/asset1" | jq \ && curl -s --header "X-Api-Key: ${SAMPLE_APIKEY}" "http://fabric-rest-sample.vcap.me/api/assets/asset1" | jq )
&& curl -s --insecure --header "X-Api-Key: ${SAMPLE_APIKEY}" "https://localhost/api/assets/asset1" | jq )
print "OK" print "OK"
stopNetwork stopNetwork

View file

@ -236,23 +236,26 @@ spec:
selector: selector:
app: fabric-rest-sample app: fabric-rest-sample
--- ---
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
metadata: metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-connect-timeout: 60s
labels:
app: fabric-rest-sample
name: fabric-rest-sample name: fabric-rest-sample
# annotations:
# nginx.ingress.kubernetes.io/rewrite-target: /$1
spec: spec:
ingressClassName: nginx
rules: rules:
- http: - host: fabric-rest-sample.${DOMAIN}
http:
paths: paths:
# - path: "/fabric-rest-sample/(.*)" - backend:
- path: "/"
pathType: Prefix
backend:
service: service:
name: fabric-rest-sample name: fabric-rest-sample
port: port:
number: 3000 name: http
path: /
pathType: ImplementationSpecific

View file

@ -6,19 +6,13 @@
# #
set -o errexit set -o errexit
# todo: better handling for input parameters. # todo: better handling for input parameters. Argbash?
# todo: skip storage volume init if deploying to a remote / cloud cluster (ICP IKS ROKS etc...) # todo: skip storage volume init if deploying to a remote / cloud cluster (ICP IKS ROKS etc...)
# todo: for logging, set up a stack and allow multi-line status output codes # todo: for logging, set up a stack and allow multi-line status output codes
# todo: refactor - lots of for-org-in-0-to-2-...
# todo: find a better technique for passing input commands to a remote kube exec
# todo: register tls csr.hosts w/ kube DNS domain .NS.svc.cluster.local
# todo: user:pass auth for tls and ecert bootstrap admins. here and in the server-config.yaml # todo: user:pass auth for tls and ecert bootstrap admins. here and in the server-config.yaml
# todo: set tls.certfiles= ... arg in deployment env / yaml
# todo: refactor chaincode install to support other chaincode routines # todo: refactor chaincode install to support other chaincode routines
# todo: consider using templates for boilerplate network nodes (orderers, peers, ...)
# todo: allow the user to specify the chaincode name (hardcoded as 'basic') both in install and invoke/query # todo: allow the user to specify the chaincode name (hardcoded as 'basic') both in install and invoke/query
# todo: track down a nasty bug whereby the CA service endpoints (kube services) will occasionally reject TCP connections after network down/up. This is patched by introducing a 10s sleep after the deployments are up... # todo: track down a nasty bug whereby the CA service endpoints (kube services) will occasionally reject TCP connections after network down/up. This is patched by introducing a 10s sleep after the deployments are up...
# todo: refactor query/invoke to specify chaincode name (-n param)
export CONTAINER_CLI=${CONTAINER_CLI:-docker} export CONTAINER_CLI=${CONTAINER_CLI:-docker}
export FABRIC_VERSION=${TEST_NETWORK_FABRIC_VERSION:-2.4.3} export FABRIC_VERSION=${TEST_NETWORK_FABRIC_VERSION:-2.4.3}
@ -75,8 +69,6 @@ function print_help() {
log "Debug log file \t\t: ${DEBUG_FILE}" log "Debug log file \t\t: ${DEBUG_FILE}"
log log
echo todo: help output, parse mode, flags, env, etc. echo todo: help output, parse mode, flags, env, etc.
} }

View file

@ -22,37 +22,23 @@ function package_chaincode_for() {
pop_fn pop_fn
} }
# Copy the chaincode archive from the local host to the org admin
function transfer_chaincode_archive_for() {
local org=$1
local cc_archive="build/chaincode/${CHAINCODE_NAME}.tgz"
push_fn "Transferring chaincode archive to ${org}"
# Like kubectl cp, but targeted to a deployment rather than an individual pod.
tar cf - ${cc_archive} | kubectl -n $NS exec -i deploy/${org}-admin-cli -c main -- tar xvf -
pop_fn
}
function install_chaincode_for() { function install_chaincode_for() {
local org=$1 local org=$1
local peer=$2 local peer=$2
push_fn "Installing chaincode for org ${org} peer ${peer}" push_fn "Installing chaincode for org ${org} peer ${peer}"
# Install the chaincode export_peer_context $org $peer
echo 'set -x
export CORE_PEER_ADDRESS='${org}'-'${peer}':7051 peer lifecycle chaincode install build/chaincode/${CHAINCODE_NAME}.tgz
peer lifecycle chaincode install build/chaincode/'${CHAINCODE_NAME}'.tgz
' | exec kubectl -n $NS exec deploy/${org}-admin-cli -c main -i -- /bin/bash
pop_fn pop_fn
} }
function launch_chaincode_service() { function launch_chaincode_service() {
local org=$1 local org=$1
local cc_id=$2 local peer=$2
local cc_image=$3 local cc_id=$3
local peer=$4 local cc_image=$4
push_fn "Launching chaincode container \"${cc_image}\"" push_fn "Launching chaincode container \"${cc_image}\""
# The chaincode endpoint needs to have the generated chaincode ID available in the environment. # The chaincode endpoint needs to have the generated chaincode ID available in the environment.
@ -72,76 +58,72 @@ function launch_chaincode_service() {
function activate_chaincode_for() { function activate_chaincode_for() {
local org=$1 local org=$1
local cc_id=$2 local peer=$2
push_fn "Activating chaincode ${CHAINCODE_ID}" local cc_id=$3
push_fn "Activating $org chaincode ${CHAINCODE_ID}"
export_peer_context $org $peer
echo 'set -x
export CORE_PEER_ADDRESS='${org}'-peer1:7051
peer lifecycle \ peer lifecycle \
chaincode approveformyorg \ chaincode approveformyorg \
--channelID '${CHANNEL_NAME}' \ --channelID ${CHANNEL_NAME} \
--name '${CHAINCODE_NAME}' \ --name ${CHAINCODE_NAME} \
--version 1 \ --version 1 \
--package-id '${cc_id}' \ --package-id ${cc_id} \
--sequence 1 \ --sequence 1 \
-o org0-orderer1:6050 \ --orderer org0-orderer1.${DOMAIN}:443 \
--tls --cafile /var/hyperledger/fabric/organizations/ordererOrganizations/org0.example.com/msp/tlscacerts/org0-tls-ca.pem --tls --cafile ${TEMP_DIR}/channel-msp/ordererOrganizations/org0/orderers/org0-orderer1/tls/signcerts/tls-cert.pem
peer lifecycle \ peer lifecycle \
chaincode commit \ chaincode commit \
--channelID '${CHANNEL_NAME}' \ --channelID ${CHANNEL_NAME} \
--name '${CHAINCODE_NAME}' \ --name ${CHAINCODE_NAME} \
--version 1 \ --version 1 \
--sequence 1 \ --sequence 1 \
-o org0-orderer1:6050 \ --orderer org0-orderer1.${DOMAIN}:443 \
--tls --cafile /var/hyperledger/fabric/organizations/ordererOrganizations/org0.example.com/msp/tlscacerts/org0-tls-ca.pem --tls --cafile ${TEMP_DIR}/channel-msp/ordererOrganizations/org0/orderers/org0-orderer1/tls/signcerts/tls-cert.pem
' | exec kubectl -n $NS exec deploy/${org}-admin-cli -c main -i -- /bin/bash
pop_fn pop_fn
} }
function query_chaincode() { function query_chaincode() {
set -x set -x
# todo: mangle additional $@ parameters with bash escape quotations
echo ' export_peer_context org1 peer1
export CORE_PEER_ADDRESS=org1-peer1:7051
peer chaincode query -n '${CHAINCODE_NAME}' -C '${CHANNEL_NAME}' -c '"'$@'"' peer chaincode query \
' | exec kubectl -n $NS exec deploy/org1-admin-cli -c main -i -- /bin/bash -n $CHAINCODE_NAME \
-C $CHANNEL_NAME \
-c $@
} }
function query_chaincode_metadata() { function query_chaincode_metadata() {
set -x set -x
local args='{"Args":["org.hyperledger.fabric:GetMetadata"]}' local args='{"Args":["org.hyperledger.fabric:GetMetadata"]}'
# todo: mangle additional $@ parameters with bash escape quotations
log ''
log 'Org1-Peer1:' log 'Org1-Peer1:'
echo ' export_peer_context org1 peer1
export CORE_PEER_ADDRESS=org1-peer1:7051 peer chaincode query -n $CHAINCODE_NAME -C $CHANNEL_NAME -c $args
peer chaincode query -n '${CHAINCODE_NAME}' -C '${CHANNEL_NAME}' -c '"'$args'"'
' | exec kubectl -n $NS exec deploy/org1-admin-cli -c main -i -- /bin/bash
log '' log ''
log 'Org1-Peer2:' log 'Org1-Peer2:'
echo ' export_peer_context org1 peer2
export CORE_PEER_ADDRESS=org1-peer2:7051 peer chaincode query -n $CHAINCODE_NAME -C $CHANNEL_NAME -c $args
peer chaincode query -n '${CHAINCODE_NAME}' -C '${CHANNEL_NAME}' -c '"'$args'"'
' | exec kubectl -n $NS exec deploy/org1-admin-cli -c main -i -- /bin/bash
} }
function invoke_chaincode() { function invoke_chaincode() {
# set -x # set -x
# todo: mangle additional $@ parameters with bash escape quotations # todo: mangle additional $@ parameters with bash escape quotations
echo '
export CORE_PEER_ADDRESS=org1-peer1:7051 export_peer_context org1 peer1
peer chaincode \
invoke \ peer chaincode invoke \
-o org0-orderer1:6050 \ -n $CHAINCODE_NAME \
--tls --cafile /var/hyperledger/fabric/organizations/ordererOrganizations/org0.example.com/msp/tlscacerts/org0-tls-ca.pem \ -C $CHANNEL_NAME \
-n '${CHAINCODE_NAME}' \ -c $@ \
-C '${CHANNEL_NAME}' \ --orderer org0-orderer1.${DOMAIN}:443 \
-c '"'$@'"' --tls --cafile ${TEMP_DIR}/channel-msp/ordererOrganizations/org0/orderers/org0-orderer1/tls/signcerts/tls-cert.pem
' | exec kubectl -n $NS exec deploy/org1-admin-cli -c main -i -- /bin/bash
sleep 2 sleep 2
} }
@ -162,7 +144,7 @@ function install_chaincode() {
local org=org1 local org=org1
package_chaincode_for ${org} package_chaincode_for ${org}
transfer_chaincode_archive_for ${org}
install_chaincode_for ${org} peer1 install_chaincode_for ${org} peer1
install_chaincode_for ${org} peer2 install_chaincode_for ${org} peer2
@ -174,7 +156,11 @@ function activate_chaincode() {
set -x set -x
set_chaincode_id set_chaincode_id
activate_chaincode_for org1 $CHAINCODE_ID activate_chaincode_for org1 peer1 $CHAINCODE_ID
# jdk: does activation on a single peer apply to all peers in the org? This is an error:
# activate_chaincode_for org1 peer1 $CHAINCODE_ID
} }
# Install, launch, and activate the chaincode # Install, launch, and activate the chaincode
@ -182,8 +168,8 @@ function deploy_chaincode() {
set -x set -x
install_chaincode install_chaincode
launch_chaincode_service org1 $CHAINCODE_ID $CHAINCODE_IMAGE peer1 launch_chaincode_service org1 peer1 $CHAINCODE_ID $CHAINCODE_IMAGE
launch_chaincode_service org1 $CHAINCODE_ID $CHAINCODE_IMAGE peer2 launch_chaincode_service org1 peer2 $CHAINCODE_ID $CHAINCODE_IMAGE
activate_chaincode activate_chaincode
} }

View file

@ -45,12 +45,12 @@ function register_org_admin() {
export FABRIC_CA_CLIENT_TLS_CERTFILES=/var/hyperledger/fabric/config/tls/ca.crt export FABRIC_CA_CLIENT_TLS_CERTFILES=/var/hyperledger/fabric/config/tls/ca.crt
fabric-ca-client register \ fabric-ca-client register \
--id.name ${id_name} \ --id.name ${id_name} \
--id.secret ${id_secret} \ --id.secret ${id_secret} \
--id.type ${type} \ --id.type ${type} \
--url https://${ca_name} \ --url https://${ca_name} \
--mspdir /var/hyperledger/fabric-ca-client/${ca_name}/rcaadmin/msp \ --mspdir /var/hyperledger/fabric-ca-client/${ca_name}/rcaadmin/msp \
--id.attrs "hf.Registrar.Roles=client,hf.Registrar.Attributes=*,hf.Revoker=true,hf.GenCRL=true,admin=true:ecert,abac.init=true:ecert" --id.attrs "hf.Registrar.Roles=client,hf.Registrar.Attributes=*,hf.Revoker=true,hf.GenCRL=true,admin=true:ecert,abac.init=true:ecert"
EOF EOF
} }
@ -104,7 +104,6 @@ function enroll_org_admin() {
--url ${CA_URL} \ --url ${CA_URL} \
--tls.certfiles ${CA_DIR}/tls-cert.pem --tls.certfiles ${CA_DIR}/tls-cert.pem
# Construct an msp config.yaml # Construct an msp config.yaml
CA_CERT_NAME=${CA_NAME}-$(echo $DOMAIN | tr -s . -)-${CA_PORT}.pem CA_CERT_NAME=${CA_NAME}-$(echo $DOMAIN | tr -s . -)-${CA_PORT}.pem
@ -204,9 +203,9 @@ function create_genesis_block() {
FABRIC_CFG_PATH=${PWD}/config/org0 \ FABRIC_CFG_PATH=${PWD}/config/org0 \
configtxgen \ configtxgen \
-profile TwoOrgsApplicationGenesis \ -profile TwoOrgsApplicationGenesis \
-channelID $CHANNEL_NAME \ -channelID $CHANNEL_NAME \
-outputBlock ${TEMP_DIR}/genesis_block.pb -outputBlock ${TEMP_DIR}/genesis_block.pb
# configtxgen -inspectBlock ${TEMP_DIR}/genesis_block.pb # configtxgen -inspectBlock ${TEMP_DIR}/genesis_block.pb
@ -235,11 +234,11 @@ function join_channel_orderer() {
# of identity than the Docker Compose network, which transmits the orderer node's TLS key pair directly # of identity than the Docker Compose network, which transmits the orderer node's TLS key pair directly
osnadmin channel join \ osnadmin channel join \
--orderer-address ${org}-${orderer}-admin.${DOMAIN} \ --orderer-address ${org}-${orderer}-admin.${DOMAIN} \
--ca-file ${TEMP_DIR}/channel-msp/ordererOrganizations/${org}/orderers/${org}-${orderer}/tls/signcerts/tls-cert.pem \ --ca-file ${TEMP_DIR}/channel-msp/ordererOrganizations/${org}/orderers/${org}-${orderer}/tls/signcerts/tls-cert.pem \
--client-cert ${TEMP_DIR}/enrollments/${org}/users/${org}admin/msp/signcerts/cert.pem \ --client-cert ${TEMP_DIR}/enrollments/${org}/users/${org}admin/msp/signcerts/cert.pem \
--client-key ${TEMP_DIR}/enrollments/${org}/users/${org}admin/msp/keystore/key.pem \ --client-key ${TEMP_DIR}/enrollments/${org}/users/${org}admin/msp/keystore/key.pem \
--channelID ${CHANNEL_NAME} \ --channelID ${CHANNEL_NAME} \
--config-block ${TEMP_DIR}/genesis_block.pb --config-block ${TEMP_DIR}/genesis_block.pb
} }
function join_channel_peers() { function join_channel_peers() {
@ -251,8 +250,6 @@ function join_org_peers() {
local org=$1 local org=$1
push_fn "Joining ${org} peers to channel ${CHANNEL_NAME}" push_fn "Joining ${org} peers to channel ${CHANNEL_NAME}"
# fetch the genesis block from an orderer. (do we need to do this? It's available locally...)
# Join peers to channel # Join peers to channel
join_channel_peer $org peer1 join_channel_peer $org peer1
join_channel_peer $org peer2 join_channel_peer $org peer2
@ -264,13 +261,11 @@ function join_channel_peer() {
local org=$1 local org=$1
local peer=$2 local peer=$2
FABRIC_CFG_PATH=${PWD}/config/${org} \ export_peer_context $org $peer
CORE_PEER_ADDRESS=${org}-${peer}.${DOMAIN}:443 \
CORE_PEER_MSPCONFIGPATH=${TEMP_DIR}/enrollments/${org}/users/${org}admin/msp \ peer channel join \
CORE_PEER_TLS_ROOTCERT_FILE=${TEMP_DIR}/channel-msp/peerOrganizations/${org}/msp/tlscacerts/tlsca-signcert.pem \ --blockpath ${TEMP_DIR}/genesis_block.pb \
peer channel join \ --orderer org0-orderer1.${DOMAIN} \
--blockpath ${TEMP_DIR}/genesis_block.pb \ --tls \
--orderer org0-orderer1.${DOMAIN} \ --cafile ${TEMP_DIR}/channel-msp/ordererOrganizations/org0/orderers/org0-orderer1/tls/signcerts/tls-cert.pem
--tls \
--cafile ${TEMP_DIR}/channel-msp/ordererOrganizations/org0/orderers/org0-orderer1/tls/signcerts/tls-cert.pem
} }

View file

@ -17,7 +17,7 @@ function launch_ECert_CAs() {
kubectl -n $NS rollout status deploy/org2-ca kubectl -n $NS rollout status deploy/org2-ca
# todo: this papers over a nasty bug whereby the CAs are ready, but sporadically refuse connections after a down / up # todo: this papers over a nasty bug whereby the CAs are ready, but sporadically refuse connections after a down / up
# sleep 10 sleep 5
pop_fn pop_fn
} }

View file

@ -1,186 +0,0 @@
#!/bin/bash
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
function create_channel_org_MSP() {
local org=$1
local org_type=$2
local ecert_ca=${org}-ca
echo 'set -x
mkdir -p /var/hyperledger/fabric/organizations/'${org_type}'Organizations/'${org}'.example.com/msp/cacerts
cp \
$FABRIC_CA_CLIENT_HOME/'${ecert_ca}'/rcaadmin/msp/cacerts/'${ecert_ca}'.pem \
/var/hyperledger/fabric/organizations/'${org_type}'Organizations/'${org}'.example.com/msp/cacerts
mkdir -p /var/hyperledger/fabric/organizations/'${org_type}'Organizations/'${org}'.example.com/msp/tlscacerts
cp \
/var/hyperledger/fabric/config/tls/ca.crt \
/var/hyperledger/fabric/organizations/'${org_type}'Organizations/'${org}'.example.com/msp/tlscacerts/'${org}'-tls-ca.pem
echo "NodeOUs:
Enable: true
ClientOUIdentifier:
Certificate: cacerts/'${ecert_ca}'.pem
OrganizationalUnitIdentifier: client
PeerOUIdentifier:
Certificate: cacerts/'${ecert_ca}'.pem
OrganizationalUnitIdentifier: peer
AdminOUIdentifier:
Certificate: cacerts/'${ecert_ca}'.pem
OrganizationalUnitIdentifier: admin
OrdererOUIdentifier:
Certificate: cacerts/'${ecert_ca}'.pem
OrganizationalUnitIdentifier: orderer "> /var/hyperledger/fabric/organizations/'${org_type}'Organizations/'${org}'.example.com/msp/config.yaml
' | exec kubectl -n $NS exec deploy/${ecert_ca} -i -- /bin/sh
}
function create_channel_MSP() {
push_fn "Creating channel MSP"
create_channel_org_MSP org0 orderer
create_channel_org_MSP org1 peer
create_channel_org_MSP org2 peer
pop_fn
}
function aggregate_channel_MSP() {
push_fn "Aggregating channel MSP"
rm -rf ./build/msp/
mkdir -p ./build/msp
kubectl -n $NS exec deploy/org0-ca -- tar zcvf - -C /var/hyperledger/fabric organizations/ordererOrganizations/org0.example.com/msp > build/msp/msp-org0.example.com.tgz
kubectl -n $NS exec deploy/org1-ca -- tar zcvf - -C /var/hyperledger/fabric organizations/peerOrganizations/org1.example.com/msp > build/msp/msp-org1.example.com.tgz
kubectl -n $NS exec deploy/org2-ca -- tar zcvf - -C /var/hyperledger/fabric organizations/peerOrganizations/org2.example.com/msp > build/msp/msp-org2.example.com.tgz
kubectl -n $NS delete configmap msp-config || true
kubectl -n $NS create configmap msp-config --from-file=build/msp/
pop_fn
}
function create_genesis_block() {
push_fn "Creating channel \"${CHANNEL_NAME}\""
echo 'set -x
configtxgen -profile TwoOrgsApplicationGenesis -channelID '${CHANNEL_NAME}' -outputBlock genesis_block.pb
# configtxgen -inspectBlock genesis_block.pb
osnadmin channel join --orderer-address org0-orderer1:9443 --channelID '${CHANNEL_NAME}' --config-block genesis_block.pb
osnadmin channel join --orderer-address org0-orderer2:9443 --channelID '${CHANNEL_NAME}' --config-block genesis_block.pb
osnadmin channel join --orderer-address org0-orderer3:9443 --channelID '${CHANNEL_NAME}' --config-block genesis_block.pb
' | exec kubectl -n $NS exec deploy/org0-admin-cli -i -- /bin/bash
# todo: readiness / liveiness equivalent for channel ? Needs a little bit to settle before peers can join.
sleep 10
pop_fn
}
function join_org_peers() {
local org=$1
push_fn "Joining ${org} peers to channel \"${CHANNEL_NAME}\""
echo 'set -x
# Fetch the genesis block from an orderer
peer channel \
fetch oldest \
genesis_block.pb \
-c '${CHANNEL_NAME}' \
-o org0-orderer1:6050 \
--tls --cafile /var/hyperledger/fabric/organizations/ordererOrganizations/org0.example.com/msp/tlscacerts/org0-tls-ca.pem
# Join peer1 to the channel.
CORE_PEER_ADDRESS='${org}'-peer1:7051 \
peer channel \
join \
-b genesis_block.pb \
-o org0-orderer1:6050 \
--tls --cafile /var/hyperledger/fabric/organizations/ordererOrganizations/org0.example.com/msp/tlscacerts/org0-tls-ca.pem
# Join peer2 to the channel.
CORE_PEER_ADDRESS='${org}'-peer2:7051 \
peer channel \
join \
-b genesis_block.pb \
-o org0-orderer1:6050 \
--tls --cafile /var/hyperledger/fabric/organizations/ordererOrganizations/org0.example.com/msp/tlscacerts/org0-tls-ca.pem
' | exec kubectl -n $NS exec deploy/${org}-admin-cli -i -- /bin/bash
pop_fn
}
function join_peers() {
join_org_peers org1
join_org_peers org2
}
# Copy the scripts/anchor_peers.sh to a remote volume
function push_anchor_peer_script() {
local org=$1
tar cf - scripts/ | kubectl -n $NS exec -i -c main deploy/${org}-admin-cli -- tar xf - -C /var/hyperledger/fabric
}
verify_result() {
if [ $1 -ne 0 ]; then
echo $2
exit $1
fi
}
# Launch the anchor peer update script on a remote org admin CLI
function invoke_anchor_peer_update() {
local org_num=$1
local peer_name=$2
kubectl exec \
-n $NS \
-c main \
deploy/org${org_num}-admin-cli \
-i \
/bin/bash -c "/var/hyperledger/fabric/scripts/set_anchor_peer.sh ${org_num} ${CHANNEL_NAME} ${peer_name}"
verify_result $? "Error updating anchor peer for org ${org_num}"
}
#
# To update the anchor peers we will need to execute a script on each of the peer admin CLI containers. These
# commands can be individually piped into kubectl exec ... but it will be simpler if we transfer the anchor
# peer update script over to the org volume and then trigger it from kubectl.
#
function update_anchor_peers() {
local peer_name=$1
push_fn "Updating anchor peers to ${peer_name}"
push_anchor_peer_script org1
push_anchor_peer_script org2
invoke_anchor_peer_update 1 ${peer_name}
invoke_anchor_peer_update 2 ${peer_name}
pop_fn
}
function channel_up() {
create_channel_MSP
aggregate_channel_MSP
create_genesis_block
join_peers
# peer1 was set as the anchor peer in configtx.yaml. Setting this again will force an
# error to be returned from the channel up. We might want to render the warning in
# this case to indicate that the call was made but had a nonzero exit.
# update_anchor_peers peer1
}

View file

@ -5,16 +5,8 @@
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
function extract_MSP_archives() { # This magical awk script led to 30 hours of debugging a "TLS handshake error"
mkdir -p build/msp # moral: do not edit / alter the number of '\' in the following transform:
kubectl -n $NS exec deploy/org1-ca -- tar zcf - -C /var/hyperledger/fabric organizations/peerOrganizations/org1.example.com/msp | tar zxf - -C build/msp
kubectl -n $NS exec deploy/org2-ca -- tar zcf - -C /var/hyperledger/fabric organizations/peerOrganizations/org2.example.com/msp | tar zxf - -C build/msp
kubectl -n $NS exec deploy/org1-ca -- tar zcf - -C /var/hyperledger/fabric organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp | tar zxf - -C build/msp
kubectl -n $NS exec deploy/org2-ca -- tar zcf - -C /var/hyperledger/fabric organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp | tar zxf - -C build/msp
}
function one_line_pem { function one_line_pem {
echo "`awk 'NF {sub(/\\n/, ""); printf "%s\\\\\\\n",$0;}' $1`" echo "`awk 'NF {sub(/\\n/, ""); printf "%s\\\\\\\n",$0;}' $1`"
} }
@ -32,41 +24,32 @@ function json_ccp {
function construct_rest_sample_configmap() { function construct_rest_sample_configmap() {
push_fn "Constructing fabric-rest-sample connection profiles" push_fn "Constructing fabric-rest-sample connection profiles"
extract_MSP_archives ENROLLMENT_DIR=${TEMP_DIR}/enrollments
CHANNEL_MSP_DIR=${TEMP_DIR}/channel-msp
CONFIG_DIR=${TEMP_DIR}/fabric-rest-sample-config
mkdir -p build/fabric-rest-sample-config mkdir -p $CONFIG_DIR
local peer_pem=build/msp/organizations/peerOrganizations/org1.example.com/msp/tlscacerts/org1-tls-ca.pem
local ca_pem=build/msp/organizations/peerOrganizations/org1.example.com/msp/cacerts/org1-ca.pem
local peer_pem=$CHANNEL_MSP_DIR/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem
local ca_pem=$CHANNEL_MSP_DIR/peerOrganizations/org1/msp/cacerts/ca-signcert.pem
echo "$(json_ccp 1 $peer_pem $ca_pem)" > build/fabric-rest-sample-config/HLF_CONNECTION_PROFILE_ORG1 echo "$(json_ccp 1 $peer_pem $ca_pem)" > build/fabric-rest-sample-config/HLF_CONNECTION_PROFILE_ORG1
peer_pem=build/msp/organizations/peerOrganizations/org2.example.com/msp/tlscacerts/org2-tls-ca.pem
ca_pem=build/msp/organizations/peerOrganizations/org2.example.com/msp/cacerts/org2-ca.pem
peer_pem=$CHANNEL_MSP_DIR/peerOrganizations/org2/msp/tlscacerts/tlsca-signcert.pem
ca_pem=$CHANNEL_MSP_DIR/peerOrganizations/org2/msp/cacerts/ca-signcert.pem
echo "$(json_ccp 2 $peer_pem $ca_pem)" > build/fabric-rest-sample-config/HLF_CONNECTION_PROFILE_ORG2 echo "$(json_ccp 2 $peer_pem $ca_pem)" > build/fabric-rest-sample-config/HLF_CONNECTION_PROFILE_ORG2
cat build/msp/organizations/peerOrganizations/org1.example.com/users/Admin\@org1.example.com/msp/signcerts/cert.pem > build/fabric-rest-sample-config/HLF_CERTIFICATE_ORG1
cat build/msp/organizations/peerOrganizations/org2.example.com/users/Admin\@org2.example.com/msp/signcerts/cert.pem > build/fabric-rest-sample-config/HLF_CERTIFICATE_ORG2
cat build/msp/organizations/peerOrganizations/org1.example.com/users/Admin\@org1.example.com/msp/keystore/server.key > build/fabric-rest-sample-config/HLF_PRIVATE_KEY_ORG1 cp $ENROLLMENT_DIR/org1/users/org1admin/msp/signcerts/cert.pem $CONFIG_DIR/HLF_CERTIFICATE_ORG1
cat build/msp/organizations/peerOrganizations/org2.example.com/users/Admin\@org2.example.com/msp/keystore/server.key > build/fabric-rest-sample-config/HLF_PRIVATE_KEY_ORG2 cp $ENROLLMENT_DIR/org2/users/org2admin/msp/signcerts/cert.pem $CONFIG_DIR/HLF_CERTIFICATE_ORG2
cp $ENROLLMENT_DIR/org1/users/org1admin/msp/keystore/key.pem $CONFIG_DIR/HLF_PRIVATE_KEY_ORG1
cp $ENROLLMENT_DIR/org2/users/org2admin/msp/keystore/key.pem $CONFIG_DIR/HLF_PRIVATE_KEY_ORG2
kubectl -n $NS delete configmap fabric-rest-sample-config || true kubectl -n $NS delete configmap fabric-rest-sample-config || true
kubectl -n $NS create configmap fabric-rest-sample-config --from-file=build/fabric-rest-sample-config/ kubectl -n $NS create configmap fabric-rest-sample-config --from-file=$CONFIG_DIR
pop_fn pop_fn
} }
# todo: Make sure to port this to IKS / ICP
function ensure_rest_sample_image() {
push_fn "Ensuring fabric-rest-sample image"
# todo: apply a tag / label to avoid pulling :latest from ghcr.io
pop_fn 0
}
function rollout_rest_sample() { function rollout_rest_sample() {
push_fn "Starting fabric-rest-sample" push_fn "Starting fabric-rest-sample"
@ -77,15 +60,19 @@ function rollout_rest_sample() {
} }
function launch_rest_sample() { function launch_rest_sample() {
ensure_rest_sample_image
construct_rest_sample_configmap construct_rest_sample_configmap
rollout_rest_sample
apply_template kube/fabric-rest-sample.yaml
kubectl -n $NS rollout status deploy/fabric-rest-sample
log "" log ""
log "The fabric-rest-sample has started. See https://github.com/hyperledger/fabric-samples/tree/main/asset-transfer-basic/rest-api-typescript for additional usage." log "The fabric-rest-sample has started."
log "See https://github.com/hyperledger/fabric-samples/tree/main/asset-transfer-basic/rest-api-typescript for additional usage details."
log "To access the endpoint:" log "To access the endpoint:"
log "" log ""
log "export SAMPLE_APIKEY=97834158-3224-4CE7-95F9-A148C886653E" log "export SAMPLE_APIKEY=97834158-3224-4CE7-95F9-A148C886653E"
log 'curl -s --header "X-Api-Key: ${SAMPLE_APIKEY}" http://localhost/api/assets' log 'curl -s --header "X-Api-Key: ${SAMPLE_APIKEY}" http://fabric-rest-sample.'${DOMAIN}'/api/assets'
log "" log ""
} }

View file

@ -84,3 +84,20 @@ function apply_template() {
cat $1 | envsubst | kubectl -n $NS apply -f - cat $1 | envsubst | kubectl -n $NS apply -f -
} }
# Set the calling context to refer the peer binary to the correct org / peer instance
#
# todo: Expose the output of this function to a target that prints the context to STDOUT.
#
# e.g.:
# bash $ source $(network set-peer-context org1 peer2)
# bash $ peer chaincode list
# bash $ ...
function export_peer_context() {
local org=$1
local peer=$2
export FABRIC_CFG_PATH=${PWD}/config/${org}
export CORE_PEER_ADDRESS=${org}-${peer}.${DOMAIN}:443
export CORE_PEER_MSPCONFIGPATH=${TEMP_DIR}/enrollments/${org}/users/${org}admin/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${TEMP_DIR}/channel-msp/peerOrganizations/${org}/msp/tlscacerts/tlsca-signcert.pem
}