diff --git a/014.purge_swarm.yml b/014.purge_swarm.yml index a079f77..09c7e31 100644 --- a/014.purge_swarm.yml +++ b/014.purge_swarm.yml @@ -2,7 +2,7 @@ # ansible-playbook -v 014.purge_swarm.yml -u root -- name: Initialize the host machines +- name: Purge all swarm services hosts: all gather_facts: no become: yes @@ -13,10 +13,27 @@ ignore_errors: yes when: "inventory_hostname in groups.swarm_manager_prime" + - name: "Remove an Overlay Docker Network" + become: yes + become_user: "root" + docker_network: + name: "{{ swarm_network }}" + state: absent + force: yes + when: "inventory_hostname in groups.swarm_manager_prime" + - name: Remove any orphan containers on any machine shell: 'docker rm $(docker ps -aq)' ignore_errors: yes + - name: Remove created volumes on any machone + shell: 'docker volume rm $(docker volume ls -q)' + ignore_errors: yes + + - name: prune all networks on any machine + shell: 'docker network prune -f' + ignore_errors: yes + - name: Leave swarm for a node docker_swarm: state: absent @@ -32,7 +49,7 @@ docker_swarm: state: absent force: true - when: "inventory_hostname in groups.swarm_managers" + when: "inventory_hostname in groups.swarm_managers" - name: Remove data for all services shell: "rm -rf /root/hlft-store/*" \ No newline at end of file diff --git a/101.deploy_orderer.yml b/101.deploy_orderer.yml index cf2372f..0d30652 100644 --- a/101.deploy_orderer.yml +++ b/101.deploy_orderer.yml @@ -4,7 +4,9 @@ - name: Spawn a Hyperledger Fabric Topology hosts: swarm_manager_prime - gather_facts: no + gather_facts: no + vars: + Consenters: [] roles: - - hlf/cli/orderer + - hlf/cli/orderer_prime - hlf/orderer \ No newline at end of file diff --git a/101.export_org_artifacts.yml b/101.export_org_artifacts.yml new file mode 100644 index 0000000..db5972f --- /dev/null +++ b/101.export_org_artifacts.yml @@ -0,0 +1,9 @@ +--- + +# ansible-playbook -v 101.export_org_artifacts.yml --flush-cache -u root + +- name: Spawn a Hyperledger Fabric Topology + hosts: swarm_manager_prime + gather_facts: no + roles: + - hlf/newOrg/gen_new_org_artifacts \ No newline at end of file diff --git a/101.import_org_artifacts.yml b/101.import_org_artifacts.yml new file mode 100644 index 0000000..839faa8 --- /dev/null +++ b/101.import_org_artifacts.yml @@ -0,0 +1,11 @@ +--- + +# ansible-playbook -v 101.import_org_artifacts.yml --flush-cache -u root + +- name: Spawn a Hyperledger Fabric Topology + hosts: swarm_manager_prime + gather_facts: no + vars: + artifact_path: "/tmp/bityoga_export.tgz" + roles: + - hlf/newOrg/add_new_org_artifacts \ No newline at end of file diff --git a/README.md b/README.md index 5215a62..e6ca236 100644 --- a/README.md +++ b/README.md @@ -210,7 +210,8 @@ Setting up of hyperledger fabric cluster requires the following steps. Creating - Contains mounts of MSPs for all agents (admin, orderer, peers, ...) - Can perfrom any and all operations on the blockchain by changing its profile to any of the mounted agents - Mounts a test chaincode under `/root/CLI/chaincodes/test_chaincode` - - Sanity Check the working of the cluster + - Sanity Check the working of the cluster [OPTIONAL] + - Test chaincode is automatically installed when *INSTALL_TEST_CHAINCODE: "yes"* in *group_vars/all.yml*. If, *INSTALL_TEST_CHAINCODE: "no"* then you can install it manually, if needed, by following the steps bellow: - Install, Instanciate and Test Chaincode ```bash docker exec -it <> bash @@ -218,37 +219,39 @@ Setting up of hyperledger fabric cluster requires the following steps. Creating CORE_PEER_ADDRESS=${PEER_HOST}:7051 CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${ADMIN_USER}/msp CORE_PEER_TLS_ROOTCERT_FILE=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/ca.crt + CORE_PEER_TLS_CLIENTAUTHREQUIRED=true + CORE_PEER_TLS_CLIENTCERT_FILE=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.crt #fully qualified path of the client certificate + CORE_PEER_TLS_CLIENTKEY_FILE=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.key #fully qualified path of the client private key ``` - Install the chaincode on peer 2 ```bash - CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE peer chaincode install -n testcc -v 1.0 -l node -p /root/CLI/chaincodes/test_chaincode/node + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode install -n testcc -v 1.0 -l node -p /root/CLI/chaincodes/test_chaincode/node ``` - Instanciate the chaincode ```bash - CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE peer chaincode instantiate -C appchannel -n testcc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -o ${ORDERER_HOST}:7050 --tls --cafile ${CORE_PEER_TLS_ROOTCERT_FILE} + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode instantiate -C appchannel -n testcc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -o ${ORDERER_HOST}:7050 --tls --cafile ${CORE_PEER_TLS_ROOTCERT_FILE} --clientauth --certfile /root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.crt --keyfile /root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.key ``` - List the installed chaincodes ```bash - CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE peer chaincode list --installed + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode list --installed ``` - List the instanciated chaincodes - ```bash - CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE peer chaincode list --instantiated -C appchannel + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode list --instantiated -C appchannel ``` - GET ```bash - CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE peer chaincode query -C appchannel -n testcc -c '{"Args":["query","a"]}' + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode query -C appchannel -n testcc -c '{"Args":["query","a"]}' ``` - PUT ```bash - CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE peer chaincode invoke -C appchannel -n testcc -c '{"Args":["invoke","a","b","10"]}' -o ${ORDERER_HOST}:7050 --tls --cafile ${CORE_PEER_TLS_ROOTCERT_FILE} + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode invoke -C appchannel -n testcc -c '{"Args":["invoke","a","b","10"]}' -o ${ORDERER_HOST}:7050 --tls --cafile ${CORE_PEER_TLS_ROOTCERT_FILE} --clientauth --certfile /root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.crt --keyfile /root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.key ``` - GET ```bash - CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE peer chaincode query -C appchannel -n testcc -c '{"Args":["query","a"]}' + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode query -C appchannel -n testcc -c '{"Args":["query","a"]}' ``` - Playbook: `104.deploy_hlf_explorer` diff --git a/filter_plugins/__pycache__/enumerate.cpython-37.pyc b/filter_plugins/__pycache__/enumerate.cpython-37.pyc index 01827cc..d0f2518 100644 Binary files a/filter_plugins/__pycache__/enumerate.cpython-37.pyc and b/filter_plugins/__pycache__/enumerate.cpython-37.pyc differ diff --git a/filter_plugins/__pycache__/enumerate.cpython-38.pyc b/filter_plugins/__pycache__/enumerate.cpython-38.pyc index ac0f871..524b5b7 100644 Binary files a/filter_plugins/__pycache__/enumerate.cpython-38.pyc and b/filter_plugins/__pycache__/enumerate.cpython-38.pyc differ diff --git a/group_vars/all.yml b/group_vars/all.yml index 58258fb..69b4217 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -1,5 +1,6 @@ --- -LOG_LEVEL: "INFO" +LOG_LEVEL: "DEBUG" +INSTALL_TEST_CHAINCODE: "yes" ########################################################################################### # # # # @@ -21,8 +22,8 @@ glusterd_version: '7' # Organization Details org: - name: "hlf" - unit: "bityoga" + name: "agelia" + unit: "energy" # Creds of various agents admin_user: "admin1" @@ -83,8 +84,8 @@ orgca: { switch: "on", image: "hyperledger/fabric-ca", tag: "1.4", replicas: -1, ######################################### Orderer ############################################# orderer: { switch: "on", image: "hyperledger/fabric-orderer", tag: "2.2", replicas: -1, port: 8053, caname: "{{orgca.name}}", anchorpeer: "{{peer1.name}}", anchorport: "{{peer1.port}}", -path: "/root/{{orderer_user}}", type: "solo", -name: "{{orderer_user}}", password: "{{orderer_password}}", type: "orderer" +path: "/root/{{orderer_user}}", type: "orderer", +name: "{{orderer_user}}", password: "{{orderer_password}}" } ######################################### Peers ############################################# @@ -92,7 +93,7 @@ peer1: { switch: "on", image: "hyperledger/fabric-peer", tag: "2.2", replicas: - caname: "{{orgca.name}}", path: "/root/{{peer1_user}}", bootstrap: "", dbtype: "goleveldb", name: "{{peer1_user}}", password: "{{peer1_password}}", type: "peer", -leader: "{peer1_user}}" +leader: "{{peer1_user}}" } peer2: { switch: "on", image: "hyperledger/fabric-peer", tag: "2.2", replicas: -1, port: 8055, @@ -103,7 +104,7 @@ leader: "{{peer1_user}}" } ######################################### CLI ############################################# -cli: { switch: "on", image: "hyperledger/fabric-tools", tag: "2.2"} +cli: { switch: "on", name: "CLI", image: "hyperledger/fabric-tools", tag: "2.2"} ######################################### DBs ############################################# sqlite: {type: "sqlite3", source: "fabric-ca-server.db"} diff --git a/inventory/hosts_org1 b/inventory/hosts_org1 new file mode 100644 index 0000000..c0ae418 --- /dev/null +++ b/inventory/hosts_org1 @@ -0,0 +1,15 @@ +[all:children] +swarm_manager_prime +swarm_managers +swarm_workers + +[swarm_manager_prime] +hlf0 ansible_host=165.232.76.37 ansible_python_interpreter=/usr/bin/python3 + + +[swarm_managers] +hlf0 ansible_host=165.232.76.37 ansible_python_interpreter=/usr/bin/python3 + +[swarm_workers] +hlf1 ansible_host=138.68.87.60 ansible_python_interpreter=/usr/bin/python3 +hlf2 ansible_host=138.68.87.49 ansible_python_interpreter=/usr/bin/python3 \ No newline at end of file diff --git a/inventory/hosts_org2 b/inventory/hosts_org2 new file mode 100644 index 0000000..689d759 --- /dev/null +++ b/inventory/hosts_org2 @@ -0,0 +1,14 @@ +[all:children] +swarm_manager_prime +swarm_managers +swarm_workers + +[swarm_manager_prime] +hlf0 ansible_host=142.93.216.173 ansible_python_interpreter=/usr/bin/python3 + + +[swarm_managers] +hlf0 ansible_host=142.93.216.173 ansible_python_interpreter=/usr/bin/python3 + +[swarm_workers] +hlf1 ansible_host=134.209.146.246 ansible_python_interpreter=/usr/bin/python3 diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..bcdedf0 --- /dev/null +++ b/notes.txt @@ -0,0 +1,43 @@ +#adding new orgs +NEW_ORG_NAME=bityoga +CHANNEL_NAME=syschannel + +configtxgen -printOrg ${NEW_ORG_NAME}MSP > org${NEW_ORG_NAME}.json -configPath /root/CLI/new_org_artifacts + +PEER_HOST=peer1 +CORE_PEER_ADDRESS=${PEER_HOST}:7051 +CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${ADMIN_USER}/msp + +CORE_PEER_TLS_ENABLED=true +CORE_PEER_TLS_ROOTCERT_FILE=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/ca.crt +CORE_PEER_TLS_KEY_FILE=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.key +CORE_PEER_TLS_CERT_FILE=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.crt +CORE_PEER_TLS_CLIENTAUTHREQUIRED=false + +CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH peer channel fetch config config_block.pb -o ${ORDERER_HOST}:7050 -c $CHANNEL_NAME --tls --cafile ${CORE_PEER_TLS_ROOTCERT_FILE} --clientauth --certfile ${CORE_PEER_TLS_CERT_FILE} --keyfile ${CORE_PEER_TLS_KEY_FILE} + + +configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json + +jq -s '.[0] * {"channel_group":{"groups":{"Orderer":{"groups": {"'${NEW_ORG_NAME}MSP'":.[1]}}}}}' config.json org${NEW_ORG_NAME}.json > config1.json + +jq -s '.[0] * {"channel_group":{"groups":{"Consortiums":{"groups":{"SampleConsortium":{"groups": {"'${NEW_ORG_NAME}MSP'":.[1]}}}}}}}' config1.json org${NEW_ORG_NAME}.json > config2.json + +cert=`base64 ./tls/server.crt | sed ':a;N;$!ba;s/\n//g'` + +cat config2.json | jq '.channel_group.groups.Orderer.values.ConsensusType.value.metadata.consenters += [{"client_tls_cert": "'$cert'", "host": "142.93.216.173", "port": 8053, "server_tls_cert": "'$cert'"}] ' > modified_config.json + + +configtxlator proto_encode --input config.json --type common.Config --output config.pb +configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb +configtxlator compute_update --channel_id ${CHANNEL_NAME} --original config.pb --updated modified_config.pb --output neworg.pb +configtxlator proto_decode --input neworg.pb --type common.ConfigUpdate | jq . > neworg.json +echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL_NAME'", "type":2}},"data":{"config_update":'$(cat neworg.json)'}}}' | jq . > org_update_in_envelope.json +configtxlator proto_encode --input org_update_in_envelope.json --type common.Envelope --output org_update_in_envelope.pb + + + + +CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH peer channel signconfigtx -f org_update_in_envelope.pb + +CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH peer channel update -o ${ORDERER_HOST}:7050 -c ${CHANNEL_NAME} -f org_update_in_envelope.pb --tls --cafile ${ORDERER_CA} --clientauth --certfile ${CORE_PEER_TLS_CERT_FILE} --keyfile ${CORE_PEER_TLS_KEY_FILE} \ No newline at end of file diff --git a/register_service/200.deploy_ registrar_service.yml b/register_service/200.deploy_ registrar_service.yml new file mode 100644 index 0000000..9ad9c5a --- /dev/null +++ b/register_service/200.deploy_ registrar_service.yml @@ -0,0 +1,95 @@ +--- + +# ansible-playbook -v 200.deploy_registrar_service.yml -u root + +- name: Deploy Registrar Service + hosts: all + gather_facts: no + tasks: + - name: Clean Registrar Folder Structure + file: + path: "/root/hlft-store/{{registrar.name}}" + state: absent + + - name: Create Registrar Folder Structure + file: + path: "/root/hlft-store/{{registrar.name}}" + state: directory + + - name: Create tls-admin Folder Structure + file: + path: "/root/hlft-store/{{registrar.name}}/tls-{{admin.name}}" + state: directory + + - name: Copy relevent files + copy: + src: "{{item[0]}}" + dest: "/root/hlft-store/{{registrar.name}}/{{item[0]}}" + mode: "{{item[1]}}" + loop: + - ["package.json", 400] + - ["server.json", 400] + - ["setup.sh", 500] + + - name: Template required files + become: yes + template: + src: "{{item}}.j2" + dest: "/root/hlft-store/{{registrar.name}}/{{item}}" + mode: '0750' + force: yes + loop: + - "connection_profile.json" + - "server.js" + + - name: Get keystore filename for admin user + shell: ls /root/hlft-store/{{admin.tlsca}}/{{admin.name}}/msp/keystore | sort -n | head -1 + register: key_filename + ignore_errors: True + + - name: Copy relevent tls files for admin user + copy: + src: "/root/hlft-store/{{admin.tlsca}}/{{admin.name}}/msp/{{item[0]}}" + dest: "/root/hlft-store/{{registrar.name}}/tls-{{admin.name}}/{{item[1]}}" + remote_src: yes + loop: + - ["tlscacerts/tls-{{tlsca.name}}-7054.pem", "ca.crt"] + - ["signcerts/cert.pem", "server.crt"] + - ["keystore/key.pem", "server.key"] + + - name: Stop the Registrar Service + become: yes + docker_swarm_service: + name: "{{ registrar.name }}" + state: absent + + - name: Start the Registrar Service + become: yes + docker_swarm_service: + name: "{{ registrar.name }}" + hostname: "{{ registrar.name }}" + networks: + - "{{swarm_network}}" + image: "{{registrar.image}}:{{registrar.tag}}" + mode: replicated + replicas: "{{registrar.replicas}}" + mounts: + - source: "/root/hlft-store/{{registrar.name}}" + target: "{{registrar.path}}" + type: bind + publish: + - published_port: "{{registrar.port}}" + target_port: "8080" + protocol: "tcp" + working_dir: "{{registrar.path}}" + command: > + bash -c "{{registrar.path}}/setup.sh;" + placement: + constraints: + - node.role == worker + force_update: yes + + # Pause for 25 seconds for yarn install to complete + - name: Pause for 30 seconds for yarn install to complete + pause: + seconds: 30 \ No newline at end of file diff --git a/register_service/README.md b/register_service/README.md new file mode 100644 index 0000000..9cc283d --- /dev/null +++ b/register_service/README.md @@ -0,0 +1,26 @@ +# Registar Server for fabric-as-code (HTTPS Enabled) +The register service is an **optional** service provided for the fabric as code hyperledger fabric network. This service provides a RESTful App for registration of users. This purticularly useful for mobile Hyperledger Fabric clients that would like to call a registration service with admin rights that is able to register a given user. + +## Pre-requisites +- Make sure that the the fabric-as-code is up and running +- You have to run the playbook '200.deploy_ registrar_service.yml' on the master node of the fabric-as-code network +- Change the file **inventory/hosts** in this directory + - Please replace the *ip.address* value in the following line inside *inventory/host* to the ip address of the machine running the master node + ```hlf1 ansible_host=ip.address ansible_python_interpreter=/usr/bin/python3``` +- Change the file **group_vars/all.yml** in this directory + - Change the following two values + - ```admin_name```: name of the user with admin rights that can register new client users. **Note: This user needs to have been already been registered with the hyperledger fabric network** + - ```admin_password```: password of the aforementioned user +- Make sure port **8088** is open for the master node of the hyperledger fabric network + +## Start the service +- Inorder to start the service run the following command +- Make sure that the machine form which you are running the following commands, has ansible version of atleast **ansible 2.9.1** or up. +- !!!Required: Ensure that you have password less SSH for these host for a user. Later when you run the playbooks change the value for the playbooks with argument -u to the appropiate user that has passwordless SHH access to these machines +- 200.deploy_ registrar_service.yml: Playbook that runs the registration services +```ansible-playbook -v 200.deploy_ registrar_service.yml -u root``` + +## Varification +- Test connection: *curl -k -X POST https://165.232.76.37:8088* +- Register a user: *curl -k -X POST -d "username=user1&password=user1pw" https://165.232.76.37:8088/register* + - Change the value for username or password \ No newline at end of file diff --git a/register_service/ansible.cfg b/register_service/ansible.cfg new file mode 100644 index 0000000..f92030c --- /dev/null +++ b/register_service/ansible.cfg @@ -0,0 +1,20 @@ +# config file for ansible -- https://ansible.com/ +# =============================================== + +[defaults] +inventory = ./inventory/hosts +callback_whitelist = profile_tasks + + +# Supresses check og host names in known hosts +host_key_checking = False + + + +# # Mitogen specific config +# strategy_plugins = ./plugins/mitogen-0.2.8/ansible_mitogen/plugins/strategy +# strategy = mitogen_linear + +# Dont enable in dev mode +#[ssh_connection] +#pipelining = True \ No newline at end of file diff --git a/register_service/dev.yml b/register_service/dev.yml new file mode 100644 index 0000000..056dd05 --- /dev/null +++ b/register_service/dev.yml @@ -0,0 +1,16 @@ +--- +- name: Test Playbook + hosts: all + gather_facts: no + tasks: + - name: Template required files + become: yes + template: + src: "{{item}}.j2" + dest: "/root/hlft-store/{{registrar.name}}/{{item}}" + mode: '0750' + force: yes + loop: + - "server.js" + # - debug: + # msg: "{{ admin.cas.values() | list }}" \ No newline at end of file diff --git a/register_service/docker-compose.yaml b/register_service/docker-compose.yaml new file mode 100644 index 0000000..a13410b --- /dev/null +++ b/register_service/docker-compose.yaml @@ -0,0 +1,21 @@ +version: '3' +networks: + mysomenet-ov: + # If network is created with deplyment, Chaincode container cannot connect to network + external: + name: mysomenet-ov + +services: + register-server: + image: 127.0.0.1:5000/register-server + build: + context: . + dockerfile: ./services/nodejs/Dockerfile + hostname: register-server + container_name: register-server + working_dir: /home/node/register-server + networks: + - mysomenet-ov + ports: + - "8080:8080" + command: node /home/node/register-server/server.js \ No newline at end of file diff --git a/register_service/files/package.json b/register_service/files/package.json new file mode 100644 index 0000000..5e7e44a --- /dev/null +++ b/register_service/files/package.json @@ -0,0 +1,19 @@ +{ + "name": "register-server", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.16.3", + "fabric-network": "~1.4.4", + "fabric-ca-client": "~1.4.4", + "fabric-client": "~1.4.4" + } +} \ No newline at end of file diff --git a/register_service/files/server.json b/register_service/files/server.json new file mode 100644 index 0000000..9f87095 --- /dev/null +++ b/register_service/files/server.json @@ -0,0 +1,7 @@ +{ + "host": "localhost", + "port": 8080, + "credentialStore": "credentialStore", + "cryptoStore": "credentialStore/cryptoStore", + "userrole": "client" +} \ No newline at end of file diff --git a/register_service/files/setup.sh b/register_service/files/setup.sh new file mode 100755 index 0000000..c727806 --- /dev/null +++ b/register_service/files/setup.sh @@ -0,0 +1,7 @@ +echo "..." +yarn install; +echo "yarn install complete" +node ./server.js +# while true; do +# sleep 0.1 +# done diff --git a/register_service/group_vars/all.yml b/register_service/group_vars/all.yml new file mode 100644 index 0000000..d5a7f27 --- /dev/null +++ b/register_service/group_vars/all.yml @@ -0,0 +1,33 @@ +--- +# Name of the user that is already registered with the fabric network. This user should have admin rights, so that it is able to register other users +admin_name: "admin1" # Argument to change +admin_password: "admin1pw" # Argument to change + +# Advances settings. Change these, if you know what you are doing. +admin: + name: "{{admin_name}}" + password: "{{admin_password}}" + cas: + orgca: "orgca" + tlsca: "tlsca" + path: "/root/{{admin_name}}" + +user: "" + +# Name of the swarm network that would host the services +swarm_network: "hlfnet" +registrar_name: "registrar" + +# Image information for the registration service +registrar: + name: "{{registrar_name}}" + image: "node" + tag: "12.15" + replicas: -1 + path: "/root/{{registrar_name}}" + port: 8088 + +# Info about the organization that hosts the CA(s) +org: + name: "hlf" + unit: "bityoga" \ No newline at end of file diff --git a/register_service/inventory/hosts b/register_service/inventory/hosts new file mode 100644 index 0000000..e0f0858 --- /dev/null +++ b/register_service/inventory/hosts @@ -0,0 +1 @@ +hlf1 ansible_host=165.232.76.37 ansible_python_interpreter=/usr/bin/python3 \ No newline at end of file diff --git a/register_service/templates/connection_profile.json.j2 b/register_service/templates/connection_profile.json.j2 new file mode 100644 index 0000000..1576327 --- /dev/null +++ b/register_service/templates/connection_profile.json.j2 @@ -0,0 +1,97 @@ +{ + "name": "{{org.name}}-{{org.unit}}", + "version": "1.0.0", + "client": { + "organization": "{{org.name}}", + "connection": { + "timeout": { + "peer": { + "endorser": "300" + } + } + } + }, + "channels": { + "appchannel": { + "orderers": [ + "orderer" + ], + "peers": { + "peer2": { + "endorsingPeer": "true", + "chaincodeQuery": "false", + "ledgerQuery": "false", + "eventSource": "false", + "discover": "true" + }, + "peer1": { + "endorsingPeer": "false", + "chaincodeQuery": "true", + "ledgerQuery": "false", + "eventSource": "false", + "discover": "true" + } + } + } + }, + "organizations": { + "hlf": { + "mspid": "hlfMSP", + "peers": [ + "peer2", + "peer1" + ], + "certificateAuthorities": [ + "orgca", + "tlsca" + ] + } + }, + "orderers": { + "orderer": { + "url": "grpcs://ip.address:8053", + "tlsCACerts": { + "path": "./hlft-store/hlfMSP/tlscacerts/tls-tlsca-7054.pem" + }, + "grpcOptions": { + "ssl-target-name-override": "orderer" + } + } + }, + "peers": { + "peer1": { + "url": "grpcs://ip.address:8054", + "tlsCACerts": { + "path": "/root/{{user}}/msp/tls/ca.crt" + }, + "grpcOptions": { + "ssl-target-name-override": "peer1" + } + }, + "peer2": { + "url": "grpcs://ip.address:8055", + "tlsCACerts": { + "path": "/root/{{user}}/msp/tls/ca.crt" + }, + "grpcOptions": { + "ssl-target-name-override": "peer2" + } + } + }, + "certificateAuthorities": { + "orgca": { + "caName": "orgca", + "url": "https://orgca:7054", + "httpOptions": { + "verify": false + } + }, + "tlsca": { + "caName": "tlsca", + "url": "https://tlsca:7054", + "httpOptions": { + "verify": false + } + } + } +} \ No newline at end of file diff --git a/register_service/templates/server.js.j2 b/register_service/templates/server.js.j2 new file mode 100644 index 0000000..da34d5d --- /dev/null +++ b/register_service/templates/server.js.j2 @@ -0,0 +1,156 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +// Hyperledger Fabric CA Related imports +const FabricCAServices = require('fabric-ca-client'); +const { FileSystemWallet, Gateway, X509WalletMixin } = require('fabric-network'); + +const fs = require('fs'); +const path = require('path'); + +const ccpPath = path.resolve(__dirname, '.', 'connection_profile.json'); +const ccpJSON = fs.readFileSync(ccpPath, 'utf8'); +const ccp = JSON.parse(ccpJSON); + +const ORGANISATION_MSP = "{{org.name}}MSP"; + +async function enrollAdmin(CA_ORGANISATION_NAME) { + try { + + + // Create a new CA client for interacting with the CA. + const caInfo = ccp.certificateAuthorities[CA_ORGANISATION_NAME]; + console.log(caInfo); + const caTLSCACerts = ["{{admin.path}}/ca.crt"]; + //const caTLSCACerts = caInfo.tlsCACerts.pem; + const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName); + + // Create a new file system based wallet for managing identities. + const walletPath = path.join(process.cwd(), 'wallet'); + + const wallet = new FileSystemWallet(walletPath); + console.log(`Wallet path: ${walletPath}`); + + // Check to see if we've already enrolled the admin user. + const adminExists = await wallet.exists("{{admin.name}}-" + CA_ORGANISATION_NAME); + if (adminExists) { + console.log('An identity for the admin user "{{admin.name}}-' + CA_ORGANISATION_NAME + 'already exists in the wallet'); + return; + } + + // Enroll the admin user, and import the new identity into the wallet. + const enrollment = await ca.enroll({ enrollmentID: "{{admin.name}}", enrollmentSecret: "{{admin.password}}" }); + const identity = X509WalletMixin.createIdentity(ORGANISATION_MSP, enrollment.certificate, enrollment.key.toBytes()); + await wallet.import("{{admin.name}}-" + CA_ORGANISATION_NAME, identity); + console.log('Successfully enrolled admin user {{admin.name}}-' + CA_ORGANISATION_NAME + ' and imported it into the wallet'); + + } catch (error) { + console.error(`Failed to enroll admin user {{admin.name}}-${CA_ORGANISATION_NAME} : ${error}`); + process.exit(1); + } +} + +// Node Express Related imports +const util = require('util'); +const os = require('os'); +const https = require('https'); +const express = require('express'); +const bodyParser = require('body-parser'); + +// Setting up https +var options = { + key: fs.readFileSync('{{registrar.path}}/tls-{{admin.name}}/server.key'), + cert: fs.readFileSync('{{registrar.path}}/tls-{{admin.name}}/server.crt'), + ca: fs.readFileSync('{{registrar.path}}/tls-{{admin.name}}/ca.crt') +} + +var server_config = require('./server.json'); + +// Create a service (the app object is just a callback). +var app = express(); +//support parsing of application/json type post data +app.use(bodyParser.json()); +//support parsing of application/x-www-form-urlencoded post data +app.use(bodyParser.urlencoded({ + extended: true +})); + +app.post('/', async function (req, res) { + res.setHeader('Content-Type', 'text/html'); + res.end('here i am \n'); + +}) + +app.post('/register', async function (req, res) { + res.setHeader('Content-Type', 'application/json'); + var status = false; + var msg = ""; + var current_ca = ""; + try { + + // Create a new file system based wallet for managing identities. + const walletPath = path.join(process.cwd(), 'wallet'); + const wallet = new FileSystemWallet(walletPath); + console.log(`Wallet path: ${walletPath}`); + + var adminExists; + // Create a new gateway for connecting to our peer node. + const gateway = new Gateway(); + var ca; + var adminIdentity; + + {% for ca_name in admin.cas.values() | list %} + current_ca = "{{ca_name}}"; + // Check to see if we've already enrolled the admin user. + adminExists = await wallet.exists("{{admin.name}}-{{ca_name}}"); + if (!adminExists) { + console.log('An identity for the admin user "{{admin.name}}-{{ca_name}}" does not exist in the wallet'); + msg = "System issue. See logs!" + res.status(400).json({ + status: status, + message: msg + }); + } else { + status=false; + await gateway.connect(ccpPath, { wallet, identity: "{{admin.name}}-{{ca_name}}", discovery: { enabled: true, asLocalhost: true } }); + // Get the CA client object from the gateway for interacting with the CA. + ca = gateway.getClient().getCertificateAuthority("{{ca_name}}"); + adminIdentity = gateway.getCurrentIdentity(); + + // Register the user, enroll the user, and import the new identity into the wallet. + await ca.register({ enrollmentID: req.body.username, role: server_config.userrole, enrollmentSecret: req.body.password }, adminIdentity); + console.log('Successfully registered user "' + req.body.username + '" with role "' + server_config.userrole + "onto ca " + "{{ca_name}}"); + msg += 'Successfully registered user "' + req.body.username + '" with role "' + server_config.userrole + "onto ca " + "{{ca_name}}" + '\n'; + + status=true; + } + + {% endfor %} + + } catch (error) { + console.error(`Failed to register user for ${current_ca} ca with error ${error}`); + msg = `Failed to register user for ${current_ca} ca with error ${error}`; + res.status(400).json({ + status: status, + message: msg + }); + } + res.status(200).json({ + status: status, + message: msg + }); +}) + +var server = https.createServer(options, app); + +server.listen(server_config.port, function () { + console.info('****************** SERVER STARTED ************************'); + console.info('*************** https://%s:%s ******************', server_config.host, server_config.port); + //Enroll the Admin User for orgca + enrollAdmin("{{admin.cas.orgca}}"); + //Enroll the Admin User for tlsca + enrollAdmin("{{admin.cas.tlsca}}"); +}); \ No newline at end of file diff --git a/roles/hlf/cli/ca/files/cli.sh b/roles/hlf/cli/ca/files/cli.sh index b0c0df7..46a05bb 100644 --- a/roles/hlf/cli/ca/files/cli.sh +++ b/roles/hlf/cli/ca/files/cli.sh @@ -26,9 +26,9 @@ if (($IDX == 0)); then export FABRIC_CA_CLIENT_HOME=$HOST_HOME/$ADMIN_USER fabric-ca-client enroll -d -u https://$ADMIN_USER:$ADMIN_SECRET@$FABRIC_CA_NAME:$FABRIC_CA_PORT - printf "${GREEN}Make $AGENT_HOST admin of itself${NC}\n" - mkdir -p $HOST_HOME/$ADMIN_USER/msp/admincerts - cp $HOST_HOME/$ADMIN_USER/msp/signcerts/cert.pem $HOST_HOME/$ADMIN_USER/msp/admincerts/${ADMIN_USER}-cert.pem + printf "${GREEN}Make $AGENT_HOST admin of itself${NC}\n" + mkdir -p $HOST_HOME/$ADMIN_USER/msp/admincerts + cp $HOST_HOME/$ADMIN_USER/msp/signcerts/cert.pem $HOST_HOME/$ADMIN_USER/msp/admincerts/${ADMIN_USER}-cert.pem fi # Delay the registration and enrollment of agents, by few seconds so that the registration and enrollment of admins are done first. @@ -38,13 +38,13 @@ if [ $type == $tlsca ]; then # We make sure that we are pointed to the admin user, prior to registering agents printf "${GREEN}Register agent $AGENT_HOST of type $AGENT_TYPE at $FABRIC_CA_NAME${NC}\n" export FABRIC_CA_CLIENT_HOME=$HOST_HOME/$ADMIN_USER - fabric-ca-client register -d --id.name $AGENT_HOST --id.secret $AGENT_SECRET --id.type $AGENT_TYPE -u https://$FABRIC_CA_NAME:$FABRIC_CA_PORT + fabric-ca-client register -d --id.name $AGENT_HOST --id.secret $AGENT_SECRET --id.type $AGENT_TYPE -u https://$FABRIC_CA_NAME:$FABRIC_CA_PORT # Enroll Agent printf "${GREEN}Enroll agent $AGENT_HOST for $FABRIC_CA_NAME${NC}\n" export FABRIC_CA_CLIENT_MSPDIR=tls-msp export FABRIC_CA_CLIENT_HOME=$HOST_HOME/$AGENT_HOST - fabric-ca-client enroll -d -u https://$AGENT_HOST:$AGENT_SECRET@$FABRIC_CA_NAME:$FABRIC_CA_PORT --enrollment.profile tls --csr.hosts ${AGENT_HOST} + fabric-ca-client enroll -d -u https://$AGENT_HOST:$AGENT_SECRET@$FABRIC_CA_NAME:$FABRIC_CA_PORT --enrollment.profile tls --csr.hosts ${CSR_HOSTS} filename=$(ls $FABRIC_CA_CLIENT_HOME/$FABRIC_CA_CLIENT_MSPDIR/keystore | sort -n | head -1) mv $FABRIC_CA_CLIENT_HOME/$FABRIC_CA_CLIENT_MSPDIR/keystore/$filename $FABRIC_CA_CLIENT_HOME/$FABRIC_CA_CLIENT_MSPDIR/keystore/key.pem diff --git a/roles/hlf/cli/ca/tasks/main.yaml b/roles/hlf/cli/ca/tasks/main.yaml index 925c39d..f7ae0e0 100644 --- a/roles/hlf/cli/ca/tasks/main.yaml +++ b/roles/hlf/cli/ca/tasks/main.yaml @@ -22,6 +22,12 @@ force: yes loop: "{{ caservices }}" +- name: Build a list for all --csr.hosts + vars: + csrhostslist: "{{ caservices | map(attribute='name') | list + peerservices | map(attribute='name') | list + [ orderer.name ] + [ cli.name ] + ['localhost'] + groups['swarm_managers'] | map('extract', hostvars, ['ansible_host']) | list }}" + set_fact: + csrhosts: "{{csrhostslist | join(',')}}" + # Enroll Agents on each CA service - name: ENROLL Agents for Fabric Service - "{{ item.0.name }}_{{item.1.1.name}}_cli" become: yes @@ -52,6 +58,7 @@ - "AGENT_HOST={{item.1.1.name}}" - "AGENT_SECRET={{item.1.1.password}}" - "AGENT_TYPE={{item.1.1.type}}" + - "CSR_HOSTS={{csrhosts}}" placement: constraints: - node.role == worker diff --git a/roles/hlf/cli/cli/files/CLI.sh b/roles/hlf/cli/cli/files/CLI.sh new file mode 100644 index 0000000..a1986d9 --- /dev/null +++ b/roles/hlf/cli/cli/files/CLI.sh @@ -0,0 +1,46 @@ +#### Pretty Print ##### +GREEN='\033[0;32m' +RED='\033[0;31m' +NC='\033[0m' +# e.g.: printf "${GREEN} I love Stack Overflow$NC\n" +####################### +if [ $INSTALL_TEST_CHAINCODE == "yes" ]; then + printf "${GREEN}Starting the process of installing test chaincode. Test chaincode will always be installed on peer2 as per the default architecture. If you want to install it on a different peer or you have changed the default architecture, please set INSTALL_TEST_CHAINCODE: no in group_vars/all.yml. Refer to ReadMe about how to install a chaincode (test) manually on a peer.{NC}\n" + PEER_HOST=peer2 + CORE_PEER_ADDRESS=${PEER_HOST}:7051 + CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${ADMIN_USER}/msp + CORE_PEER_TLS_ROOTCERT_FILE=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/ca.crt + CORE_PEER_TLS_CLIENTAUTHREQUIRED=false + CORE_PEER_TLS_CLIENTCERT_FILE=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.crt #fully qualified path of the client certificate + CORE_PEER_TLS_CLIENTKEY_FILE=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.key #fully qualified path of the client private key + + printf "${GREEN}Install the chaincode on peer 2${NC}\n" + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode install -n testcc -v 1.0 -l node -p /root/CLI/chaincodes/test_chaincode/node + sleep 3s; + + printf "${GREEN}Instanciate the chaincode${NC}\n" + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode instantiate -C appchannel -n testcc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -o ${ORDERER_HOST}:7050 --tls --cafile ${CORE_PEER_TLS_ROOTCERT_FILE} --clientauth --certfile /root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.crt --keyfile /root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.key + sleep 3s; + + printf "${GREEN}List the installed chaincodes${NC}\n" + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode list --installed + + printf "${GREEN}List the instanciated chaincodes${NC}\n" + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode list --instantiated -C appchannel + + printf "${GREEN}Run a GET Query${NC}\n" + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode query -C appchannel -n testcc -c '{"Args":["query","a"]}' + + printf "${GREEN}Run a PUT Invoke Query${NC}\n" + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode invoke -C appchannel -n testcc -c '{"Args":["invoke","a","b","10"]}' -o ${ORDERER_HOST}:7050 --tls --cafile ${CORE_PEER_TLS_ROOTCERT_FILE} --clientauth --certfile /root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.crt --keyfile /root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp/tls/server.key + sleep 3s; + + printf "${GREEN}Run a GET Query after running the PUT Invoke Query${NC}\n" + CORE_PEER_ADDRESS=$CORE_PEER_ADDRESS CORE_PEER_MSPCONFIGPATH=/root/CLI/${ORGCA_HOST}/${PEER_HOST}/msp CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer chaincode query -C appchannel -n testcc -c '{"Args":["query","a"]}' + + printf "${GREEN}Installing test Chaincode complete!${NC}\n" +fi + +printf "${GREEN}Keeping CLI active${NC}\n" + +while true; do sleep 2; done; \ No newline at end of file diff --git a/roles/hlf/cli/cli/tasks/main.yml b/roles/hlf/cli/cli/tasks/main.yml index 6443003..7168a24 100644 --- a/roles/hlf/cli/cli/tasks/main.yml +++ b/roles/hlf/cli/cli/tasks/main.yml @@ -15,22 +15,30 @@ src: "test_chaincode/" dest: "/root/hlft-store/chaincodes/test_chaincode" mode: 0750 + +- name: Copy CLI script + become: yes + copy: + src: "CLI.sh" + dest: "/root/hlft-store/CLI.sh" + mode: "0500" + force: yes # Create & Start service for CLI -- name: Fabric Service - {{ item.name }} +- name: Fabric Service - {{ cli.name }} become: yes docker_swarm_service: - name: "CLI" - hostname: "CLI" + name: "{{ cli.name }}" + hostname: "{{ cli.name }}" networks: - "{{swarm_network}}" image: "{{cli.image}}:{{cli.tag}}" command: > - bash -c "while true; do sleep 2; done;" - working_dir: /root/CLI + bash -c "/root/{{ cli.name }}/CLI.sh;" + working_dir: /root/{{ cli.name }} mounts: - source: "/root/hlft-store" - target: "/root/CLI" + target: "/root/{{ cli.name }}" type: bind env: - "GOPATH=/opt/gopath" @@ -41,8 +49,14 @@ - "ADMIN_USER={{admin_user}}" - "TLSCA_HOST={{tlsca.name}}" - "ORGCA_HOST={{orgca.name}}" + - "INSTALL_TEST_CHAINCODE={{INSTALL_TEST_CHAINCODE}}" placement: constraints: - node.role == worker force_update: yes - when: cli.switch == "on" \ No newline at end of file + when: cli.switch == "on" + +- name: Remove orphan CLIs + become: yes + shell: docker service rm $(docker service ls | grep _cli | cut -b 1-12 | sed 's/ *$//g') + ignore_errors: yes \ No newline at end of file diff --git a/roles/hlf/cli/orderer/files/cli.sh b/roles/hlf/cli/orderer_prime/files/cli.sh similarity index 100% rename from roles/hlf/cli/orderer/files/cli.sh rename to roles/hlf/cli/orderer_prime/files/cli.sh diff --git a/roles/hlf/cli/orderer/tasks/main.yaml b/roles/hlf/cli/orderer_prime/tasks/main.yaml similarity index 68% rename from roles/hlf/cli/orderer/tasks/main.yaml rename to roles/hlf/cli/orderer_prime/tasks/main.yaml index 139ca87..a00355a 100644 --- a/roles/hlf/cli/orderer/tasks/main.yaml +++ b/roles/hlf/cli/orderer_prime/tasks/main.yaml @@ -1,7 +1,6 @@ # --- # HLF CA CLI Services - # Stop all CLI Services services - name: Stop CLI Service - {{ orderer.name }}_cli become: yes @@ -34,13 +33,25 @@ mode: "0500" force: yes -# # Generate the list of swarm managers to be used as Orderer Endpoints in configtx -# - name: Get IP addresses as a list for all swarm manager nodes -# vars: -# _swarm_manager_ip_list: "{{ groups['swarm_managers'] | map('extract', hostvars, ['ansible_host']) | list | join(':{{orderer.port}},') }}" -# __swarm_manager_ip_list: "{{_swarm_manager_ip_list}}:{{orderer.port}}" -# set_fact: -# swarm_manager_ip_list: "{{ __swarm_manager_ip_list.split(',') }}" +# Generate the list of swarm managers to be used as Orderer Endpoints in configtx +- name: Get IP addresses as a list for all swarm manager nodes + vars: + _swarm_manager_ip_list: "{{ groups['swarm_managers'] | map('extract', hostvars, ['ansible_host']) | list | join(':{{orderer.port}},') }}" + __swarm_manager_ip_list: "{{_swarm_manager_ip_list}}:{{orderer.port}}" + set_fact: + swarm_manager_ip_list: "{{ __swarm_manager_ip_list.split(',') }}" + +# Generate the list of swarm managers to be used in RAFT Consenters in configtx +- name: Build a list of all consenter + set_fact: + Consenters: "{{ Consenters }} + [ {{ senter }} ]" + vars: + senter: {Host: "{{item}}", Port: "{{orderer.port}}",ClientTLSCert: "{{orderer.path}}/msp/tls/server.crt",ServerTLSCert: "{{orderer.path}}/msp/tls/server.crt"} + loop: "{{groups['swarm_managers'] | map('extract', hostvars, ['ansible_host']) | list}}" + +- name: Get IP addresses as a list for all swarm manager nodes to be used as anchor ips + set_fact: + swarm_manager_ip_list_anchor: "{{ groups['swarm_managers'] | map('extract', hostvars, ['ansible_host']) | list }}" # Copy relevent config files to mount directories for the docker services - name: Config templating configtx.yaml @@ -70,13 +81,13 @@ # Copy tls certs - name: Copy TLS certs copy: - src: "/root/hlft-store/{{tlsca.name}}/{{orderer.name}}/tls-msp/{{item[0]}}" + src: "/root/hlft-store/{{tlsca.name}}/{{item[0]}}" dest: "/root/hlft-store/{{orgca.name}}/{{orderer.name}}/msp/tls/{{item[1]}}" remote_src: yes loop: - - ["tlscacerts/tls-{{tlsca.name}}-7054.pem", "ca.crt"] - - ["signcerts/cert.pem", "server.crt"] - - ["keystore/key.pem", "server.key"] + - ["tls-cert.pem", "ca.crt"] + - ["{{orderer.name}}/tls-msp/signcerts/cert.pem", "server.crt"] + - ["{{orderer.name}}/tls-msp/keystore/key.pem", "server.key"] # Create ORG MSP folder and subfolders - name: Clean org MSP-folder @@ -111,9 +122,9 @@ dest: "/root/hlft-store/{{org.name}}MSP/{{item[1]}}" remote_src: yes loop: - - ["{{tlsca.name}}/{{orderer.name}}/tls-msp/tlscacerts/tls-{{tlsca.name}}-7054.pem", "tlscacerts/tls-{{tlsca.name}}-7054.pem"] - - ["{{orgca.name}}/{{orderer.name}}/msp/admincerts/{{admin_user}}-cert.pem", "admincerts/{{admin_user}}-cert.pem"] - - ["{{orgca.name}}/{{orderer.name}}/msp/cacerts/{{orgca.name}}-7054.pem", "cacerts/{{orgca.name}}-7054.pem"] + - ["{{tlsca.name}}/ca-cert.pem", "tlscacerts/{{tlsca.name}}-7054.pem"] + - ["{{orgca.name}}/ca-cert.pem", "cacerts/{{orgca.name}}-7054.pem"] + - ["{{orgca.name}}/{{admin_user}}/msp/signcerts/cert.pem", "admincerts/{{admin_user}}-cert.pem"] # Create & Start service for CLI diff --git a/roles/hlf/cli/peer/files/cli.sh b/roles/hlf/cli/peer/files/cli.sh index ea47824..eb8f13c 100644 --- a/roles/hlf/cli/peer/files/cli.sh +++ b/roles/hlf/cli/peer/files/cli.sh @@ -3,16 +3,22 @@ EXIT_CODE=0 if (($IDX == 0)); then CORE_PEER_MSPCONFIGPATH=/root/${AGENT_HOST}/msp # Create the application channel - CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH peer channel create -c appchannel -f /root/${AGENT_HOST}_cli/artifacts/appchannel.tx -o ${ORDERER_HOST}:7050 --outputBlock /root/${AGENT_HOST}_cli/artifacts/appchannel.block --tls --cafile $CORE_PEER_TLS_ROOTCERT_FILE || EXIT_CODE=$? + CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH peer channel create -c appchannel -f /root/${AGENT_HOST}_cli/artifacts/appchannel.tx -o ${ORDERER_HOST}:7050 --outputBlock /root/${AGENT_HOST}_cli/artifacts/appchannel.block --tls --cafile /root/${AGENT_HOST}/msp/tls/ca.crt --clientauth --certfile /root/${AGENT_HOST}/msp/tls/server.crt --keyfile /root/${AGENT_HOST}/msp/tls/server.key || EXIT_CODE=$? - #Update the channel with anchor peers - CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH peer channel update -o ${ORDERER_HOST}:7050 -c appchannel -f /root/${AGENT_HOST}_cli/artifacts/appchannel_anchor.tx --tls --cafile $CORE_PEER_TLS_ROOTCERT_FILE || EXIT_CODE=$? + #Update the channel with anchor peers + CORE_PEER_TLS_ROOTCERT_FILE=$CORE_PEER_TLS_ROOTCERT_FILE CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH peer channel update -o ${ORDERER_HOST}:7050 -c appchannel -f /root/${AGENT_HOST}_cli/artifacts/appchannel_anchor.tx --tls --cafile /root/${AGENT_HOST}/msp/tls/ca.crt --clientauth --certfile /root/${AGENT_HOST}/msp/tls/server.crt --keyfile /root/${AGENT_HOST}/msp/tls/server.key || EXIT_CODE=$? +else + # We we have the IDX 1 running, we wait for 5 secs first + sleep 5s; fi CORE_PEER_MSPCONFIGPATH=/root/${ADMIN_USER}/msp +CORE_PEER_TLS_CLIENTAUTHREQUIRED=true +CORE_PEER_TLS_CLIENTCERT_FILE=/root/${AGENT_HOST}/msp/tls/server.crt #fully qualified path of the client certificate +CORE_PEER_TLS_CLIENTKEY_FILE=/root/${AGENT_HOST}/msp/tls/server.key #fully qualified path of the client private key # Join the peers to the application channel -CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH peer channel join -b /root/${AGENT_HOST}_cli/artifacts/appchannel.block +CORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer channel join -b /root/${AGENT_HOST}_cli/artifacts/appchannel.block || EXIT_CODE=$? echo $EXIT_CODE # while true; do # sleep 0.1 -# done \ No newline at end of file +# doneCORE_PEER_MSPCONFIGPATH=$CORE_PEER_MSPCONFIGPATH CORE_PEER_TLS_CLIENTAUTHREQUIRED=$CORE_PEER_TLS_CLIENTAUTHREQUIRED CORE_PEER_TLS_CLIENTCERT_FILE=$CORE_PEER_TLS_CLIENTCERT_FILE CORE_PEER_TLS_CLIENTKEY_FILE=$CORE_PEER_TLS_CLIENTKEY_FILE peer channel join -b /root/${AGENT_HOST}_cli/artifacts/appchannel.block --ordererTLSHostnameOverride 165.232.76.37 \ No newline at end of file diff --git a/roles/hlf/newOrg/add_new_org_artifacts/tasks/main.yaml b/roles/hlf/newOrg/add_new_org_artifacts/tasks/main.yaml new file mode 100644 index 0000000..7402cea --- /dev/null +++ b/roles/hlf/newOrg/add_new_org_artifacts/tasks/main.yaml @@ -0,0 +1,29 @@ +# --- +- name: Clean the import directory if present + file: + path: "/root/hlft-store/new_org_artifacts" + state: absent + +- name: Create the import directory + file: + path: "/root/hlft-store/new_org_artifacts" + state: directory + +- name: Copy new org artifact to remote machine + copy: + src: "{{artifact_path}}" + dest: "/root/hlft-store/new_org_artifacts/artifact.tgz" + +- name: Extract /root/hlft-store/new_org_artifacts/artifact.tgz into /root/hlft-store/new_org_artifacts/ + unarchive: + src: /root/hlft-store/new_org_artifacts/artifact.tgz + dest: /root/hlft-store/new_org_artifacts + remote_src: yes + +- name: Remove the archive /root/hlft-store/new_org_artifacts/artifact.tgz + file: + path: "/root/hlft-store/new_org_artifacts/artifact.tgz" + state: absent + +- debug: + msg: "Log into CLI and do the rest." diff --git a/roles/hlf/newOrg/gen_new_org_artifacts/tasks/main.yaml b/roles/hlf/newOrg/gen_new_org_artifacts/tasks/main.yaml new file mode 100644 index 0000000..e3c878f --- /dev/null +++ b/roles/hlf/newOrg/gen_new_org_artifacts/tasks/main.yaml @@ -0,0 +1,96 @@ +# --- +- name: Clean the export directory if present + file: + path: "/root/hlft-store/{{org.name}}_export" + state: absent + +- name: Create an export directory to be used for sending the relevent information for adding this organization to the existing hlf blockchain consortium + file: + path: "/root/hlft-store/{{org.name}}_export" + state: directory + +# Generate the list of swarm managers to be used as Orderer Endpoints in configtx +- name: Get IP addresses as a list for all swarm manager nodes + vars: + _swarm_manager_ip_list: "{{ groups['swarm_managers'] | map('extract', hostvars, ['ansible_host']) | list | join(':{{orderer.port}},') }}" + __swarm_manager_ip_list: "{{_swarm_manager_ip_list}}:{{orderer.port}}" + set_fact: + swarm_manager_ip_list: "{{ __swarm_manager_ip_list.split(',') }}" + +- name: Get IP addresses as a list for all swarm manager nodes to be used as anchor ips + set_fact: + swarm_manager_ip_list_anchor: "{{ groups['swarm_managers'] | map('extract', hostvars, ['ansible_host']) | list }}" + + # Copy relevent config files to mount directories for the docker services +- name: Config templating configtx_newOrg.yaml + become: yes + template: + src: "configtx_newOrg.yaml.j2" + dest: "/root/hlft-store/{{org.name}}_export/configtx.yaml" + mode: 0660 + force: yes + +# Prep the TLS certs +- name: Create tls folder under /root/hlft-store/{{org.name}}_export/tls + become: yes + file: + path: "/root/hlft-store/{{org.name}}_export/tls" + state: directory + mode: '0755' + +# Copy tls certs +- name: Copy TLS certs + copy: + src: "/root/hlft-store/{{tlsca.name}}/{{orderer.name}}/tls-msp/{{item[0]}}" + dest: "/root/hlft-store/{{org.name}}_export/tls/{{item[1]}}" + remote_src: yes + loop: + - ["tlscacerts/tls-{{tlsca.name}}-7054.pem", "ca.crt"] + - ["signcerts/cert.pem", "server.crt"] + +- name: Create org MSP-folder + become: yes + file: + path: "/root/hlft-store/{{org.name}}_export/msp" + state: directory + mode: '0755' + +- name: Create subfolders folder under /root/hlft-store/{{org.name}}_export/msp + become: yes + file: + path: "/root/hlft-store/{{org.name}}_export/msp/{{item}}" + state: directory + mode: '0755' + loop: + - "tlscacerts" + - "admincerts" + - "cacerts" + - "users" + +- name: Copy certs in the msp subfolder + copy: + src: "/root/hlft-store/{{item[0]}}" + dest: "/root/hlft-store/{{org.name}}_export/msp/{{item[1]}}" + remote_src: yes + loop: + - ["{{tlsca.name}}/ca-cert.pem", "tlscacerts/{{tlsca.name}}-7054.pem"] + - ["{{orgca.name}}/ca-cert.pem", "cacerts/{{orgca.name}}-7054.pem"] + - ["{{orgca.name}}/{{admin_user}}/msp/signcerts/cert.pem", "admincerts/{{admin_user}}-cert.pem"] + + +- name: Compress the export folder + archive: + path: "/root/hlft-store/{{org.name}}_export/" + dest: "/root/hlft-store/{{org.name}}_export.tgz" + +- name: Fetch the exported folder to your local machine. Send it out to the organization that invited you to be part of the blockchain + fetch: + src: "/root/hlft-store/{{org.name}}_export.tgz" + dest: "/tmp/{{org.name}}_export.tgz" + flat: yes + +- name: Remove the compress file from the remote machine + file: + path: "/root/hlft-store/{{org.name}}_export.tgz" + state: absent + diff --git a/roles/hlf/orderer/tasks/main.yml b/roles/hlf/orderer/tasks/main.yml index a49d0a6..dfc3b54 100644 --- a/roles/hlf/orderer/tasks/main.yml +++ b/roles/hlf/orderer/tasks/main.yml @@ -9,6 +9,23 @@ networks: - "{{swarm_network}}" +- name: Clean the tlscacerts directory in MSP + file: + path: /root/hlft-store/{{orgca.name}}/{{orderer.name}}/msp/tlscacerts + state: absent + +- name: Create the tlscacerts directory in MSP + file: + path: /root/hlft-store/{{orgca.name}}/{{orderer.name}}/msp/tlscacerts + state: directory + +- name: Copy tlscacerts + copy: + src: /root/hlft-store/{{tlsca.name}}/{{orderer.name}}/tls-msp/tlscacerts/tls-{{tlsca.name}}-7054.pem + dest: /root/hlft-store/{{orgca.name}}/{{orderer.name}}/msp/tlscacerts/{{tlsca.name}}.{{org.name}}-cert.crt + remote_src: yes + + # Create & Start service orderer with RAFT enabled - name: Start the fabric orderer become: yes @@ -27,6 +44,10 @@ - source: "/root/hlft-store/{{orderer.name}}_cli/artifacts/genesis.block" target: "{{orderer.path}}/genesis.block" type: bind + # ROOT TLSCA + - source: "/root/hlft-store/{{tlsca.name}}/tls-cert.pem" + target: "{{orderer.path}}/tls-cert.pem" + type: bind publish: - published_port: "{{orderer.port}}" target_port: "7050" @@ -46,7 +67,7 @@ - "ORDERER_GENERAL_TLS_CERTIFICATE={{orderer.path}}/msp/tls/server.crt" #fully qualified path of the file that contains the server certificate - "ORDERER_GENERAL_TLS_ROOTCAS=[{{orderer.path}}/msp/tls/ca.crt]" #fully qualified path of the file that contains the certificate chain of the CA that issued TLS server certificate - "ORDERER_GENERAL_TLS_CLIENTAUTHREQUIRED=false" - # - "ORDERER_GENERAL_TLS_CLIENTROOTCAS=tba" #fully qualified path of the file that contains the certificate chain of the CA that issued TLS server certificate + - "ORDERER_GENERAL_TLS_CLIENTROOTCAS=[{{orderer.path}}/msp/tls/ca.crt]" #fully qualified path of the file that contains the certificate chain of the CA that issued TLS server certificate - "ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE={{orderer.path}}/msp/tls/server.crt" - "ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY={{orderer.path}}/msp/tls/server.key" - "ORDERER_GENERAL_CLUSTER_ROOTCAS=[{{orderer.path}}/msp/tls/ca.crt]" diff --git a/roles/hlf/peer/tasks/main.yml b/roles/hlf/peer/tasks/main.yml index f2af67d..5782e62 100644 --- a/roles/hlf/peer/tasks/main.yml +++ b/roles/hlf/peer/tasks/main.yml @@ -39,7 +39,25 @@ - [["tlscacerts/tls-{{tlsca.name}}-7054.pem", "ca.crt"], ["signcerts/cert.pem", "server.crt"], ["keystore/key.pem", "server.key"]] - + +- name: Clean the tlscacerts directory in MSP + file: + path: /root/hlft-store/{{orgca.name}}/{{item.name}}/map/tlscacerts + state: absent + loop: "{{peerservices}}" + +- name: Create the tlscacerts directory in MSP + file: + path: /root/hlft-store/{{orgca.name}}/{{item.name}}/msp/tlscacerts + state: directory + loop: "{{peerservices}}" + +- name: Copy tlscacerts + copy: + src: /root/hlft-store/{{tlsca.name}}/{{item.name}}/tls-msp/tlscacerts/tls-{{tlsca.name}}-7054.pem + dest: /root/hlft-store/{{orgca.name}}/{{item.name}}/msp/tlscacerts/{{tlsca.name}}.{{org.name}}-cert.crt + remote_src: yes + loop: "{{peerservices}}" # Create & Start services for Peers - name: Fabric Service - {{ item }} @@ -84,9 +102,9 @@ - "CORE_PEER_TLS_KEY_FILE={{item.path}}/msp/tls/server.key" #fully qualified path of the server private key - "CORE_PEER_TLS_ROOTCERT_FILE={{item.path}}/msp/tls/ca.crt" #fully qualified path of the CA chain file - "CORE_PEER_TLS_CLIENTAUTHREQUIRED=false" - # - "CORE_PEER_TLS_CLIENTROOTCAS_FILES=tba" #fully qualified path of the CA chain file - # - "CORE_PEER_TLS_CLIENTCERT_FILE=tba" #fully qualified path of the client certificate - # - "CORE_PEER_TLS_CLIENTKEY_FILE=tba" #fully qualified path of the client private key + - "CORE_PEER_TLS_CLIENTROOTCAS_FILES={{item.path}}/msp/tls/ca.crt" #fully qualified path of the CA chain file + - "CORE_PEER_TLS_CLIENTCERT_FILE={{item.path}}/msp/tls/server.crt" #fully qualified path of the client certificate + - "CORE_PEER_TLS_CLIENTKEY_FILE={{item.path}}/msp/tls/server.key" #fully qualified path of the client private key - "CORE_PEER_GOSSIP_USELEADERELECTION=true" - "CORE_PEER_GOSSIP_ORGLEADER=false" - "CORE_PEER_GOSSIP_EXTERNALENDPOINT={{item.name}}:7051" diff --git a/start_all_services.sh b/start_all_services.sh index 020e097..a6bb212 100644 --- a/start_all_services.sh +++ b/start_all_services.sh @@ -1,14 +1,14 @@ #!/bin/bash set -x #echo on -ansible-playbook -v 011.initialize_hosts.yml -u root && -ansible-playbook -v 012.prepare_docker_images.yml -u root && -ansible-playbook -v 013.mount_fs.yml -u root && -ansible-playbook -v 014.spawn_swarm.yml -u root && -ansible-playbook -v 015.deploy_swarm_visualizer.yml --flush-cache -u root && -ansible-playbook -v 016.deploy_portainer.yml --flush-cache -u root && -ansible-playbook -v 100.deploy_ca.yml --flush-cache -u root && sleep 15 && -ansible-playbook -v 101.deploy_orderer.yml --flush-cache -u root && sleep 10 && -ansible-playbook -v 102.deploy_peers.yml --flush-cache -u root && sleep 10 && -ansible-playbook -v 103.deploy_cli.yml --flush-cache -u root && sleep 10 && -ansible-playbook -v 104.deploy_hlf_explorer.yml --flush-cache -u root \ No newline at end of file +ansible-playbook -v 011.initialize_hosts.yml -u root; +ansible-playbook -v 012.prepare_docker_images.yml -u root; +ansible-playbook -v 013.mount_fs.yml -u root; +ansible-playbook -v 014.spawn_swarm.yml -u root; +ansible-playbook -v 015.deploy_swarm_visualizer.yml --flush-cache -u root; +ansible-playbook -v 016.deploy_portainer.yml --flush-cache -u root; +ansible-playbook -v 100.deploy_ca.yml --flush-cache -u root; +ansible-playbook -v 101.deploy_orderer.yml --flush-cache -u root; +ansible-playbook -v 102.deploy_peers.yml --flush-cache -u root; +ansible-playbook -v 103.deploy_cli.yml --flush-cache -u root; +ansible-playbook -v 104.deploy_hlf_explorer.yml --flush-cache -u root; \ No newline at end of file diff --git a/start_hlf_services.sh b/start_hlf_services.sh old mode 100644 new mode 100755 index 6edb1c3..353916a --- a/start_hlf_services.sh +++ b/start_hlf_services.sh @@ -1,8 +1,8 @@ #!/bin/bash set -x #echo on -ansible-playbook -v 100.deploy_ca.yml --flush-cache -u root && sleep 15 && -ansible-playbook -v 101.deploy_orderer.yml --flush-cache -u root && sleep 10 && -ansible-playbook -v 102.deploy_peers.yml --flush-cache -u root && sleep 10 && -ansible-playbook -v 103.deploy_cli.yml --flush-cache -u root && sleep 10 && -ansible-playbook -v 104.deploy_hlf_explorer.yml --flush-cache -u root \ No newline at end of file +ansible-playbook -v 100.deploy_ca.yml --flush-cache -u root -i inventory/hosts_org1; +ansible-playbook -v 101.deploy_orderer.yml --flush-cache -u root -i inventory/hosts_org1; +ansible-playbook -v 102.deploy_peers.yml --flush-cache -u root -i inventory/hosts_org1; +ansible-playbook -v 103.deploy_cli.yml --flush-cache -u root -i inventory/hosts_org1; +#ansible-playbook -v 104.deploy_hlf_explorer.yml --flush-cache -u root; \ No newline at end of file diff --git a/templates/configtx.yaml.j2 b/templates/configtx.yaml.j2 index 8843147..997a81a 100644 --- a/templates/configtx.yaml.j2 +++ b/templates/configtx.yaml.j2 @@ -16,12 +16,16 @@ Organizations: # SampleOrg defines an MSP using the sampleconfig. It should never be used # in production but may be used as a template for other definitions. - - &org1{{org.name}} + - &org{{org.name}} # Name is the key by which this org will be referenced in channel # configuration transactions. # Name can include alphanumeric characters as well as dots and dashes. Name: {{org.name}}MSP + # ID is the key by which this org's MSP definition will be referenced. + # ID can include alphanumeric characters as well as dots and dashes. + ID: {{org.name}}MSP + # SkipAsForeign can be set to true for org definitions which are to be # inherited from the orderer system channel during channel creation. This # is especially useful when an admin of a single org without access to the @@ -29,10 +33,7 @@ Organizations: # this property must always be set to false for orgs included in block # creation. SkipAsForeign: false - - # ID is the key by which this org's MSP definition will be referenced. - # ID can include alphanumeric characters as well as dots and dashes. - ID: {{org.name}}MSP + # MSPDir is the filesystem path which contains the MSP configuration. MSPDir: /root/{{org.name}}MSP @@ -63,16 +64,19 @@ Organizations: # OrdererEndpoints is a list of all orderers this org runs which clients # and peers may to connect to to push transactions and receive blocks respectively. - #OrdererEndpoints: swarm_manager_ip_list - OrdererEndpoints: - - {{orderer.name}}:7050 + OrdererEndpoints: + {% for endpoint in swarm_manager_ip_list %} + - {{endpoint}} + {% endfor %} # AnchorPeers defines the location of peers which can be used for # cross-org gossip communication. Note, this value is only encoded in # the genesis block in the Application section context. AnchorPeers: - - Host: {{orderer.anchorpeer}} - Port: 7051 + {% for endpoint in swarm_manager_ip_list_anchor %} + - Host: {{endpoint}} + Port: {{orderer.anchorport}} + {% endfor %} ################################################################################ # @@ -327,10 +331,13 @@ Orderer: &OrdererDefaults # a subset of the host:port items enumerated in this list should be # replicated under the Orderer.Addresses key above. Consenters: - - Host: {{orderer.name}} - Port: {{orderer.port}} - ClientTLSCert: {{orderer.path}}/msp/tls/server.crt - ServerTLSCert: {{orderer.path}}/msp/tls/server.crt + {% for consenter in Consenters %} + - Host: {{consenter.Host}} + Port: {{consenter.Port}} + ClientTLSCert: {{consenter.ClientTLSCert}} + ServerTLSCert: {{consenter.ServerTLSCert}} + {% endfor %} + # Options to be specified for all the etcd/raft nodes. The values here # are the defaults for all new channels and can be modified on a # per-channel basis via configuration updates. @@ -441,11 +448,11 @@ Profiles: Orderer: <<: *OrdererDefaults Organizations: - - *org1{{org.name}} + - *org{{org.name}} Consortiums: SampleConsortium: Organizations: - - *org1{{org.name}} + - *org{{org.name}} # SampleSingleMSPKafka defines a configuration that differs from the # SampleSingleMSPSolo one only in that it uses the Kafka-based orderer. @@ -455,11 +462,11 @@ Profiles: <<: *OrdererDefaults OrdererType: kafka Organizations: - - *org1{{org.name}} + - *org{{org.name}} Consortiums: SampleConsortium: Organizations: - - *org1{{org.name}} + - *org{{org.name}} # SampleInsecureSolo defines a configuration which uses the Solo orderer, # contains no MSP definitions, and allows all transactions and channel @@ -493,7 +500,7 @@ Profiles: Orderer: <<: *OrdererDefaults Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} Policies: <<: *SampleOrgPolicies Admins: @@ -502,7 +509,7 @@ Profiles: Application: <<: *ApplicationDefaults Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} Policies: <<: *SampleOrgPolicies Admins: @@ -511,7 +518,7 @@ Profiles: Consortiums: SampleConsortium: Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} Policies: <<: *SampleOrgPolicies Admins: @@ -526,7 +533,7 @@ Profiles: <<: *OrdererDefaults OrdererType: kafka Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} Policies: <<: *SampleOrgPolicies Admins: @@ -535,7 +542,7 @@ Profiles: Application: <<: *ApplicationDefaults Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} Policies: <<: *SampleOrgPolicies Admins: @@ -544,7 +551,7 @@ Profiles: Consortiums: SampleConsortium: Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} Policies: <<: *SampleOrgPolicies Admins: @@ -562,7 +569,7 @@ Profiles: Application: <<: *ApplicationDefaults Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} # SampleDevModeEtcdRaft defines a configuration that differs from the # SampleDevModeSolo one only in that it uses the etcd/raft-based orderer. @@ -572,7 +579,7 @@ Profiles: <<: *OrdererDefaults OrdererType: etcdraft Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} Policies: <<: *SampleOrgPolicies Admins: @@ -581,7 +588,7 @@ Profiles: Application: <<: *ApplicationDefaults Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} Policies: <<: *SampleOrgPolicies Admins: @@ -590,7 +597,7 @@ Profiles: Consortiums: SampleConsortium: Organizations: - - <<: *org1{{org.name}} + - <<: *org{{org.name}} Policies: <<: *SampleOrgPolicies Admins: diff --git a/templates/configtx_newOrg.yaml.j2 b/templates/configtx_newOrg.yaml.j2 new file mode 100644 index 0000000..6dcc9fa --- /dev/null +++ b/templates/configtx_newOrg.yaml.j2 @@ -0,0 +1,61 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +--- +################################################################################ +# +# Section: Organizations +# +# - This section defines the different organizational identities which will +# be referenced later in the configuration. +# +################################################################################ +Organizations: + - &org{{org.name}} + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: {{org.name}}MSP + + # ID to load the MSP definition as + ID: {{org.name}}MSP + + # SkipAsForeign can be set to true for org definitions which are to be + # inherited from the orderer system channel during channel creation. This + # is especially useful when an admin of a single org without access to the + # MSP directories of the other orgs wishes to create a channel. Note + # this property must always be set to false for orgs included in block + # creation. + SkipAsForeign: false + + MSPDir: /root/CLI/new_org_artifacts/msp + + Policies: &SampleOrgPolicies + Readers: + Type: Signature + Rule: "OR('{{org.name}}MSP.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('SampleOrg.admin', 'SampleOrg.peer', 'SampleOrg.client')" + Writers: + Type: Signature + Rule: "OR('{{org.name}}MSP.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('SampleOrg.admin', 'SampleOrg.client')" + Admins: + Type: Signature + Rule: "OR('{{org.name}}MSP.admin')" + Endorsement: + Type: Signature + Rule: "OR('{{org.name}}MSP.member')" + + # AnchorPeers defines the location of peers which can be used for + # cross-org gossip communication. Note, this value is only encoded in + # the genesis block in the Application section context. + AnchorPeers: + {% for endpoint in swarm_manager_ip_list_anchor %} + - Host: {{endpoint}} + Port: {{orderer.anchorport}} + {% endfor %} \ No newline at end of file diff --git a/test.yml b/test.yml index a7b2eea..2ffa40d 100644 --- a/test.yml +++ b/test.yml @@ -1,9 +1,15 @@ --- - name: Test Playbook - hosts: all - gather_facts: true + hosts: swarm_manager_prime + gather_facts: no + vars: + Consenters: [] tasks: - - name: Test hosts list - debug: - msg: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" - \ No newline at end of file + - name: Build a list for all --csr.hosts + vars: + csrhostslist: "{{ caservices | map(attribute='name') | list + peerservices | map(attribute='name') | list + [ orderer.name ] + [ cli.name ] + ['localhost'] + groups['swarm_managers'] | map('extract', hostvars, ['ansible_host']) | list }}" + set_fact: + csrhosts: "{{csrhostslist | join(',')}}" + + - debug: + msg: "{{csrhosts}}" \ No newline at end of file