diff --git a/deploy/ansible/playbooks/iroha-k8s/README.md b/deploy/ansible/playbooks/iroha-k8s/README.md new file mode 100644 index 0000000000..4f6dbcda1a --- /dev/null +++ b/deploy/ansible/playbooks/iroha-k8s/README.md @@ -0,0 +1,30 @@ +# To use: + +``` +pip3 install sha3, future +ansible-playbook playbooks/iroha-k8s/main.yml + +``` +* Tested to work on Google Kubernetes Engine + + +# To destroy the k8s environment created by iroha: + +## If you went with the default namespace +``` +kubectl delete -f path/to/iroha-k8s-peer-keys.yml \ + -f path/to/iroha-k8s-services.yml \ + -f path/to/iroha-k8s-configmap.yml \ + -f path/to/iroha-k8s.yml +``` + +## If you deployed with a custom namespace +``` +kubectl delete namespace +kubectl delete service +``` +e.g. based on default config +``` +kubectl delete namespace iroha-network +kubectl delete service iroha-peer +``` diff --git a/deploy/ansible/playbooks/iroha-k8s/group_vars/all.yml b/deploy/ansible/playbooks/iroha-k8s/group_vars/all.yml index d8c3a58a14..e69de29bb2 100644 --- a/deploy/ansible/playbooks/iroha-k8s/group_vars/all.yml +++ b/deploy/ansible/playbooks/iroha-k8s/group_vars/all.yml @@ -1,4 +0,0 @@ -replicas: 4 -iroha_port: 50051 -pod_basename: iroha -service_name: iroha diff --git a/deploy/ansible/playbooks/iroha-k8s/iroha-deploy.yml b/deploy/ansible/playbooks/iroha-k8s/iroha-deploy.yml deleted file mode 100644 index 7168375cc3..0000000000 --- a/deploy/ansible/playbooks/iroha-k8s/iroha-deploy.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - - hosts: localhost - connection: local - roles: - - { role: iroha-k8s, tags: iroha-k8s } diff --git a/deploy/ansible/playbooks/iroha-k8s/main.yml b/deploy/ansible/playbooks/iroha-k8s/main.yml new file mode 100644 index 0000000000..73e2429f0f --- /dev/null +++ b/deploy/ansible/playbooks/iroha-k8s/main.yml @@ -0,0 +1,7 @@ +--- + - hosts: localhost + connection: local + roles: + - { role: iroha-k8s, tags: [] } + + # TODO: tag each/most tasks and assign here so tasks can be selectively performed \ No newline at end of file diff --git a/deploy/ansible/playbooks/iroha-k8s/scripts/ed25519-cli b/deploy/ansible/playbooks/iroha-k8s/scripts/ed25519-cli deleted file mode 100755 index 549c13b952..0000000000 Binary files a/deploy/ansible/playbooks/iroha-k8s/scripts/ed25519-cli and /dev/null differ diff --git a/deploy/ansible/playbooks/iroha-k8s/scripts/genesis-add-peers.py b/deploy/ansible/playbooks/iroha-k8s/scripts/genesis-add-peers.py deleted file mode 100644 index adc0eedc39..0000000000 --- a/deploy/ansible/playbooks/iroha-k8s/scripts/genesis-add-peers.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/env/python3 -import json, csv, sys, base64 -''' -peers.csv -host;port;priv_key_b64_encoded;pub_key_b64_encoded -''' - -class Peer: - def __init__(self, host, port, priv_key, pub_key): - self.host = host - self.port = port - self.priv_key = priv_key - self.pub_key = pub_key - -def parse_peers(peers_csv_fp): - peers = [] - with open(peers_csv_fp) as csvfile: - peersreader = csv.reader(csvfile, delimiter=';') - next(peersreader, None) # skip the header - for peer in peersreader: - peers.append(Peer(peer[0], peer[1], peer[3], peer[2])) - return peers - -def genesis_add_peers(peers_list, genesis_block_fp): - with open(genesis_block_fp, 'r+') as genesis_json: - genesis_dict = json.load(genesis_json) - try: - genesis_dict['blockV1']['payload']['transactions'][0]['payload']['reducedPayload']['commands'] = filter(lambda c: not c.get('addPeer'), genesis_dict['blockV1']['payload']['transactions'][0]['payload']['reducedPayload']['commands']) - except KeyError: - pass - genesis_dict['blockV1']['payload']['transactions'][0]['payload']['reducedPayload']['commands'] = list(genesis_dict['blockV1']['payload']['transactions'][0]['payload']['reducedPayload']['commands']) - for p in peers_list: - p_add_command = {"addPeer": {"peer": {"address": "%s:%s" % (p.host, '10001'), "peerKey": p.pub_key}}} - genesis_dict['blockV1']['payload']['transactions'][0]['payload']['reducedPayload']['commands'].append(p_add_command) - genesis_json.seek(0) - json.dump(genesis_dict, genesis_json, sort_keys=True) - genesis_json.truncate() - -def caliper_add_peers(peers_list, caliper_conf_fp): - with open(caliper_conf_fp, 'r+') as caliper_conf_json: - caliper_conf_dict = json.load(caliper_conf_json) - try: - caliper_conf_dict['iroha']['network'] = {} - except KeyError: - pass - for i, p in enumerate(peers_list): - p_node = {"node%s" % i: {"torii": "%s:%s" % (p.host, p.port)}} - caliper_conf_dict['iroha']['network'].update(p_node) - caliper_conf_json.seek(0) - json.dump(caliper_conf_dict, caliper_conf_json, sort_keys=True) - caliper_conf_json.truncate() - -def caliper_rename_keys(priv_key_name, pub_key_name, caliper_conf_fp): - with open(caliper_conf_fp, 'r+') as caliper_conf_json: - caliper_conf_dict = json.load(caliper_conf_json) - caliper_conf_dict['iroha']['admin']['key-pub'] = "network/iroha/simplenetwork/%s" % pub_key_name - caliper_conf_dict['iroha']['admin']['key-priv'] = "network/iroha/simplenetwork/%s" % priv_key_name - caliper_conf_json.seek(0) - json.dump(caliper_conf_dict, caliper_conf_json, sort_keys=True) - caliper_conf_json.truncate() - -def to_b64(bytes_array): - return base64.b64encode(bytes_array).decode('utf-8') - -def print_keys_b64(peers): - for peer in peers: - priv_key = peer.priv_key.encode() - pub_key = peer.pub_key.encode() - print(to_b64(priv_key) + ',' + to_b64(pub_key)) - -if __name__ == "__main__": - command = sys.argv[1] - peers_csv = sys.argv[2] - try: - json_conf = sys.argv[3] - except IndexError: - pass - peers = parse_peers(peers_csv) - if command == 'add_iroha_peers': - genesis_add_peers(peers, json_conf) - elif command == 'add_caliper_peers': - caliper_add_peers(peers, json_conf) - caliper_rename_keys('admin-test.priv', 'admin-test.pub', json_conf) - elif command == 'print_keys_b64': - print_keys_b64(peers) - else: - print('Invalid command') diff --git a/deploy/ansible/roles/iroha-k8s/README.md b/deploy/ansible/roles/iroha-k8s/README.md deleted file mode 100644 index 377d6686ef..0000000000 --- a/deploy/ansible/roles/iroha-k8s/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# iroha-k8s role -This role is used for generating Iroha node configuration files and keys. They are meant to be deployed in a cluster. It also contains Kubernetes service and pod definitions file that deploys Iroha cluster. - -## Requirements -- Python3 -- ed25519-cli for key generation. Statically linked binary (for x86_64 platform) is already bundled in iroha-k8s Ansible role. Check out [ed25519-cli](https://github.com/Warchant/ed25519-cli) repo for compilation guide for other platforms. - -## Generating configs -``` -ansible-playbook -e 'max_proposal_size=2000 proposal_delay=300 vote_delay=5000' --tags "iroha-k8s" ../playbooks/iroha-caliper/caliper-deploy.yml -``` - -This command generates and stores configuration files in `files/conf` directory under role root. In case you're deploying without using Kubernetes cluster (bare metal or simple Docker containers), you have to copy corresponding key pair on each node (nodeX.{pub,priv}). `genesis.block`, `config.sample` are identitical for each node and have to be copied as well. `entrypoint.sh` is k8s cluster-specific and can be ignored. - -Ansible playbook's extra parameters are used for `config.sample` file generation. - -## Deploying on k8s cluster -In order to deploy Iroha cluster using generated configs you must first create *configMap*. Being created on a single master node, it then distributed on each cluster node. -``` -kubectl create configmap iroha-config --from-file=files/conf/ -``` - -We're ready to deploy Iroha cluster: -``` -kubectl create -f files/k8s-iroha.yaml -kubectl create -f files/k8s-peer-keys.yaml -``` - -You should see all the pods are in `Running` state after Docker images are downloaded and run on every node. Check the status with `kubectl get pods` command. diff --git a/deploy/ansible/roles/iroha-k8s/defaults/main.yml b/deploy/ansible/roles/iroha-k8s/defaults/main.yml index f31d25155d..16d95e784f 100644 --- a/deploy/ansible/roles/iroha-k8s/defaults/main.yml +++ b/deploy/ansible/roles/iroha-k8s/defaults/main.yml @@ -1,9 +1,23 @@ -# config.sample -max_proposal_size: 3000 -proposal_delay: 300 -vote_delay: 5000 -load_delay: 5000 -# k8s-iroha.yaml -iroha_image: hyperledger/iroha:develop +iroha_block_store_path: "/tmp/block-store/" +iroha_internal_port: 10001 +iroha_torii_port: 50051 +iroha_pg_opt: "host=localhost port=5432 user=postgres password=mysecretpassword" +iroha_max_proposal_size: 10 +iroha_proposal_delay: 5000 +iroha_vote_delay: 5000 +iroha_mst_enable: 'true' +iroha_mst_expiration_time: 1440 # 24 hours; default; + +iroha_pod_basename: iroha-peer +iroha_governing_service_domain_name: iroha # https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id +iroha_replicas: 8 # Minimum number of peers is 6 (5f+1) for consensus to work properly. +iroha_image_tag: hyperledger/iroha:1.0.0_rc4 +postgres_image_tag: postgres:11.2-alpine postgres_volume_size: 1Gi blockstore_volume_size: 1Gi +iroha_internal_port_name: internal-port +iroha_torii_port_name: torii-port +iroha_configmap_name: iroha-config + +create_custom_namespace: true # TODO: not yet working; set `iroha_namespace` below, e.g `iroha_namespace: default` +iroha_namespace: iroha-peer-network # ignored when `create_custom_namespace`='false' \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/files/conf/config.docker b/deploy/ansible/roles/iroha-k8s/files/conf/config.docker index e8916ac105..4f786d54bf 100644 --- a/deploy/ansible/roles/iroha-k8s/files/conf/config.docker +++ b/deploy/ansible/roles/iroha-k8s/files/conf/config.docker @@ -3,9 +3,9 @@ "torii_port" : 50051, "internal_port" : 10001, "pg_opt" : "host=localhost port=5432 user=postgres password=mysecretpassword", - "max_proposal_size" : 3000, - "proposal_delay" : 300, + "max_proposal_size" : 10, + "proposal_delay" : 5000, "vote_delay" : 5000, - "load_delay" : 5000, - "mst_enable" : false + "mst_enable" : true, + "mst_expiration_time" : 1440 } diff --git a/deploy/ansible/roles/iroha-k8s/files/conf/genesis.block b/deploy/ansible/roles/iroha-k8s/files/conf/genesis.block index 21b2e48ca4..b251622021 100644 --- a/deploy/ansible/roles/iroha-k8s/files/conf/genesis.block +++ b/deploy/ansible/roles/iroha-k8s/files/conf/genesis.block @@ -1 +1 @@ -{"blockV1": {"payload": {"height": "1", "prevBlockHash": "0000000000000000000000000000000000000000000000000000000000000000", "transactions": [{"payload": {"reducedPayload": {"commands": [{"createRole": {"permissions": ["can_add_peer", "can_add_signatory", "can_create_account", "can_create_domain", "can_get_all_acc_ast", "can_get_all_acc_ast_txs", "can_get_all_acc_detail", "can_get_all_acc_txs", "can_get_all_accounts", "can_get_all_signatories", "can_get_all_txs", "can_get_blocks", "can_get_roles", "can_read_assets", "can_remove_signatory", "can_set_quorum"], "roleName": "admin"}}, {"createRole": {"permissions": ["can_add_signatory", "can_get_my_acc_ast", "can_get_my_acc_ast_txs", "can_get_my_acc_detail", "can_get_my_acc_txs", "can_get_my_account", "can_get_my_signatories", "can_get_my_txs", "can_grant_can_add_my_signatory", "can_grant_can_remove_my_signatory", "can_grant_can_set_my_account_detail", "can_grant_can_set_my_quorum", "can_grant_can_transfer_my_assets", "can_receive", "can_remove_signatory", "can_set_quorum", "can_transfer"], "roleName": "user"}}, {"createRole": {"permissions": ["can_add_asset_qty", "can_create_asset", "can_receive", "can_transfer"], "roleName": "money_creator"}}, {"createDomain": {"defaultRole": "user", "domainId": "test"}}, {"createAsset": {"assetName": "coin", "domainId": "test", "precision": 2}}, {"createAccount": {"accountName": "admin", "domainId": "test", "publicKey": "313a07e6384776ed95447710d15e59148473ccfc052a681317a72a69f2a49910"}}, {"createAccount": {"accountName": "test", "domainId": "test", "publicKey": "716fe505f69f18511a1b083915aa9ff73ef36e6688199f3959750db38b8f4bfc"}}, {"appendRole": {"accountId": "admin@test", "roleName": "admin"}}, {"appendRole": {"accountId": "admin@test", "roleName": "money_creator"}}, {"addPeer": {"peer": {"address": "iroha-0.iroha:10001", "peerKey": "c1328b090617992581ca9bc4b2466f58634b067dd345c783e4a1ab02a691302c"}}}, {"addPeer": {"peer": {"address": "iroha-1.iroha:10001", "peerKey": "15c09a6019ace7b98c8a5606a8cbca583d6442e84b5faaf57f97245f3d575ef5"}}}, {"addPeer": {"peer": {"address": "iroha-2.iroha:10001", "peerKey": "f11f7bd883674e7745fb88b8b2ff7e917fac2ebc44f4740bd791a87113169a00"}}}, {"addPeer": {"peer": {"address": "iroha-3.iroha:10001", "peerKey": "87a97b63b30ef48736c19b5e6a50504e4eb57d582861c25f5c9e0a56a22d8dd3"}}}], "quorum": 1}}}], "txNumber": 1}}} \ No newline at end of file +{"block_v1":{"payload":{"height":"1","prevBlockHash":"0000000000000000000000000000000000000000000000000000000000000000","transactions":[{"payload":{"reducedPayload":{"commands":[{"createRole":{"permissions":["can_add_peer","can_add_signatory","can_create_account","can_create_domain","can_get_all_acc_ast","can_get_all_acc_ast_txs","can_get_all_acc_detail","can_get_all_acc_txs","can_get_all_accounts","can_get_all_signatories","can_get_all_txs","can_get_blocks","can_get_roles","can_read_assets","can_remove_signatory","can_set_quorum"],"roleName":"admin"}},{"createRole":{"permissions":["can_add_signatory","can_get_my_acc_ast","can_get_my_acc_ast_txs","can_get_my_acc_detail","can_get_my_acc_txs","can_get_my_account","can_get_my_signatories","can_get_my_txs","can_grant_can_add_my_signatory","can_grant_can_remove_my_signatory","can_grant_can_set_my_account_detail","can_grant_can_set_my_quorum","can_grant_can_transfer_my_assets","can_receive","can_remove_signatory","can_set_quorum","can_transfer"],"roleName":"user"}},{"createRole":{"permissions":["can_add_asset_qty","can_create_asset","can_receive","can_transfer"],"roleName":"money_creator"}},{"createDomain":{"defaultRole":"user","domainId":"test"}},{"createAsset":{"assetName":"coin","domainId":"test","precision":2}},{"createAccount":{"accountName":"admin","domainId":"test","publicKey":"f98baa265831780855e80d0dbe271eb916a89fc7c6078ba55f3f111aec3baf40"}},{"createAccount":{"accountName":"test","domainId":"test","publicKey":"705d21dc33c06f821ae32a2c9c188481471c567028ec999f8027a2b923c6b6aa"}},{"appendRole":{"accountId":"admin@test","roleName":"admin"}},{"appendRole":{"accountId":"admin@test","roleName":"money_creator"}},{"addPeer":{"peer":{"address":"iroha-peer-0.iroha:10001","peerKey":"def1742b8293536ac0ecf3c04e4a7305963dc85e927a9742b5d915fde27e1399"}}},{"addPeer":{"peer":{"address":"iroha-peer-1.iroha:10001","peerKey":"4c84670a4c8b1a9513604986f80dab085d5373bb7bfba9d14ecc3a46fbc8797e"}}},{"addPeer":{"peer":{"address":"iroha-peer-2.iroha:10001","peerKey":"76af9fa68bb3b839f2bab63e67ac77a4f5dcc0d0842bea3787b5f9189ad1136e"}}},{"addPeer":{"peer":{"address":"iroha-peer-3.iroha:10001","peerKey":"94cf1c22325e2d6d4200ce9779833f103c3d2461b6d4684b124ad91b64b79fdb"}}},{"addPeer":{"peer":{"address":"iroha-peer-4.iroha:10001","peerKey":"43d6ae141f277e1309be0f5912a5a879c317f0d91202befd6fe872f49d51c7a2"}}},{"addPeer":{"peer":{"address":"iroha-peer-5.iroha:10001","peerKey":"0f7de3d0cd57a286160571c50ffb9c6e73f2070a58479a21751a12f0863a103e"}}},{"addPeer":{"peer":{"address":"iroha-peer-6.iroha:10001","peerKey":"bc3cec44a09c129532dcf51568fe45bb568f76af48b4cdec85e3728dd438ae93"}}}],"quorum":1}}}],"txNumber":1}}} \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/files/genesis.block b/deploy/ansible/roles/iroha-k8s/files/genesis.block deleted file mode 100644 index 21b2e48ca4..0000000000 --- a/deploy/ansible/roles/iroha-k8s/files/genesis.block +++ /dev/null @@ -1 +0,0 @@ -{"blockV1": {"payload": {"height": "1", "prevBlockHash": "0000000000000000000000000000000000000000000000000000000000000000", "transactions": [{"payload": {"reducedPayload": {"commands": [{"createRole": {"permissions": ["can_add_peer", "can_add_signatory", "can_create_account", "can_create_domain", "can_get_all_acc_ast", "can_get_all_acc_ast_txs", "can_get_all_acc_detail", "can_get_all_acc_txs", "can_get_all_accounts", "can_get_all_signatories", "can_get_all_txs", "can_get_blocks", "can_get_roles", "can_read_assets", "can_remove_signatory", "can_set_quorum"], "roleName": "admin"}}, {"createRole": {"permissions": ["can_add_signatory", "can_get_my_acc_ast", "can_get_my_acc_ast_txs", "can_get_my_acc_detail", "can_get_my_acc_txs", "can_get_my_account", "can_get_my_signatories", "can_get_my_txs", "can_grant_can_add_my_signatory", "can_grant_can_remove_my_signatory", "can_grant_can_set_my_account_detail", "can_grant_can_set_my_quorum", "can_grant_can_transfer_my_assets", "can_receive", "can_remove_signatory", "can_set_quorum", "can_transfer"], "roleName": "user"}}, {"createRole": {"permissions": ["can_add_asset_qty", "can_create_asset", "can_receive", "can_transfer"], "roleName": "money_creator"}}, {"createDomain": {"defaultRole": "user", "domainId": "test"}}, {"createAsset": {"assetName": "coin", "domainId": "test", "precision": 2}}, {"createAccount": {"accountName": "admin", "domainId": "test", "publicKey": "313a07e6384776ed95447710d15e59148473ccfc052a681317a72a69f2a49910"}}, {"createAccount": {"accountName": "test", "domainId": "test", "publicKey": "716fe505f69f18511a1b083915aa9ff73ef36e6688199f3959750db38b8f4bfc"}}, {"appendRole": {"accountId": "admin@test", "roleName": "admin"}}, {"appendRole": {"accountId": "admin@test", "roleName": "money_creator"}}, {"addPeer": {"peer": {"address": "iroha-0.iroha:10001", "peerKey": "c1328b090617992581ca9bc4b2466f58634b067dd345c783e4a1ab02a691302c"}}}, {"addPeer": {"peer": {"address": "iroha-1.iroha:10001", "peerKey": "15c09a6019ace7b98c8a5606a8cbca583d6442e84b5faaf57f97245f3d575ef5"}}}, {"addPeer": {"peer": {"address": "iroha-2.iroha:10001", "peerKey": "f11f7bd883674e7745fb88b8b2ff7e917fac2ebc44f4740bd791a87113169a00"}}}, {"addPeer": {"peer": {"address": "iroha-3.iroha:10001", "peerKey": "87a97b63b30ef48736c19b5e6a50504e4eb57d582861c25f5c9e0a56a22d8dd3"}}}], "quorum": 1}}}], "txNumber": 1}}} \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/files/iroha-k8s-configmap.yml b/deploy/ansible/roles/iroha-k8s/files/iroha-k8s-configmap.yml new file mode 100644 index 0000000000..fb1e95638e --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/files/iroha-k8s-configmap.yml @@ -0,0 +1,20 @@ +apiVersion: v1 +data: + config.docker: | + { + "block_store_path" : "/tmp/block_store/", + "torii_port" : 50051, + "internal_port" : 10001, + "pg_opt" : "host=localhost port=5432 user=postgres password=mysecretpassword", + "max_proposal_size" : 10, + "proposal_delay" : 5000, + "vote_delay" : 5000, + "mst_enable" : true, + "mst_expiration_time" : 1440 + } + genesis.block: '{"block_v1":{"payload":{"height":"1","prevBlockHash":"0000000000000000000000000000000000000000000000000000000000000000","transactions":[{"payload":{"reducedPayload":{"commands":[{"createRole":{"permissions":["can_add_peer","can_add_signatory","can_create_account","can_create_domain","can_get_all_acc_ast","can_get_all_acc_ast_txs","can_get_all_acc_detail","can_get_all_acc_txs","can_get_all_accounts","can_get_all_signatories","can_get_all_txs","can_get_blocks","can_get_roles","can_read_assets","can_remove_signatory","can_set_quorum"],"roleName":"admin"}},{"createRole":{"permissions":["can_add_signatory","can_get_my_acc_ast","can_get_my_acc_ast_txs","can_get_my_acc_detail","can_get_my_acc_txs","can_get_my_account","can_get_my_signatories","can_get_my_txs","can_grant_can_add_my_signatory","can_grant_can_remove_my_signatory","can_grant_can_set_my_account_detail","can_grant_can_set_my_quorum","can_grant_can_transfer_my_assets","can_receive","can_remove_signatory","can_set_quorum","can_transfer"],"roleName":"user"}},{"createRole":{"permissions":["can_add_asset_qty","can_create_asset","can_receive","can_transfer"],"roleName":"money_creator"}},{"createDomain":{"defaultRole":"user","domainId":"test"}},{"createAsset":{"assetName":"coin","domainId":"test","precision":2}},{"createAccount":{"accountName":"admin","domainId":"test","publicKey":"f98baa265831780855e80d0dbe271eb916a89fc7c6078ba55f3f111aec3baf40"}},{"createAccount":{"accountName":"test","domainId":"test","publicKey":"705d21dc33c06f821ae32a2c9c188481471c567028ec999f8027a2b923c6b6aa"}},{"appendRole":{"accountId":"admin@test","roleName":"admin"}},{"appendRole":{"accountId":"admin@test","roleName":"money_creator"}},{"addPeer":{"peer":{"address":"iroha-peer-0.iroha:10001","peerKey":"def1742b8293536ac0ecf3c04e4a7305963dc85e927a9742b5d915fde27e1399"}}},{"addPeer":{"peer":{"address":"iroha-peer-1.iroha:10001","peerKey":"4c84670a4c8b1a9513604986f80dab085d5373bb7bfba9d14ecc3a46fbc8797e"}}},{"addPeer":{"peer":{"address":"iroha-peer-2.iroha:10001","peerKey":"76af9fa68bb3b839f2bab63e67ac77a4f5dcc0d0842bea3787b5f9189ad1136e"}}},{"addPeer":{"peer":{"address":"iroha-peer-3.iroha:10001","peerKey":"94cf1c22325e2d6d4200ce9779833f103c3d2461b6d4684b124ad91b64b79fdb"}}},{"addPeer":{"peer":{"address":"iroha-peer-4.iroha:10001","peerKey":"43d6ae141f277e1309be0f5912a5a879c317f0d91202befd6fe872f49d51c7a2"}}},{"addPeer":{"peer":{"address":"iroha-peer-5.iroha:10001","peerKey":"0f7de3d0cd57a286160571c50ffb9c6e73f2070a58479a21751a12f0863a103e"}}},{"addPeer":{"peer":{"address":"iroha-peer-6.iroha:10001","peerKey":"bc3cec44a09c129532dcf51568fe45bb568f76af48b4cdec85e3728dd438ae93"}}}],"quorum":1}}}],"txNumber":1}}}' +kind: ConfigMap +metadata: + creationTimestamp: null + name: iroha-config + namespace: iroha-peer-network diff --git a/deploy/ansible/roles/iroha-k8s/files/iroha-k8s-peer-keys.yml b/deploy/ansible/roles/iroha-k8s/files/iroha-k8s-peer-keys.yml new file mode 100644 index 0000000000..c5a917f28c --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/files/iroha-k8s-peer-keys.yml @@ -0,0 +1,80 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: iroha-peer-key-0 + namespace: iroha-peer-network +type: Opaque +data: + node.priv: MDNhNzU2MDlmYzhjMWJkZjVmOWE3NDgxNmE0MDliMDMwZWNlZjlhMjI5ZjM3M2Q4NDAyMWNhZDcyNDQ3MTk3NQ== + node.pub: ZGVmMTc0MmI4MjkzNTM2YWMwZWNmM2MwNGU0YTczMDU5NjNkYzg1ZTkyN2E5NzQyYjVkOTE1ZmRlMjdlMTM5OQ== +--- +apiVersion: v1 +kind: Secret +metadata: + name: iroha-peer-key-1 + namespace: iroha-peer-network +type: Opaque +data: + node.priv: MmYxOWNjYTIyZDA0ODM4ZTYwNzJhYzdhNDhhYTIwN2Y4MDU0NWFkNjFlMmJlZjM0YzljMzk0MTBiNzg4YTE2Mw== + node.pub: NGM4NDY3MGE0YzhiMWE5NTEzNjA0OTg2ZjgwZGFiMDg1ZDUzNzNiYjdiZmJhOWQxNGVjYzNhNDZmYmM4Nzk3ZQ== +--- +apiVersion: v1 +kind: Secret +metadata: + name: iroha-peer-key-2 + namespace: iroha-peer-network +type: Opaque +data: + node.priv: NDBmYzI4NWY5MTdjNWZmYzY4MDY3NDI1OWRhNWI0MjZlNzRjZDY4NjA2ZDkzZWQwY2Y4YWQzMDg4ZWI4ZGM2Mw== + node.pub: NzZhZjlmYTY4YmIzYjgzOWYyYmFiNjNlNjdhYzc3YTRmNWRjYzBkMDg0MmJlYTM3ODdiNWY5MTg5YWQxMTM2ZQ== +--- +apiVersion: v1 +kind: Secret +metadata: + name: iroha-peer-key-3 + namespace: iroha-peer-network +type: Opaque +data: + node.priv: NjcyZjEwOGNjMDI4MWJlY2JlOTFkOWRlOTMzZjM5NmZlZjdmM2E4ZjgzZDA1MzgxMmZhMGFlYTVhYmJhOTM0NQ== + node.pub: OTRjZjFjMjIzMjVlMmQ2ZDQyMDBjZTk3Nzk4MzNmMTAzYzNkMjQ2MWI2ZDQ2ODRiMTI0YWQ5MWI2NGI3OWZkYg== +--- +apiVersion: v1 +kind: Secret +metadata: + name: iroha-peer-key-4 + namespace: iroha-peer-network +type: Opaque +data: + node.priv: MjFiNzUwZDhmMTc2YjdiZTY1Zjg5NGNkNjcxY2FkNWUwMzFmMmU2NDE4YmNjMzg1NGRiOGRiNWU2NWNhMWIxYw== + node.pub: NDNkNmFlMTQxZjI3N2UxMzA5YmUwZjU5MTJhNWE4NzljMzE3ZjBkOTEyMDJiZWZkNmZlODcyZjQ5ZDUxYzdhMg== +--- +apiVersion: v1 +kind: Secret +metadata: + name: iroha-peer-key-5 + namespace: iroha-peer-network +type: Opaque +data: + node.priv: MzA5NTY2YTlmYTU2ZTAxZDcyMTE1NjgxYzNkNzhkNDk1NDgwYWJlNWM4NmMyMjA0M2QxOTQ3MzQxZjgxMzYzNQ== + node.pub: MGY3ZGUzZDBjZDU3YTI4NjE2MDU3MWM1MGZmYjljNmU3M2YyMDcwYTU4NDc5YTIxNzUxYTEyZjA4NjNhMTAzZQ== +--- +apiVersion: v1 +kind: Secret +metadata: + name: iroha-peer-key-6 + namespace: iroha-peer-network +type: Opaque +data: + node.priv: NGM5OTlmMzk5NzA1YzNkYTY2YjBhZjEzYjQ5YTdkOGY2M2ZiNmFlNGQ3MWJlOWNiY2EzYmNlYTVhMDRhOThmYg== + node.pub: YmMzY2VjNDRhMDljMTI5NTMyZGNmNTE1NjhmZTQ1YmI1NjhmNzZhZjQ4YjRjZGVjODVlMzcyOGRkNDM4YWU5Mw== +--- +apiVersion: v1 +kind: Secret +metadata: + name: iroha-peer-key-7 + namespace: iroha-peer-network +type: Opaque +data: + node.priv: YWQwNjM1MWE1YzBmZGIxYTVkMTg1NmNlMDk2MzUxMzJmYjhkNWE4YTUxODFhNWI4N2VjZjRkNTdkNjU4NWZmZA== + node.pub: ZjNhNTc1NjA5M2ZjNTVkZDU4NjJjODE2ZjQxZTg3MTliZTEwZDE4MWI2MGMwODM5NjI0YWYxM2UyN2UzYmUyOQ== diff --git a/deploy/ansible/roles/iroha-k8s/files/iroha-k8s-services.yml b/deploy/ansible/roles/iroha-k8s/files/iroha-k8s-services.yml new file mode 100644 index 0000000000..cf55399c76 --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/files/iroha-k8s-services.yml @@ -0,0 +1,32 @@ +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: iroha + name: iroha + namespace: iroha-peer-network +spec: + clusterIP: None + ports: + - name: internal-port + port: 10001 + targetPort: 10001 + - name: torii-port + port: 50051 + targetPort: 50051 + selector: + app: iroha +--- +# docs at https://kubernetes.io/docs/concepts/services-networking/service/#externalname +# reference at https://stackoverflow.com/a/44329470 +kind: Service +apiVersion: v1 +metadata: + name: iroha-peer + namespace: default # target namespace to expose the port in +spec: + type: ExternalName + externalName: iroha.iroha-peer-network.svc.cluster.local + ports: + - port: 50051 \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/files/k8s-iroha.yaml b/deploy/ansible/roles/iroha-k8s/files/iroha-k8s.yml similarity index 58% rename from deploy/ansible/roles/iroha-k8s/files/k8s-iroha.yaml rename to deploy/ansible/roles/iroha-k8s/files/iroha-k8s.yml index b5a86a5eb4..a584c1f053 100644 --- a/deploy/ansible/roles/iroha-k8s/files/k8s-iroha.yaml +++ b/deploy/ansible/roles/iroha-k8s/files/iroha-k8s.yml @@ -1,30 +1,23 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: iroha - name: iroha -spec: - clusterIP: None - ports: - - port: 50051 - selector: - app: iroha --- apiVersion: apps/v1 kind: StatefulSet metadata: - name: iroha + name: iroha-peer labels: app: iroha + namespace: iroha-peer-network spec: serviceName: iroha - replicas: 4 + replicas: 8 + podManagementPolicy: "Parallel" + updateStrategy: + type: RollingUpdate selector: matchLabels: app: iroha template: metadata: + namespace: iroha-peer-network labels: app: iroha spec: @@ -39,22 +32,32 @@ spec: fieldRef: fieldPath: metadata.name volumeMounts: - - name: iroha-secret-0 - mountPath: /opt/secrets/iroha-0 - - name: iroha-secret-1 - mountPath: /opt/secrets/iroha-1 - - name: iroha-secret-2 - mountPath: /opt/secrets/iroha-2 - - name: iroha-secret-3 - mountPath: /opt/secrets/iroha-3 - - name: iroha-config + - name: iroha-peer-secret-0 + mountPath: /opt/secrets/iroha-peer-0 + - name: iroha-peer-secret-1 + mountPath: /opt/secrets/iroha-peer-1 + - name: iroha-peer-secret-2 + mountPath: /opt/secrets/iroha-peer-2 + - name: iroha-peer-secret-3 + mountPath: /opt/secrets/iroha-peer-3 + - name: iroha-peer-secret-4 + mountPath: /opt/secrets/iroha-peer-4 + - name: iroha-peer-secret-5 + mountPath: /opt/secrets/iroha-peer-5 + - name: iroha-peer-secret-6 + mountPath: /opt/secrets/iroha-peer-6 + - name: iroha-peer-secret-7 + mountPath: /opt/secrets/iroha-peer-7 + - name: iroha-peer-config mountPath: /opt/iroha_config - - name: iroha-data + - name: iroha-peer-data mountPath: /opt/iroha_data containers: - name: postgres image: postgres:9.5 imagePullPolicy: Always + command: ["docker-entrypoint.sh"] + args: ["postgres", "-c", "max_prepared_transactions=100"] ports: - containerPort: 5432 name: pg-port @@ -77,46 +80,59 @@ spec: - name: pg-data mountPath: /var/lib/postgresql/data - name: iroha - image: hyperledger/iroha:develop + image: hyperledger/iroha:1.0.0_rc3 imagePullPolicy: Always ports: - containerPort: 10001 - name: inter-peer + name: internal-port - containerPort: 50051 - name: external + name: torii-port env: - name: IROHA_POSTGRES_HOST value: localhost - name: KEY value: node volumeMounts: - - name: iroha-data + - name: iroha-peer-data mountPath: /opt/iroha_data - name: block-store mountPath: /tmp/block_store volumes: - - name: iroha-secret-0 + - name: iroha-peer-secret-0 secret: secretName: iroha-peer-key-0 - - name: iroha-secret-1 + - name: iroha-peer-secret-1 secret: secretName: iroha-peer-key-1 - - name: iroha-secret-2 + - name: iroha-peer-secret-2 secret: secretName: iroha-peer-key-2 - - name: iroha-secret-3 + - name: iroha-peer-secret-3 secret: secretName: iroha-peer-key-3 - - name: iroha-config + - name: iroha-peer-secret-4 + secret: + secretName: iroha-peer-key-4 + - name: iroha-peer-secret-5 + secret: + secretName: iroha-peer-key-5 + - name: iroha-peer-secret-6 + secret: + secretName: iroha-peer-key-6 + - name: iroha-peer-secret-7 + secret: + secretName: iroha-peer-key-7 + - name: iroha-peer-config configMap: name: iroha-config - - name: iroha-data + - name: iroha-peer-data emptyDir: {} - name: block-store emptyDir: {} volumeClaimTemplates: - metadata: name: pg-data + namespace: iroha-peer-network labels: app: iroha spec: @@ -127,6 +143,7 @@ spec: storage: 1Gi - metadata: name: block-store + namespace: iroha-peer-network labels: app: iroha spec: @@ -134,4 +151,4 @@ spec: - ReadWriteOnce resources: requests: - storage: 1Gi + storage: 1Gi \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/files/k8s-peer-keys.yaml b/deploy/ansible/roles/iroha-k8s/files/k8s-peer-keys.yaml deleted file mode 100644 index 936d95ff5f..0000000000 --- a/deploy/ansible/roles/iroha-k8s/files/k8s-peer-keys.yaml +++ /dev/null @@ -1,36 +0,0 @@ ---- -apiVersion: v1 -kind: Secret -metadata: - name: iroha-peer-key-0 -type: Opaque -data: - node.priv: YmI2MGE2ODNiZjQxYTc5ZWRhNzQxODhkYmUxYmM1M2RiOGY0ZmNlYTQwMWY2NDI3MTE1N2QwYWFkNzQxODdjYQ== - node.pub: YzEzMjhiMDkwNjE3OTkyNTgxY2E5YmM0YjI0NjZmNTg2MzRiMDY3ZGQzNDVjNzgzZTRhMWFiMDJhNjkxMzAyYw== ---- -apiVersion: v1 -kind: Secret -metadata: - name: iroha-peer-key-1 -type: Opaque -data: - node.priv: NGViOWJhZmIyYTEzZWNiMDRkOTZkN2JmNmQzY2Y3MTNkNTA4NDRjNWYyYTQxMjczNWEwMzU3NDFmYjU0NmU5NQ== - node.pub: MTVjMDlhNjAxOWFjZTdiOThjOGE1NjA2YThjYmNhNTgzZDY0NDJlODRiNWZhYWY1N2Y5NzI0NWYzZDU3NWVmNQ== ---- -apiVersion: v1 -kind: Secret -metadata: - name: iroha-peer-key-2 -type: Opaque -data: - node.priv: N2Y3OTI0NWRjMzRiN2FkOGVmNTNjNmI4MzUyZWZlNTdiMzE1N2VlZTgxODQxYzliM2U4NzdjMjQzMzZkNmVmZg== - node.pub: ZjExZjdiZDg4MzY3NGU3NzQ1ZmI4OGI4YjJmZjdlOTE3ZmFjMmViYzQ0ZjQ3NDBiZDc5MWE4NzExMzE2OWEwMA== ---- -apiVersion: v1 -kind: Secret -metadata: - name: iroha-peer-key-3 -type: Opaque -data: - node.priv: NGE3Yzc4ODRhNmNhOTFlN2YzOTE2NGQ2Y2UzOGY2NjAwMzFjYzZiYTdjNGFhZjIwNWQ2MjA1MmU0MWE3Nzg0MQ== - node.pub: ODdhOTdiNjNiMzBlZjQ4NzM2YzE5YjVlNmE1MDUwNGU0ZWI1N2Q1ODI4NjFjMjVmNWM5ZTBhNTZhMjJkOGRkMw== diff --git a/deploy/ansible/roles/iroha-k8s/files/peers.csv b/deploy/ansible/roles/iroha-k8s/files/peers.csv index e0e122a50e..9dabc76ab0 100644 --- a/deploy/ansible/roles/iroha-k8s/files/peers.csv +++ b/deploy/ansible/roles/iroha-k8s/files/peers.csv @@ -1,5 +1,9 @@ -host;port;priv_key_b64_encoded;pub_key_b64_encoded -iroha.iroha-0;50051;fec007e5efc95934aef8233f94ddad1b1c5006e0992c8b783a11413b7e627a1e;0897b2443848f7c541bc52e6b758f95e5a79f4b0d3ac6bcfcdcea361d8452a7a -iroha.iroha-1;50051;dfcb9f048e10e527b2a81eb69d273ba0fa087722c3c241f86dc156aa3adf4300;e9e726a09317c04816cd768e5d360be42684c27af8eba72c7a8c43ec3c7af3ad -iroha.iroha-2;50051;667cd9edd589b0209f8216f0588d296e8afb2919f37fc8d2440a7c3aacc5e013;0109dbafccb8107df5f5a5ca426b6b21e9fafa9a30f9f6f8e7af1f21295839d6 -iroha.iroha-3;50051;0a959f58adab203899a1a84a25feb785422fc16ea0672ae7f8186bf45b2d1d97;5e81ee948703379ce8de995f0c0a1d521cbc36665a7c244a88adb0b9ec30f900 +host;port;priv_key_hex;pub_key_hex +iroha-peer-0.iroha;10001;03a75609fc8c1bdf5f9a74816a409b030ecef9a229f373d84021cad724471975;def1742b8293536ac0ecf3c04e4a7305963dc85e927a9742b5d915fde27e1399 +iroha-peer-1.iroha;10001;2f19cca22d04838e6072ac7a48aa207f80545ad61e2bef34c9c39410b788a163;4c84670a4c8b1a9513604986f80dab085d5373bb7bfba9d14ecc3a46fbc8797e +iroha-peer-2.iroha;10001;40fc285f917c5ffc680674259da5b426e74cd68606d93ed0cf8ad3088eb8dc63;76af9fa68bb3b839f2bab63e67ac77a4f5dcc0d0842bea3787b5f9189ad1136e +iroha-peer-3.iroha;10001;672f108cc0281becbe91d9de933f396fef7f3a8f83d053812fa0aea5abba9345;94cf1c22325e2d6d4200ce9779833f103c3d2461b6d4684b124ad91b64b79fdb +iroha-peer-4.iroha;10001;21b750d8f176b7be65f894cd671cad5e031f2e6418bcc3854db8db5e65ca1b1c;43d6ae141f277e1309be0f5912a5a879c317f0d91202befd6fe872f49d51c7a2 +iroha-peer-5.iroha;10001;309566a9fa56e01d72115681c3d78d495480abe5c86c22043d1947341f813635;0f7de3d0cd57a286160571c50ffb9c6e73f2070a58479a21751a12f0863a103e +iroha-peer-6.iroha;10001;4c999f399705c3da66b0af13b49a7d8f63fb6ae4d71be9cbca3bcea5a04a98fb;bc3cec44a09c129532dcf51568fe45bb568f76af48b4cdec85e3728dd438ae93 +iroha-peer-7.iroha;10001;ad06351a5c0fdb1a5d1856ce09635132fb8d5a8a5181a5b87ecf4d57d6585ffd;f3a5756093fc55dd5862c816f41e8719be10d181b60c0839624af13e27e3be29 diff --git a/deploy/ansible/roles/iroha-k8s/files/scripts/ed25519.py b/deploy/ansible/roles/iroha-k8s/files/scripts/ed25519.py new file mode 100644 index 0000000000..25d1ea2f3e --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/files/scripts/ed25519.py @@ -0,0 +1,166 @@ +#!/usr/env/python3 + +import builtins +from past.utils import old_div +import sys, os +if sys.version_info < (3, 6): + from sha3 import sha3_512 as SHA3512 +else: + import hashlib + + +python_version = sys.version_info.major +b = 256 +q = 2 ** 255 - 19 +l = 2 ** 252 + 27742317777372353535851937790883648493 + + +def H(m): + if sys.version_info < (3, 6): + return SHA3512(m).digest() + else: + sha3_512 = hashlib.sha3_512() + sha3_512.update(m) + return sha3_512.digest() + +def expmod(b, e, m): + if e == 0: return 1 + t = expmod(b, old_div(e, 2), m) ** 2 % m + if e & 1: t = (t * b) % m + return t + + +def inv(x): + return expmod(x, q - 2, q) + + +d = -121665 * inv(121666) +I = expmod(2, old_div((q - 1), 4), q) + + +def xrecover(y): + xx = (y * y - 1) * inv(d * y * y + 1) + x = expmod(xx, old_div((q + 3), 8), q) + if (x * x - xx) % q != 0: x = (x * I) % q + if x % 2 != 0: x = q - x + return x + + +By = 4 * inv(5) +Bx = xrecover(By) +B = [Bx % q, By % q] + + +def edwards(P, Q): + x1 = P[0] + y1 = P[1] + x2 = Q[0] + y2 = Q[1] + x3 = (x1 * y2 + x2 * y1) * inv(1 + d * x1 * x2 * y1 * y2) + y3 = (y1 * y2 + x1 * x2) * inv(1 - d * x1 * x2 * y1 * y2) + return [x3 % q, y3 % q] + + +def scalarmult(P, e): + if e == 0: return [0, 1] + Q = scalarmult(P, old_div(e, 2)) + Q = edwards(Q, Q) + if e & 1: Q = edwards(Q, P) + return Q + + +def encodeint(y): + bits = [(y >> i) & 1 for i in range(b)] + return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(old_div(b, 8))]) + + +def encodepoint(P): + x = P[0] + y = P[1] + bits = [(y >> i) & 1 for i in range(b - 1)] + [x & 1] + return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(old_div(b, 8))]) + + +if python_version == 3: + def bit(h, i): + return ((h[old_div(i, 8)]) >> (i % 8)) & 1 +else: + def bit(h, i): + return (ord(h[old_div(i, 8)]) >> (i % 8)) & 1 + + +def publickey(sk): + h = H(sk) + a = 2 ** (b - 2) + sum(2 ** i * bit(h, i) for i in list(range(3, b - 2))) + A = scalarmult(B, a) + return encodepoint(A) + + +def Hint(m): + h = H(m) + return sum(2 ** i * bit(h, i) for i in list(range(2 * b))) + + +def signature(m, sk, pk): + h = H(sk) + a = 2 ** (b - 2) + sum(2 ** i * bit(h, i) for i in list(range(3, b - 2))) + r = Hint(''.join([h[i] for i in range(old_div(b, 8), old_div(b, 4))]) + m) + R = scalarmult(B, r) + S = (r + Hint(encodepoint(R) + pk + m) * a) % l + return encodepoint(R) + encodeint(S) + + +def isoncurve(P): + x = P[0] + y = P[1] + return (-x * x + y * y - 1 - d * x * x * y * y) % q == 0 + + +def decodeint(s): + return sum(2 ** i * bit(s, i) for i in list(range(0, b))) + + +def decodepoint(s): + y = sum(2 ** i * bit(s, i) for i in list(range(0, b - 1))) + x = xrecover(y) + if x & 1 != bit(s, b - 1): x = q - x + P = [x, y] + if not isoncurve(P): raise Exception("decoding point that is not on curve") + return P + + +def checkvalid(s, m, pk): + if len(s) != old_div(b, 4): raise Exception("signature length is wrong") + if len(pk) != old_div(b, 8): raise Exception("public-key length is wrong") + R = decodepoint(s[0:old_div(b, 8)]) + A = decodepoint(pk) + S = decodeint(s[old_div(b, 8):old_div(b, 4)]) + h = Hint(encodepoint(R) + pk + m) + if scalarmult(B, S) != edwards(R, scalarmult(A, h)): + raise Exception("signature does not pass verification") + + +def derive_pubkey_from_priv(priv): + return publickey(priv) + + +def sign(msg, priv, pub): + return signature(msg, priv, pub) + + +def verify(msg, sig, pub): + try: + checkvalid(sig, msg, pub) + return True + except Exception: + return False + +k = os.urandom(32) +# private key +if sys.version_info >= (3, 0): + print(k.hex()) +else: + print(k.encode('hex')) +pub = derive_pubkey_from_priv(k) +# public key +print(''.join(hex(ord(j))[2:].zfill(2) for j in pub)) diff --git a/deploy/ansible/roles/iroha-k8s/tasks/add-peers.yml b/deploy/ansible/roles/iroha-k8s/tasks/add-peers.yml new file mode 100644 index 0000000000..2178e01aae --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/tasks/add-peers.yml @@ -0,0 +1,24 @@ +--- +- name: Get peer entry from peer list file + command: > + sed '1d;$d' peers.csv + register: peer_list + args: + chdir: "{{ role_path }}/files/" + tags: + - add-peers + +- name: Generate genesis block file + template: + src: genesis.block.j2 + dest: "{{ role_path }}/files/conf/genesis.block" + tags: + - add-peers + +- name: Minify genesis.block + replace: + path: "{{ role_path }}/files/conf/genesis.block" + regexp: "[\t\n\r\\s]" + replace: "" + tags: + - add-peers diff --git a/deploy/ansible/roles/iroha-k8s/tasks/config-gen.yml b/deploy/ansible/roles/iroha-k8s/tasks/config-gen.yml new file mode 100644 index 0000000000..e5649c4724 --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/tasks/config-gen.yml @@ -0,0 +1,70 @@ +--- +- name: Write header to peer list file + shell: > + echo 'host;port;priv_key_hex;pub_key_hex' > peers.csv + args: + chdir: "{{ role_path }}/files/" + +- name: "Generate keypairs (iroha_replicas: {{ iroha_replicas }})" + command: > + python {{ role_path }}/files/scripts/ed25519.py + loop: "{{ range(iroha_replicas|int)|list }}" + register: result + +- name: Save gathered peer info in peer list file + shell: | + echo '{{ iroha_pod_basename }}-{{ item }}.{{ iroha_governing_service_domain_name }};{{ iroha_internal_port }};{{ result.results[item].stdout_lines[0] }};{{ result.results[item].stdout_lines[1] }}' >> {{ role_path }}/files/peers.csv + loop: "{{ range(iroha_replicas|int)|list }}" + args: + chdir: "{{ role_path }}/files/" + +- name: Generate config.docker + template: + src: config.docker.j2 + dest: "{{ role_path }}/files/conf/config.docker" + +- name: Build genesis.block + include: add-peers.yml + +- name: Move genesis block to {{ role_path }}/file/conf/ + command: "cp genesis.block conf/genesis.block" + args: + creates: "{{ role_path }}/files/conf" + chdir: "{{ role_path }}/files/" + +- name: Extract peer keys to use in defining secrets + shell: > + cat peers.csv | grep -E "[A-Fa-f0-9]{64}[;][A-Fa-f0-9]{64}" -o + register: peer_keys + args: + chdir: "{{ role_path }}/files/" + +- name: Generate/define k8s secrets + template: + src: iroha-k8s-peer-keys.yml.j2 + dest: "{{ role_path }}/files/iroha-k8s-peer-keys.yml" + +- name: Generate k8s config for iroha services + template: + src: iroha-k8s-services.yml.j2 + dest: "{{ role_path }}/files/iroha-k8s-services.yml" + +- name: Generate k8s config for iroha peers + template: + src: iroha-k8s.yml.j2 + dest: "{{ role_path }}/files/iroha-k8s.yml" + +- name: Generate configmap config file + shell: > + kubectl create configmap --dry-run {{ iroha_configmap_name }} \ + --from-file=conf/ \ + --output yaml \ + -n {{ iroha_namespace }} | tee iroha-k8s-configmap.yml + register: output + args: + chdir: "{{ role_path }}/files/" + tags: + - deploy + - configmap + +- debug: var=output.stdout_lines \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/tasks/deploy.yml b/deploy/ansible/roles/iroha-k8s/tasks/deploy.yml new file mode 100644 index 0000000000..d544039459 --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/tasks/deploy.yml @@ -0,0 +1,20 @@ +--- +- name: Provision Iroha services + command: > + kubectl apply -f iroha-k8s-configmap.yml \ + -f iroha-k8s-peer-keys.yml \ + -f iroha-k8s-services.yml + register: output + args: + chdir: "{{ role_path }}/files/" + +- debug: var=output.stdout_lines + +- name: Provision Iroha peers + command: > + kubectl apply -f iroha-k8s.yml + register: output + args: + chdir: "{{ role_path }}/files/" + +- debug: var=output.stdout_lines \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/tasks/destroy.yml b/deploy/ansible/roles/iroha-k8s/tasks/destroy.yml new file mode 100644 index 0000000000..0f26640613 --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/tasks/destroy.yml @@ -0,0 +1,16 @@ +--- +- name: DESTROYING IROHA PEER NETWORK AND DATA + command: kubectl delete -f iroha-k8s-peer-keys.yml -f iroha-k8s-services.yml -f iroha-k8s-configmap.yml -f iroha-k8s.yml + args: + chdir: "{{ role_path }}/files/" + tags: + - not-deploy + ignore_errors: yes + +- name: Delete namespace too + command: kubectl delete namespace {{ iroha_namespace }} + args: + chdir: "{{ role_path }}/files/" + when: iroha_namespace != "default" + tags: + - not-deploy \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/tasks/main.yml b/deploy/ansible/roles/iroha-k8s/tasks/main.yml index 5d2017de59..a9ed6257e2 100644 --- a/deploy/ansible/roles/iroha-k8s/tasks/main.yml +++ b/deploy/ansible/roles/iroha-k8s/tasks/main.yml @@ -1,54 +1,21 @@ --- - - name: Make CSV header - shell: "echo 'host;port;priv_key_b64_encoded;pub_key_b64_encoded' > {{ playbook_dir }}/scripts/peers.csv" - args: - chdir: "{{ playbook_dir }}/../../roles/iroha-k8s/files" - - - name: Make keys - shell: "{{ playbook_dir }}/scripts/ed25519-cli keygen | tr -d [:blank:] | cut -d':' -f2" - loop: "{{ range(replicas|int)|list }}" - register: result - - - name: Generate CSV with peers - shell: > - echo '{{ pod_basename }}-{{ item }}.{{ service_name }};{{ iroha_port }};{{ result.results[item].stdout_lines[0] }};{{ result.results[item].stdout_lines[1] }}' - >> {{ playbook_dir }}/scripts/peers.csv - args: - chdir: "{{ playbook_dir }}/../../roles/iroha-k8s/files" - loop: "{{ range(replicas|int)|list }}" - - - name: Generate config.docker - template: - src: config.docker.j2 - dest: "{{ playbook_dir }}/../../roles/iroha-k8s/files/conf/config.docker" - delegate_to: localhost - - - name: Make genesis block file - command: > - python3 {{ playbook_dir }}/scripts/genesis-add-peers.py add_iroha_peers {{ playbook_dir }}/scripts/peers.csv genesis.block - args: - chdir: "{{ playbook_dir }}/../../roles/iroha-k8s/files" - - - name: Move genesis block - command: "cp genesis.block conf/genesis.block" - args: - chdir: "{{ playbook_dir }}/../../roles/iroha-k8s/files" - - - name: Get peer keys for secrets - command: > - python3 {{ playbook_dir }}/scripts/genesis-add-peers.py print_keys_b64 {{ playbook_dir }}/scripts/peers.csv genesis.block - args: - chdir: "{{ playbook_dir }}/../../roles/iroha-k8s/files" - register: peer_keys - - - name: Generate k8s secrets - template: - src: k8s-peer-keys.yaml.j2 - dest: "{{ playbook_dir }}/../../roles/iroha-k8s/files/k8s-peer-keys.yaml" - delegate_to: localhost - - - name: Generate k8s config - template: - src: k8s-iroha.yaml.j2 - dest: "{{ playbook_dir }}/../../roles/iroha-k8s/files/k8s-iroha.yaml" - delegate_to: localhost +- set_fact: + iroha_namespace = "default" + when: create_custom_namespace | default(false) | bool + +- name: Create custom namespace + command: kubectl create namespace {{ iroha_namespace }} + ignore_errors: yes + tags: + - deploy + - required + +- name: Generate Iroha configs + include: config-gen.yml + tags: + - config-gen + +- name: Deploy Iroha + include: deploy.yml + tags: + - deploy diff --git a/deploy/ansible/roles/iroha-k8s/templates/config.docker.j2 b/deploy/ansible/roles/iroha-k8s/templates/config.docker.j2 index 0c7b44fb7d..83afc27d15 100644 --- a/deploy/ansible/roles/iroha-k8s/templates/config.docker.j2 +++ b/deploy/ansible/roles/iroha-k8s/templates/config.docker.j2 @@ -1,11 +1,11 @@ { "block_store_path" : "/tmp/block_store/", - "torii_port" : 50051, - "internal_port" : 10001, + "torii_port" : {{ iroha_torii_port }}, + "internal_port" : {{ iroha_internal_port }}, "pg_opt" : "host=localhost port=5432 user=postgres password=mysecretpassword", - "max_proposal_size" : {{ max_proposal_size }}, - "proposal_delay" : {{ proposal_delay }}, - "vote_delay" : {{ vote_delay }}, - "load_delay" : {{ load_delay }}, - "mst_enable" : false + "max_proposal_size" : {{ iroha_max_proposal_size }}, + "proposal_delay" : {{ iroha_proposal_delay }}, + "vote_delay" : {{ iroha_vote_delay }}, + "mst_enable" : {{ iroha_mst_enable }}, + "mst_expiration_time" : {{ iroha_mst_expiration_time }} } diff --git a/deploy/ansible/roles/iroha-k8s/templates/genesis.block.j2 b/deploy/ansible/roles/iroha-k8s/templates/genesis.block.j2 new file mode 100644 index 0000000000..0a8d790867 --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/templates/genesis.block.j2 @@ -0,0 +1,130 @@ +{ + "block_v1":{ + "payload":{ + "height":"1", + "prevBlockHash":"0000000000000000000000000000000000000000000000000000000000000000", + "transactions":[ + { + "payload":{ + "reducedPayload":{ + "commands":[ + { + "createRole":{ + "permissions":[ + "can_add_peer", + "can_add_signatory", + "can_create_account", + "can_create_domain", + "can_get_all_acc_ast", + "can_get_all_acc_ast_txs", + "can_get_all_acc_detail", + "can_get_all_acc_txs", + "can_get_all_accounts", + "can_get_all_signatories", + "can_get_all_txs", + "can_get_blocks", + "can_get_roles", + "can_read_assets", + "can_remove_signatory", + "can_set_quorum" + ], + "roleName":"admin" + } + }, + { + "createRole":{ + "permissions":[ + "can_add_signatory", + "can_get_my_acc_ast", + "can_get_my_acc_ast_txs", + "can_get_my_acc_detail", + "can_get_my_acc_txs", + "can_get_my_account", + "can_get_my_signatories", + "can_get_my_txs", + "can_grant_can_add_my_signatory", + "can_grant_can_remove_my_signatory", + "can_grant_can_set_my_account_detail", + "can_grant_can_set_my_quorum", + "can_grant_can_transfer_my_assets", + "can_receive", + "can_remove_signatory", + "can_set_quorum", + "can_transfer" + ], + "roleName":"user" + } + }, + { + "createRole":{ + "permissions":[ + "can_add_asset_qty", + "can_create_asset", + "can_receive", + "can_transfer" + ], + "roleName":"money_creator" + } + }, + { + "createDomain":{ + "defaultRole":"user", + "domainId":"test" + } + }, + { + "createAsset":{ + "assetName":"coin", + "domainId":"test", + "precision":2 + } + }, + { + "createAccount":{ + "accountName":"admin", + "domainId":"test", + "publicKey":"f98baa265831780855e80d0dbe271eb916a89fc7c6078ba55f3f111aec3baf40" + } + }, + { + "createAccount":{ + "accountName":"test", + "domainId":"test", + "publicKey":"705d21dc33c06f821ae32a2c9c188481471c567028ec999f8027a2b923c6b6aa" + } + }, + { + "appendRole":{ + "accountId":"admin@test", + "roleName":"admin" + } + }, + { + "appendRole":{ + "accountId":"admin@test", + "roleName":"money_creator" + } + }, +{% for peer in peer_list.stdout_lines %} +{% set peer_data = peer.split(';') %} + { + "addPeer":{ + "peer":{ + "address":"{{ peer_data[0] }}:{{ peer_data[1] }}", + "peerKey":"{{ peer_data[3] }}" + } + } + } + {% if not loop.last %}, + {% endif %} +{% endfor %} + ], + "quorum":1 + } + } + } + ], + "txNumber":1 + } + } +} \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s-peer-keys.yml.j2 b/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s-peer-keys.yml.j2 new file mode 100644 index 0000000000..3278762530 --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s-peer-keys.yml.j2 @@ -0,0 +1,13 @@ +{% for key_pair in peer_keys.stdout_lines %} +{% set keys = key_pair.split(';') %} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ iroha_pod_basename }}-key-{{ loop.index - 1 }} + namespace: {{ iroha_namespace }} +type: Opaque +data: + node.priv: {{ keys[0] | b64encode }} + node.pub: {{ keys[1] | b64encode }} +{% endfor %} diff --git a/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s-resource-limits.yml.j2 b/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s-resource-limits.yml.j2 new file mode 100644 index 0000000000..5106141331 --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s-resource-limits.yml.j2 @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: LimitRange +metadata: + name: resource-limits + namespace: {{ iroha_namespace }} +spec: + limits: + - default: + cpu: 500m + memory: 500Mi + defaultRequest: + cpu: 100m + memory: 200Mi + type: Container \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s-services.yml.j2 b/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s-services.yml.j2 new file mode 100644 index 0000000000..8926e7789a --- /dev/null +++ b/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s-services.yml.j2 @@ -0,0 +1,32 @@ +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: iroha + name: {{ iroha_governing_service_domain_name }} + namespace: {{ iroha_namespace }} +spec: + clusterIP: None + ports: + - name: {{ iroha_internal_port_name }} + port: {{ iroha_internal_port }} + targetPort: {{ iroha_internal_port }} + - name: {{ iroha_torii_port_name }} + port: {{ iroha_torii_port }} + targetPort: {{ iroha_torii_port }} + selector: + app: iroha +--- +# docs at https://kubernetes.io/docs/concepts/services-networking/service/#externalname +# reference at https://stackoverflow.com/a/44329470 +kind: Service +apiVersion: v1 +metadata: + name: {{ iroha_pod_basename }} + namespace: default # target namespace to expose the port in +spec: + type: ExternalName + externalName: {{ iroha_governing_service_domain_name }}.{{ iroha_namespace }}.svc.cluster.local + ports: + - port: {{ iroha_torii_port }} \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/templates/k8s-iroha.yaml.j2 b/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s.yml.j2 similarity index 63% rename from deploy/ansible/roles/iroha-k8s/templates/k8s-iroha.yaml.j2 rename to deploy/ansible/roles/iroha-k8s/templates/iroha-k8s.yml.j2 index 2e18607f13..e62e4a9ccf 100644 --- a/deploy/ansible/roles/iroha-k8s/templates/k8s-iroha.yaml.j2 +++ b/deploy/ansible/roles/iroha-k8s/templates/iroha-k8s.yml.j2 @@ -1,30 +1,24 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: iroha - name: iroha -spec: - clusterIP: None - ports: - - port: 50051 - selector: - app: iroha --- apiVersion: apps/v1 kind: StatefulSet metadata: - name: iroha + name: {{ iroha_pod_basename }} labels: app: iroha + max-supported-replicas: "{{ iroha_replicas }}" + namespace: {{ iroha_namespace }} spec: - serviceName: iroha - replicas: {{ replicas }} + serviceName: {{ iroha_governing_service_domain_name }} + replicas: {{ iroha_replicas }} + podManagementPolicy: "Parallel" + updateStrategy: + type: RollingUpdate selector: matchLabels: app: iroha template: metadata: + namespace: {{ iroha_namespace }} labels: app: iroha spec: @@ -40,17 +34,19 @@ spec: fieldPath: metadata.name volumeMounts: {% for key_pair in peer_keys.stdout_lines %} - - name: iroha-secret-{{ loop.index - 1 }} - mountPath: /opt/secrets/iroha-{{ loop.index - 1 }} + - name: {{ iroha_pod_basename }}-secret-{{ loop.index - 1 }} + mountPath: /opt/secrets/{{ iroha_pod_basename }}-{{ loop.index - 1 }} {% endfor %} - - name: iroha-config + - name: {{ iroha_pod_basename }}-config mountPath: /opt/iroha_config - - name: iroha-data + - name: {{ iroha_pod_basename }}-data mountPath: /opt/iroha_data containers: - name: postgres - image: postgres:9.5 + image: {{ postgres_image_tag }} imagePullPolicy: Always + command: ["docker-entrypoint.sh"] + args: ["postgres", "-c", "max_prepared_transactions=100"] ports: - containerPort: 5432 name: pg-port @@ -73,39 +69,40 @@ spec: - name: pg-data mountPath: /var/lib/postgresql/data - name: iroha - image: {{ iroha_image }} + image: {{ iroha_image_tag }} imagePullPolicy: Always ports: - - containerPort: 10001 - name: inter-peer - - containerPort: 50051 - name: external + - containerPort: {{ iroha_internal_port }} + name: {{ iroha_internal_port_name }} + - containerPort: {{ iroha_torii_port }} + name: {{ iroha_torii_port_name }} env: - name: IROHA_POSTGRES_HOST value: localhost - name: KEY value: node volumeMounts: - - name: iroha-data + - name: {{ iroha_pod_basename }}-data mountPath: /opt/iroha_data - name: block-store mountPath: /tmp/block_store volumes: {% for key_pair in peer_keys.stdout_lines %} - - name: iroha-secret-{{ loop.index - 1 }} + - name: {{ iroha_pod_basename }}-secret-{{ loop.index - 1 }} secret: - secretName: iroha-peer-key-{{ loop.index - 1 }} + secretName: {{ iroha_pod_basename }}-key-{{ loop.index - 1 }} {% endfor %} - - name: iroha-config + - name: {{ iroha_pod_basename }}-config configMap: - name: iroha-config - - name: iroha-data + name: {{ iroha_configmap_name }} + - name: {{ iroha_pod_basename }}-data emptyDir: {} - name: block-store emptyDir: {} volumeClaimTemplates: - metadata: name: pg-data + namespace: {{ iroha_namespace }} labels: app: iroha spec: @@ -116,6 +113,7 @@ spec: storage: {{ postgres_volume_size }} - metadata: name: block-store + namespace: {{ iroha_namespace }} labels: app: iroha spec: @@ -123,4 +121,4 @@ spec: - ReadWriteOnce resources: requests: - storage: {{ blockstore_volume_size }} + storage: {{ blockstore_volume_size }} \ No newline at end of file diff --git a/deploy/ansible/roles/iroha-k8s/templates/k8s-peer-keys.yaml.j2 b/deploy/ansible/roles/iroha-k8s/templates/k8s-peer-keys.yaml.j2 deleted file mode 100644 index af85c77d2b..0000000000 --- a/deploy/ansible/roles/iroha-k8s/templates/k8s-peer-keys.yaml.j2 +++ /dev/null @@ -1,12 +0,0 @@ -{% for key_pair in peer_keys.stdout_lines %} -{% set keys = key_pair.split(',') %} ---- -apiVersion: v1 -kind: Secret -metadata: - name: iroha-peer-key-{{ loop.index - 1 }} -type: Opaque -data: - node.priv: {{ keys[0] }} - node.pub: {{ keys[1] }} -{% endfor %}