fabric-samples/full-stack-asset-transfer-guide/infrastructure/sample-network/scripts/channel.sh
Aadithyan Raju b82a309d91
NixOS support (Multi-Linux Distro Support) (#1310)
Signed-off-by: AadithyanRaju <aadithyan75@gmail.com>
Signed-off-by: Aadithyan Raju <93834376+AadithyanRaju@users.noreply.github.com>
2025-03-24 19:15:58 +00:00

269 lines
8 KiB
Bash

#!/usr/bin/env bash
#
# 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.
#
# todo: Refuse to overwrite an existing admin enrollment ?
function channel_up() {
set -x
enroll_org_admins
create_channel_msp
create_genesis_block
join_channel_orderers
join_channel_peers
}
# create an enrollment MSP config.yaml
function create_msp_config_yaml() {
local ca_name=$1
local ca_cert_name=$2
local msp_dir=$3
echo "Creating msp config ${msp_dir}/config.yaml with cert ${ca_cert_name}"
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
}
function get_connection_profile() {
local node_name=$1
local connection_profile=$2
mkdir -p $(dirname ${connection_profile})
echo "writing $node_name connection profile to $connection_profile"
kubectl -n $NS get cm/${node_name}-connection-profile -o json \
| jq -r .binaryData.\"profile.json\" \
| base64 -d \
> ${connection_profile}
}
function enroll_org_admin() {
local type=$1
local org=$2
local username=$3
local password=$4
echo "Enrolling $type org admin $username"
ENROLLMENTS_DIR=${TEMP_DIR}/enrollments
ORG_ADMIN_DIR=${ENROLLMENTS_DIR}/${org}/users/${username}
# skip the enrollment if the admin certificate is available.
if [ -f "${ORG_ADMIN_DIR}/msp/keystore/key.pem" ]; then
echo "Found an existing admin enrollment at ${ORG_ADMIN_DIR}"
return
fi
# Retrieve the CA information from Kubernetes
CA_NAME=${org}-ca
CA_DIR=${TEMP_DIR}/cas/${CA_NAME}
CONNECTION_PROFILE=${CA_DIR}/connection-profile.json
get_connection_profile $CA_NAME $CONNECTION_PROFILE
# extract the CA enrollment URL and tls cert from the org connection profile
CA_AUTH=${username}:${password}
CA_ENDPOINT=$(jq -r .endpoints.api $CONNECTION_PROFILE)
CA_HOST=$(echo ${CA_ENDPOINT} | cut -d/ -f3 | tr ':' '\n' | head -1)
CA_PORT=$(echo ${CA_ENDPOINT} | cut -d/ -f3 | tr ':' '\n' | tail -1)
CA_URL=https://${CA_AUTH}@${CA_HOST}:${CA_PORT}
jq -r .tls.cert $CONNECTION_PROFILE | base64 -d >& $CA_DIR/tls-cert.pem
# enroll the admin user
FABRIC_CA_CLIENT_HOME=${ORG_ADMIN_DIR} fabric-ca-client enroll --url ${CA_URL} --tls.certfiles ${CA_DIR}/tls-cert.pem
# Construct an msp config.yaml
CA_CERT_NAME=${NS}-${CA_NAME}-ca-$(echo $INGRESS_DOMAIN | tr -s . -)-${CA_PORT}.pem
create_msp_config_yaml ${CA_NAME} ${CA_CERT_NAME} ${ORG_ADMIN_DIR}/msp
# private keys are hashed by name, but we only support one enrollment.
# test-network examples refer to this as "server.key", which is incorrect.
# This is the private key used to endorse transactions using the admin's
# public key.
mv ${ORG_ADMIN_DIR}/msp/keystore/*_sk ${ORG_ADMIN_DIR}/msp/keystore/key.pem
# enroll the admin user at the TLS CA - used for the channel admin API
FABRIC_CA_CLIENT_HOME=${ORG_ADMIN_DIR} \
fabric-ca-client enroll \
--url ${CA_URL} \
--tls.certfiles ${CA_DIR}/tls-cert.pem \
--mspdir ${ORG_ADMIN_DIR}/tls \
--caname tlsca
mv ${ORG_ADMIN_DIR}/tls/keystore/*_sk ${ORG_ADMIN_DIR}/tls/keystore/key.pem
}
function enroll_org_admins() {
push_fn "Enrolling org admin users"
enroll_org_admin orderer org0 org0admin org0adminpw
enroll_org_admin peer org1 org1admin org1adminpw
enroll_org_admin peer org2 org2admin org2adminpw
pop_fn
}
function create_channel_org_msp() {
local type=$1
local org=$2
echo "Creating channel org $org MSP"
CA_DIR=${TEMP_DIR}/cas/${org}-ca
ORG_MSP_DIR=${TEMP_DIR}/channel-msp/${type}Organizations/${org}/msp
mkdir -p ${ORG_MSP_DIR}/cacerts
mkdir -p ${ORG_MSP_DIR}/tlscacerts
jq -r .ca.signcerts ${CA_DIR}/connection-profile.json | base64 -d >& ${ORG_MSP_DIR}/cacerts/ca-signcert.pem
jq -r .tlsca.signcerts ${CA_DIR}/connection-profile.json | base64 -d >& ${ORG_MSP_DIR}/tlscacerts/tlsca-signcert.pem
create_msp_config_yaml ${org}-ca ca-signcert.pem ${ORG_MSP_DIR}
}
function create_channel_msp() {
push_fn "Creating channel MSP"
create_channel_org_msp orderer org0
create_channel_org_msp peer org1
create_channel_org_msp peer org2
extract_orderer_tls_cert org0 orderersnode1
extract_orderer_tls_cert org0 orderersnode2
extract_orderer_tls_cert org0 orderersnode3
pop_fn
}
function extract_orderer_tls_cert() {
local org=$1
local orderer=$2
echo "Extracting TLS cert for $org $orderer"
ORDERER_NAME=${org}-${orderer}
ORDERER_DIR=${TEMP_DIR}/channel-msp/ordererOrganizations/${org}/orderers/${ORDERER_NAME}
ORDERER_TLS_DIR=${ORDERER_DIR}/tls
CONNECTION_PROFILE=${ORDERER_DIR}/connection-profile.json
get_connection_profile $ORDERER_NAME $CONNECTION_PROFILE
mkdir -p $ORDERER_TLS_DIR/signcerts
jq -r .tls.signcerts ${CONNECTION_PROFILE} \
| base64 -d \
>& $ORDERER_TLS_DIR/signcerts/tls-cert.pem
}
function create_genesis_block() {
push_fn "Creating channel genesis block"
mkdir -p ${TEMP_DIR}/config
cp ${PWD}/config/core.yaml ${TEMP_DIR}/config/
# The channel configtx file needs to specify dynamic elements from the environment,
# for instance, the ${INGRESS_DOMAIN} for ingress controller and service endpoints.
cat ${PWD}/config/configtx-template.yaml | envsubst > ${TEMP_DIR}/config/configtx.yaml
FABRIC_CFG_PATH=${TEMP_DIR}/config \
configtxgen \
-profile TwoOrgsApplicationGenesis \
-channelID $CHANNEL_NAME \
-outputBlock ${TEMP_DIR}/genesis_block.pb
# configtxgen -inspectBlock ${TEMP_DIR}/genesis_block.pb
pop_fn
}
function join_channel_orderers() {
push_fn "Joining orderers to channel ${CHANNEL_NAME}"
join_channel_orderer org0 orderersnode1
join_channel_orderer org0 orderersnode2
join_channel_orderer org0 orderersnode3
# todo: readiness / liveiness equivalent for channel? Needs a little bit to settle before peers can join.
sleep 10
pop_fn
}
# Request from the channel ADMIN api that the orderer joins the target channel
function join_channel_orderer() {
local org=$1
local orderer=$2
# The client certificate presented in this case is the admin USER TLS enrollment key. This is a stronger assertion
# of identity than the Docker Compose network, which transmits the orderer NODE TLS key pair directly
osnadmin channel join \
--orderer-address ${NS}-${org}-${orderer}-admin.${INGRESS_DOMAIN} \
--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/tls/signcerts/cert.pem \
--client-key ${TEMP_DIR}/enrollments/${org}/users/${org}admin/tls/keystore/key.pem \
--channelID ${CHANNEL_NAME} \
--config-block ${TEMP_DIR}/genesis_block.pb
}
function join_channel_peers() {
join_org_peers 1
join_org_peers 2
}
function join_org_peers() {
local orgnum=$1
push_fn "Joining org${orgnum} peers to channel ${CHANNEL_NAME}"
# Join peers to channel
join_channel_peer $orgnum 1
join_channel_peer $orgnum 2
pop_fn
}
function join_channel_peer() {
local orgnum=$1
local peernum=$2
export_peer_context $orgnum $peernum
peer channel join \
--blockpath ${TEMP_DIR}/genesis_block.pb
}