mirror of
https://github.com/fluencelabs/tendermint
synced 2025-07-31 04:01:55 +00:00
@@ -9,5 +9,8 @@
|
||||
"amount": 9007199254740992
|
||||
}
|
||||
]
|
||||
}]
|
||||
}],
|
||||
"plugin_options": [
|
||||
"coin/issuer", {"app": "sigs", "addr": "1B1BE55F969F54064628A63B9559E7C21C925165"}
|
||||
]
|
||||
|
||||
|
@@ -13,6 +13,24 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "greg",
|
||||
"address": "B01C264BFE9CBD45458256E613A6F07061A3A6B6",
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data": "E1FFBD187FA2A922CE1B367532CEAC1AD8E606D576AB0D2E2CAA7EC6B7DAC10F"
|
||||
},
|
||||
"coins": [
|
||||
{
|
||||
"denom": "buckyball",
|
||||
"amount": 9007199254740991
|
||||
},
|
||||
{
|
||||
"denom": "gregcoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "anton",
|
||||
"address": "40CC622438D3E42148A1FFD3A27C07C100F8FA3D",
|
||||
@@ -22,30 +40,26 @@
|
||||
},
|
||||
"coins": [
|
||||
{
|
||||
"denom": "anton",
|
||||
"denom": "buckyball",
|
||||
"amount": 9007199254740992
|
||||
},
|
||||
{
|
||||
"denom": "tank",
|
||||
"amount": 99
|
||||
"denom": "antoncoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "adrian",
|
||||
"address": "98F28277FA8C512968BBDE443F5DB27AC743F814",
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data": "2E7EAB9E4C93D3657A63E063D6ABB851596BA97ED9F4EB9A2FC714043DC9685D"
|
||||
},
|
||||
"address": "0FA1DB09E8B174E81E94280C047C158D4271457B",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "axi",
|
||||
"denom": "buckyball",
|
||||
"amount": 1928936473812
|
||||
},
|
||||
{
|
||||
"denom": "bear",
|
||||
"amount": 42
|
||||
"denom": "adriancoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -62,16 +76,8 @@
|
||||
"amount": 20000000000
|
||||
},
|
||||
{
|
||||
"denom": "bumblebee",
|
||||
"amount": 100
|
||||
},
|
||||
{
|
||||
"denom": "french",
|
||||
"amount": 10
|
||||
},
|
||||
{
|
||||
"denom": "frey",
|
||||
"amount": 4838271727204
|
||||
"denom": "buckycoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -84,34 +90,12 @@
|
||||
},
|
||||
"coins": [
|
||||
{
|
||||
"denom": "radio",
|
||||
"amount": 50
|
||||
},
|
||||
{
|
||||
"denom": "tv",
|
||||
"amount": 3478765434568
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gregkey",
|
||||
"address": "B01C264BFE9CBD45458256E613A6F07061A3A6B6",
|
||||
"pubkey": {
|
||||
"type": "ed25519",
|
||||
"data": "E1FFBD187FA2A922CE1B367532CEAC1AD8E606D576AB0D2E2CAA7EC6B7DAC10F"
|
||||
},
|
||||
"coins": [
|
||||
{
|
||||
"denom": "mycoin",
|
||||
"amount": 3478765434568
|
||||
"denom": "rigelcoin",
|
||||
"amount": 1000
|
||||
},
|
||||
{
|
||||
"denom": "buckyball",
|
||||
"amount": 8367251830291
|
||||
},
|
||||
{
|
||||
"denom": "playmoney",
|
||||
"amount": 9999999999999
|
||||
"amount": 3478765434568
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -124,13 +108,87 @@
|
||||
},
|
||||
"coins": [
|
||||
{
|
||||
"denom": "shadow",
|
||||
"denom": "buckyball",
|
||||
"amount": 53712836452781
|
||||
},
|
||||
{
|
||||
"denom": "unit",
|
||||
"amount": 1
|
||||
"denom": "shadowcoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "peng",
|
||||
"address": "7B8422A210D0F0B8734908C093ECF0E9A768BDB8",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "buckyball",
|
||||
"amount": 53712836452781
|
||||
},
|
||||
{
|
||||
"denom": "pengcoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "matt",
|
||||
"address": "C2104A8191E282AA45D210BA93282B36768EDDA1",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "buckyball",
|
||||
"amount": 53712836452781
|
||||
},
|
||||
{
|
||||
"denom": "mattcoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "frey",
|
||||
"address": "0F8FB94B5A4D04220F15058B7AA16AF1328B57A9",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "buckyball",
|
||||
"amount": 53712836452781
|
||||
},
|
||||
{
|
||||
"denom": "freycoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wancloud",
|
||||
"address": "117FE408E1F74C453901BCB638F996964FD29CBB",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "buckyball",
|
||||
"amount": 53712836452781
|
||||
},
|
||||
{
|
||||
"denom": "wancloudcoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bianjie",
|
||||
"address": "F63F2D34C03430A54B7F6A43C886B4A83F366B84",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "buckyball",
|
||||
"amount": 53712836452781
|
||||
},
|
||||
{
|
||||
"denom": "bianjiecoin",
|
||||
"amount": 1000
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
],
|
||||
"plugin_options": [
|
||||
"coin/issuer", {"app": "sigs", "addr": "B01C264BFE9CBD45458256E613A6F07061A3A6B6"}
|
||||
]
|
||||
|
@@ -13,4 +13,8 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"plugin_options": [
|
||||
"coin/issuer", {"app": "sigs", "addr": "1B1BE55F969F54064628A63B9559E7C21C925165"}
|
||||
]
|
||||
|
||||
|
8
ansible/getconfigtoml.yml
Normal file
8
ansible/getconfigtoml.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
|
||||
#variable "service" is required
|
||||
|
||||
- hosts: "{{ lookup('env','TF_VAR_TESTNET_NAME') }}:tag_Environment_{{ lookup('env','TF_VAR_TESTNET_NAME') | regex_replace('-','_') }}"
|
||||
roles:
|
||||
- getconfigtoml
|
||||
|
8
ansible/getfile.yml
Normal file
8
ansible/getfile.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
|
||||
#variable "source" is required
|
||||
|
||||
- hosts: "{{ lookup('env','TF_VAR_TESTNET_NAME') }}:tag_Environment_{{ lookup('env','TF_VAR_TESTNET_NAME') | regex_replace('-','_') }}"
|
||||
roles:
|
||||
- getfile
|
||||
|
@@ -7,6 +7,6 @@
|
||||
roles:
|
||||
- install
|
||||
- {role: generic-service, when: service == 'tendermint'}
|
||||
- {role: config, testnet_name: "{{lookup('env','TF_VAR_TESTNET_NAME')}}"}
|
||||
- {role: config, testnet_name: "{{lookup('env','TF_VAR_TESTNET_NAME')}}", tags: reconfig }
|
||||
- start
|
||||
|
||||
|
8
ansible/jsonconfig.yml
Normal file
8
ansible/jsonconfig.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
|
||||
#variable "service" is required
|
||||
|
||||
- hosts: "{{ lookup('env','TF_VAR_TESTNET_NAME') }}:tag_Environment_{{ lookup('env','TF_VAR_TESTNET_NAME') | regex_replace('-','_') }}"
|
||||
roles:
|
||||
- jsonconfig
|
||||
|
@@ -1,7 +1,6 @@
|
||||
---
|
||||
#tendermint_genesis_file: "<undefined>"
|
||||
#service_genesis_file: "<undefined>"
|
||||
app_options_file: "app_options_files/dev_money"
|
||||
#genesis_file: "<undefined>"
|
||||
app_options_file: "app_options_files/public_testnet"
|
||||
seeds: ""
|
||||
testnet_name: testnet1
|
||||
validators: true
|
||||
|
@@ -2,64 +2,56 @@
|
||||
|
||||
- name: gather tendermint public keys
|
||||
when: (validators == true or validators == 'true') and tendermint_genesis_file is not defined
|
||||
command: "/usr/bin/tendermint show_validator --home /etc/{{service}}/tendermint --log_level error"
|
||||
tags: reconfig-toml,reconfig-genesis
|
||||
command: "/usr/bin/tendermint show_validator --home /etc/{{service}} --log_level error"
|
||||
register: pubkeys
|
||||
changed_when: false
|
||||
|
||||
- name: resetting permissions from root after gathering public keys
|
||||
file: "path=/etc/{{service}}/tendermint owner={{service}} group={{service}} recurse=yes"
|
||||
tags: reconfig-toml,reconfig-genesis
|
||||
file: "path=/etc/{{service}} owner={{service}} group={{service}} recurse=yes"
|
||||
|
||||
- name: register tendermint public keys as host facts
|
||||
when: (validators == true or validators == 'true') and tendermint_genesis_file is not defined
|
||||
tags: reconfig-toml,reconfig-genesis
|
||||
set_fact: "pubkey='{{pubkeys.stdout}}'"
|
||||
connection: local
|
||||
|
||||
- name: copy generated tendermint genesis.json - genesis_time will be updated
|
||||
when: (validators == true or validators == 'true') and tendermint_genesis_file is not defined
|
||||
- name: copy generated genesis.json - genesis_time will be updated
|
||||
when: (validators == true or validators == 'true') and (genesis_file is not defined)
|
||||
tags: reconfig-genesis
|
||||
template:
|
||||
src: genesis-server.json.j2
|
||||
dest: "/etc/{{service}}/tendermint/genesis.json"
|
||||
owner: "{{service}}"
|
||||
group: "{{service}}"
|
||||
|
||||
- name: copy generated service genesis.json - genesis_time will be updated
|
||||
when: (validators == true or validators == 'true') and (service_genesis_file is not defined) and (service != 'ethermint')
|
||||
template:
|
||||
src: genesis-service.json.j2
|
||||
src: genesis.json.j2
|
||||
dest: "/etc/{{service}}/genesis.json"
|
||||
owner: "{{service}}"
|
||||
group: "{{service}}"
|
||||
|
||||
- name: copy pre-created tendermint genesis.json
|
||||
when: tendermint_genesis_file is defined
|
||||
copy: "src={{tendermint_genesis_file}} dest=/etc/{{service}}/tendermint/genesis.json owner={{service}} group={{service}}"
|
||||
|
||||
- name: copy pre-created service genesis.json
|
||||
when: service_genesis_file is defined
|
||||
copy: "src={{service_genesis_file}} dest=/etc/{{service}}/genesis.json owner={{service}} group={{service}}"
|
||||
- name: copy pre-created genesis.json
|
||||
when: genesis_file is defined
|
||||
copy: "src={{genesis_file}} dest=/etc/{{service}}/genesis.json owner={{service}} group={{service}}"
|
||||
|
||||
- name: copy tendermint config.toml
|
||||
tags: reconfig
|
||||
tags: reconfig-toml
|
||||
when: validators == true or validators == 'true'
|
||||
template:
|
||||
src: config.toml.j2
|
||||
dest: "/etc/{{service}}/tendermint/config.toml"
|
||||
dest: "/etc/{{service}}/config.toml"
|
||||
owner: "{{service}}"
|
||||
group: "{{service}}"
|
||||
|
||||
- name: Copy validator network files for non-validators
|
||||
when: validators == false or validators == 'false'
|
||||
tags: reconfig-toml,reconfig-genesis
|
||||
get_url: "url={{item['src']}} dest={{item['dst']}} force=yes"
|
||||
with_items:
|
||||
- { src: "https://raw.githubusercontent.com/tendermint/testnets/master/{{validator_network}}/{{service}}/genesis.json" , dst: "/etc/{{service}}/genesis.json" }
|
||||
- { src: "https://raw.githubusercontent.com/tendermint/testnets/master/{{validator_network}}/tendermint/genesis.json" , dst: "/etc/{{service}}/tendermint/genesis.json" }
|
||||
- { src: "https://raw.githubusercontent.com/tendermint/testnets/master/{{validator_network}}/tendermint/config.toml" , dst: "/etc/{{service}}/tendermint/config.toml" }
|
||||
- { src: "https://raw.githubusercontent.com/tendermint/testnets/master/{{validator_network}}/config.toml" , dst: "/etc/{{service}}/config.toml" }
|
||||
|
||||
- name: Set validator network files permissions for non-validators
|
||||
when: validators == false or validators == 'false'
|
||||
tags: reconfig-toml,reconfig-genesis
|
||||
file: "path={{item}} owner={{service}} group={{service}}"
|
||||
with_items:
|
||||
- "/etc/{{service}}/genesis.json"
|
||||
- "/etc/{{service}}/tendermint/genesis.json"
|
||||
- "/etc/{{service}}/tendermint/config.toml"
|
||||
- "/etc/{{service}}/config.toml"
|
||||
|
||||
|
@@ -4,13 +4,23 @@
|
||||
proxy_app = "tcp://127.0.0.1:46658"
|
||||
moniker = "{{inventory_hostname}}"
|
||||
fast_sync = true
|
||||
{% if service == 'tendermint' %}
|
||||
|
||||
db_backend = "memdb"
|
||||
#log_level = "mempool:error,*:debug"
|
||||
log_level = "mempool:error,*:debug"
|
||||
|
||||
{% else %}
|
||||
|
||||
db_backend = "leveldb"
|
||||
log_level = "state:info,*:error"
|
||||
|
||||
{% endif %}
|
||||
|
||||
[rpc]
|
||||
laddr = "tcp://0.0.0.0:46657"
|
||||
|
||||
{% if service == 'tendermint' %}
|
||||
|
||||
[mempool]
|
||||
recheck = false
|
||||
broadcast = false
|
||||
@@ -24,11 +34,21 @@ skip_timeout_commit = true
|
||||
timeout_commit = 1
|
||||
wal_light = true
|
||||
block_part_size = 262144
|
||||
create_empty_blocks_interval = 1
|
||||
|
||||
{% else %}
|
||||
|
||||
[consensus]
|
||||
create_empty_blocks_interval = 1
|
||||
|
||||
{% endif %}
|
||||
|
||||
[p2p]
|
||||
{% if service == 'tendermint' %}
|
||||
max_msg_packet_payload_size=65536
|
||||
send_rate=51200000 # 50 MB/s
|
||||
recv_rate=51200000 # 50 MB/s
|
||||
{% endif %}
|
||||
laddr = "tcp://0.0.0.0:46656"
|
||||
{% if validators == true or validators == 'true' %}
|
||||
{% set comma = joiner(",") %}seeds = "{% for host in ((groups[testnet_name]|default([]))+(groups['tag_Environment_'~(testnet_name|regex_replace('-','_'))]|default([])))|difference(inventory_hostname) %}{{ comma() }}{{hostvars[host]["inventory_hostname"]}}:46656{% endfor %}"
|
||||
|
@@ -12,7 +12,7 @@
|
||||
"data": "{{hostvars[host]["pubkey"]["data"]}}",
|
||||
"type": "{{hostvars[host]["pubkey"]["type"]}}"
|
||||
},
|
||||
"amount":10,
|
||||
"power":10,
|
||||
"name":"{{hostvars[host]["inventory_hostname"]}}"
|
||||
}
|
||||
{% endfor %}
|
||||
|
46
ansible/roles/config/templates/genesis.json.j2
Normal file
46
ansible/roles/config/templates/genesis.json.j2
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"genesis_time":"{{ansible_date_time.iso8601}}",
|
||||
"chain_id":"{{testnet_name}}",
|
||||
"validators":
|
||||
[
|
||||
{% if (validators == true) or (validators == 'true') %}
|
||||
{% set comma = joiner(",") %}
|
||||
{% for host in (groups[testnet_name]|default([]))+(groups['tag_Environment_'~(testnet_name|regex_replace('-','_'))]|default([])) %}
|
||||
{{ comma() }}
|
||||
{
|
||||
"pub_key": {
|
||||
"data": "{{hostvars[host]["pubkey"]["data"]}}",
|
||||
"type": "{{hostvars[host]["pubkey"]["type"]}}"
|
||||
},
|
||||
"power":10,
|
||||
"name":"{{hostvars[host]["inventory_hostname"]}}"
|
||||
}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
],
|
||||
"app_hash":"",
|
||||
"app_options": {
|
||||
{% if app_options_file is defined %}
|
||||
{% include app_options_file %}
|
||||
{% endif %}
|
||||
}
|
||||
{% if service == 'ethermint' %}
|
||||
,
|
||||
"config": {
|
||||
"chainId": 15,
|
||||
"homesteadBlock": 0,
|
||||
"eip155Block": 0,
|
||||
"eip158Block": 0
|
||||
},
|
||||
"nonce": "0xdeadbeefdeadbeef",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"difficulty": "0x40",
|
||||
"gasLimit": "0x8000000",
|
||||
"alloc": {
|
||||
"0x7eff122b94897ea5b0e2a9abf47b86337fafebdc": { "balance": "10000000000000000000000000000000000" },
|
||||
"0xc6713982649D9284ff56c32655a9ECcCDA78422A": { "balance": "10000000000000000000000000000000000" }
|
||||
}
|
||||
{% endif %}
|
||||
}
|
@@ -15,11 +15,8 @@
|
||||
- name: Reload systemd services
|
||||
systemd: "name={{service}} daemon_reload=yes enabled=no"
|
||||
|
||||
- name: Create tendermint directory
|
||||
file: "path=/etc/{{service}}/tendermint state=directory mode=0755 owner={{service}} group={{service}}"
|
||||
|
||||
- name: Initialize tendermint
|
||||
command: "/usr/bin/tendermint init --home /etc/{{service}}/tendermint"
|
||||
command: "/usr/bin/tendermint init --home /etc/{{service}}"
|
||||
become: yes
|
||||
become_user: "{{service}}"
|
||||
|
||||
|
6
ansible/roles/getconfigtoml/tasks/main.yml
Normal file
6
ansible/roles/getconfigtoml/tasks/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
- name: Get config.toml from node
|
||||
fetch: "dest={{ destination | default('.') }}/config.toml flat=yes src=/etc/{{service}}/config.toml"
|
||||
run_once: yes
|
||||
|
6
ansible/roles/getfile/tasks/main.yml
Normal file
6
ansible/roles/getfile/tasks/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
- name: Get file from node
|
||||
fetch: "dest={{ destination | default('.') }}/{{ source | basename }} flat=yes src='{{source}}'"
|
||||
run_once: yes
|
||||
|
@@ -1,4 +1,5 @@
|
||||
---
|
||||
release_install: true
|
||||
binary: "{{ lookup('env','GOPATH') | default('') }}/bin/{{service}}"
|
||||
devops_path: false
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
#Workaround
|
||||
- name: Download repository key for CentOS/RedHat
|
||||
when: ansible_os_family == "RedHat"
|
||||
get_url: "url=https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint dest=/root/RPM-GPG-KEY-Tendermint force=yes checksum=sha256:a8c61d4061697d2595562c703dbafbdfdcfa7f0c75a523ac84d5609d1b444abe"
|
||||
get_url: "url=https://tendermint-packages.interblock.io/{{ (devops_path | default(false) | bool) | ternary('devops/','') }}centos/7/os/x86_64/RPM-GPG-KEY-Tendermint dest=/root/RPM-GPG-KEY-Tendermint force=yes checksum=sha256:a8c61d4061697d2595562c703dbafbdfdcfa7f0c75a523ac84d5609d1b444abe"
|
||||
- name: Import repository key for CentOS/RedHat
|
||||
when: ansible_os_family == "RedHat"
|
||||
command: "rpm --import /root/RPM-GPG-KEY-Tendermint"
|
||||
@@ -22,13 +22,32 @@
|
||||
when: ansible_os_family == "RedHat"
|
||||
yum_repository:
|
||||
name: tendermint
|
||||
baseurl: https://tendermint-packages.interblock.io/centos/7/os/x86_64
|
||||
baseurl: https://tendermint-packages.interblock.io/{{ (devops_path | default(false) | bool) | ternary('devops/','') }}centos/7/os/x86_64
|
||||
description: "Tendermint repo"
|
||||
gpgcheck: yes
|
||||
gpgkey: https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint
|
||||
gpgkey: https://tendermint-packages.interblock.io/{{ (devops_path | default(false) | bool) | ternary('devops/','') }}centos/7/os/x86_64/RPM-GPG-KEY-Tendermint
|
||||
# repo_gpgcheck: yes
|
||||
|
||||
- name: Install package on CentOS/RedHat
|
||||
when: ansible_os_family == "RedHat"
|
||||
yum: "pkg={{service}} update_cache=yes state=latest"
|
||||
|
||||
# The below commands are required so that the tomlconfig playbook can run.
|
||||
|
||||
- name: Install epel-release on CentOS/RedHat
|
||||
when: ansible_os_family == "RedHat"
|
||||
yum: "pkg=epel-release update_cache=yes state=latest"
|
||||
|
||||
- name: Install pip on CentOS/RedHat
|
||||
when: ansible_os_family == "RedHat"
|
||||
yum: "pkg={{item}} state=latest"
|
||||
with_items:
|
||||
- python2-pip
|
||||
- python-virtualenv
|
||||
- unzip
|
||||
- tar
|
||||
|
||||
- name: Install toml
|
||||
when: ansible_os_family == "RedHat"
|
||||
pip: name=toml
|
||||
|
||||
|
@@ -8,15 +8,24 @@
|
||||
- name: Add repository key on Debian/Ubuntu
|
||||
when: ansible_os_family == "Debian"
|
||||
apt_key:
|
||||
url: https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint
|
||||
url: https://tendermint-packages.interblock.io/{{ (devops_path | default(false) | bool) | ternary('devops/','') }}centos/7/os/x86_64/RPM-GPG-KEY-Tendermint
|
||||
id: 2122CBE9
|
||||
|
||||
- name: Install tendermint repository on Debian/Ubuntu
|
||||
when: ansible_os_family == "Debian"
|
||||
apt_repository:
|
||||
repo: deb https://tendermint-packages.interblock.io/debian stable main
|
||||
repo: deb https://tendermint-packages.interblock.io/{{ (devops_path | default(false) | bool) | ternary('devops/','') }}debian stable main
|
||||
|
||||
- name: Install package on Debian/Ubuntu
|
||||
when: ansible_os_family == "Debian"
|
||||
apt: "pkg={{service}} update_cache=yes state=latest"
|
||||
|
||||
# The below command is required to use the tomlconfig playbook.
|
||||
|
||||
- name: Install package on Debian/Ubuntu
|
||||
when: ansible_os_family == "Debian"
|
||||
apt: "pkg={{item}} state=latest"
|
||||
with_items:
|
||||
- python-toml
|
||||
- unzip
|
||||
- tar
|
||||
|
@@ -13,6 +13,9 @@
|
||||
- name: Restart journald
|
||||
service: name=systemd-journald state=restarted
|
||||
|
||||
#TODO include is deprecated in Ansible 2.4.0 and will be removed in 2.8.0
|
||||
#Replace it with include_tasks
|
||||
|
||||
- include: debian.yml
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
|
360
ansible/roles/jsonconfig/library/jsonconfig.py
Normal file
360
ansible/roles/jsonconfig/library/jsonconfig.py
Normal file
@@ -0,0 +1,360 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'
|
||||
}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: jsonconfig
|
||||
|
||||
short_description: Ensure a particular configuration is added to a json-formatted configuration file
|
||||
|
||||
version_added: "2.4"
|
||||
|
||||
description:
|
||||
- This module will add configuration to a json-formatted configuration file.
|
||||
|
||||
options:
|
||||
dest:
|
||||
description:
|
||||
- The file to modify.
|
||||
required: true
|
||||
aliases: [ name, destfile ]
|
||||
json:
|
||||
description:
|
||||
- The configuration in json format to apply.
|
||||
required: false
|
||||
default: '{}'
|
||||
merge:
|
||||
description:
|
||||
- Used with C(state=present). If specified, it will merge the configuration. Othwerwise
|
||||
the configuration will be overwritten.
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: "yes"
|
||||
state:
|
||||
description:
|
||||
- Whether the configuration should be there or not.
|
||||
required: false
|
||||
choices: [ present, absent ]
|
||||
default: "present"
|
||||
create:
|
||||
description:
|
||||
- Used with C(state=present). If specified, the file will be created
|
||||
if it does not already exist. By default it will fail if the file
|
||||
is missing.
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: "no"
|
||||
backup:
|
||||
description:
|
||||
- Create a backup file including the timestamp information so you can
|
||||
get the original file back if you somehow clobbered it incorrectly.
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: "no"
|
||||
others:
|
||||
description:
|
||||
- All arguments accepted by the M(file) module also work here.
|
||||
required: false
|
||||
|
||||
extends_documentation_fragment:
|
||||
- files
|
||||
- validate
|
||||
|
||||
author:
|
||||
- "Greg Szabo (@greg-szabo)"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Add a new section to a json file
|
||||
- name: Add comment section
|
||||
jsonconfig:
|
||||
dest: /etc/something.json
|
||||
json: '{ "comment": { "comment1": "mycomment" } }'
|
||||
|
||||
# Rewrite a json file with the configuration
|
||||
- name: Create or overwrite config.json
|
||||
jsonconfig:
|
||||
dest: /etc/config.json
|
||||
json: '{ "regedit": { "freshfile": true } }'
|
||||
merge: no
|
||||
create: yes
|
||||
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
changed:
|
||||
description: True if the configuration changed.
|
||||
type: bool
|
||||
msg:
|
||||
description: Description of the change
|
||||
type: str
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.six import b
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
import tempfile
|
||||
import json
|
||||
import copy
|
||||
import os
|
||||
|
||||
def write_changes(module, b_lines, dest):
|
||||
|
||||
tmpfd, tmpfile = tempfile.mkstemp()
|
||||
f = os.fdopen(tmpfd, 'wb')
|
||||
f.writelines(b_lines)
|
||||
f.close()
|
||||
|
||||
validate = module.params.get('validate', None)
|
||||
valid = not validate
|
||||
if validate:
|
||||
if "%s" not in validate:
|
||||
module.fail_json(msg="validate must contain %%s: %s" % (validate))
|
||||
(rc, out, err) = module.run_command(to_bytes(validate % tmpfile, errors='surrogate_or_strict'))
|
||||
valid = rc == 0
|
||||
if rc != 0:
|
||||
module.fail_json(msg='failed to validate: '
|
||||
'rc:%s error:%s' % (rc, err))
|
||||
if valid:
|
||||
module.atomic_move(tmpfile,
|
||||
to_native(os.path.realpath(to_bytes(dest, errors='surrogate_or_strict')), errors='surrogate_or_strict'),
|
||||
unsafe_writes=module.params['unsafe_writes'])
|
||||
|
||||
|
||||
def check_file_attrs(module, changed, message, diff):
|
||||
|
||||
file_args = module.load_file_common_arguments(module.params)
|
||||
if module.set_fs_attributes_if_different(file_args, False, diff=diff):
|
||||
|
||||
if changed:
|
||||
message += " and "
|
||||
changed = True
|
||||
message += "ownership, perms or SE linux context changed"
|
||||
|
||||
return message, changed
|
||||
|
||||
|
||||
#Merge dict d2 into dict d1 and return a new object
|
||||
def deepmerge(d1, d2):
|
||||
if d1 is None:
|
||||
return copy.deepcopy(d2)
|
||||
if d2 is None:
|
||||
return copy.deepcopy(d1)
|
||||
if d1 == d2:
|
||||
return copy.deepcopy(d1)
|
||||
if isinstance(d1, dict) and isinstance(d2, dict):
|
||||
result={}
|
||||
for key in set(d1.keys()+d2.keys()):
|
||||
da = db = None
|
||||
if key in d1:
|
||||
da = d1[key]
|
||||
if key in d2:
|
||||
db = d2[key]
|
||||
result[key] = deepmerge(da, db)
|
||||
return result
|
||||
else:
|
||||
return copy.deepcopy(d2)
|
||||
|
||||
|
||||
#Remove dict d2 from dict d1 and return a new object
|
||||
def deepdiff(d1, d2):
|
||||
if d1 is None or d2 is None:
|
||||
return None
|
||||
if d1 == d2:
|
||||
return None
|
||||
if isinstance(d1, dict) and isinstance(d2, dict):
|
||||
result = {}
|
||||
for key in d1.keys():
|
||||
if key in d2:
|
||||
dd = deepdiff(d1[key],d2[key])
|
||||
if dd is not None:
|
||||
result[key] = dd
|
||||
else:
|
||||
result[key] = d1[key]
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def present(module, dest, conf, merge, create, backup):
|
||||
|
||||
diff = {'before': '',
|
||||
'after': '',
|
||||
'before_header': '%s (content)' % dest,
|
||||
'after_header': '%s (content)' % dest}
|
||||
|
||||
b_dest = to_bytes(dest, errors='surrogate_or_strict')
|
||||
if not os.path.exists(b_dest):
|
||||
if not create:
|
||||
module.fail_json(rc=257, msg='Destination %s does not exist !' % dest)
|
||||
b_destpath = os.path.dirname(b_dest)
|
||||
if not os.path.exists(b_destpath) and not module.check_mode:
|
||||
os.makedirs(b_destpath)
|
||||
b_lines = []
|
||||
else:
|
||||
f = open(b_dest, 'rb')
|
||||
b_lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
lines = to_native(b('').join(b_lines))
|
||||
|
||||
if module._diff:
|
||||
diff['before'] = lines
|
||||
|
||||
b_conf = to_bytes(conf, errors='surrogate_or_strict')
|
||||
|
||||
jsonconfig = json.loads(lines)
|
||||
config = eval(b_conf)
|
||||
|
||||
if not isinstance(config, dict):
|
||||
module.fail_json(msg="Invalid value in json parameter: {0}".format(config))
|
||||
|
||||
b_lines_new = b_lines
|
||||
msg = ''
|
||||
changed = False
|
||||
|
||||
if not merge:
|
||||
if jsonconfig != config:
|
||||
b_lines_new = to_bytes(json.dumps(config, sort_keys=True, indent=4, separators=(',', ': ')))
|
||||
msg = 'config overwritten'
|
||||
changed = True
|
||||
else:
|
||||
mergedconfig = deepmerge(jsonconfig,config)
|
||||
if jsonconfig != mergedconfig:
|
||||
b_lines_new = to_bytes(json.dumps(mergedconfig, sort_keys=True, indent=4, separators=(',', ': ')))
|
||||
msg = 'config merged'
|
||||
changed = True
|
||||
|
||||
if module._diff:
|
||||
diff['after'] = to_native(b('').join(b_lines_new))
|
||||
|
||||
backupdest = ""
|
||||
if changed and not module.check_mode:
|
||||
if backup and os.path.exists(b_dest):
|
||||
backupdest = module.backup_local(dest)
|
||||
write_changes(module, b_lines_new, dest)
|
||||
|
||||
if module.check_mode and not os.path.exists(b_dest):
|
||||
module.exit_json(changed=changed, msg=msg, backup=backupdest, diff=diff)
|
||||
|
||||
attr_diff = {}
|
||||
msg, changed = check_file_attrs(module, changed, msg, attr_diff)
|
||||
|
||||
attr_diff['before_header'] = '%s (file attributes)' % dest
|
||||
attr_diff['after_header'] = '%s (file attributes)' % dest
|
||||
|
||||
difflist = [diff, attr_diff]
|
||||
module.exit_json(changed=changed, msg=msg, backup=backupdest, diff=difflist)
|
||||
|
||||
|
||||
def absent(module, dest, conf, backup):
|
||||
|
||||
b_dest = to_bytes(dest, errors='surrogate_or_strict')
|
||||
if not os.path.exists(b_dest):
|
||||
module.exit_json(changed=False, msg="file not present")
|
||||
|
||||
msg = ''
|
||||
diff = {'before': '',
|
||||
'after': '',
|
||||
'before_header': '%s (content)' % dest,
|
||||
'after_header': '%s (content)' % dest}
|
||||
|
||||
f = open(b_dest, 'rb')
|
||||
b_lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
lines = to_native(b('').join(b_lines))
|
||||
b_conf = to_bytes(conf, errors='surrogate_or_strict')
|
||||
|
||||
lines = to_native(b('').join(b_lines))
|
||||
jsonconfig = json.loads(lines)
|
||||
config = eval(b_conf)
|
||||
|
||||
if not isinstance(config, dict):
|
||||
module.fail_json(msg="Invalid value in json parameter: {0}".format(config))
|
||||
|
||||
if module._diff:
|
||||
diff['before'] = to_native(b('').join(b_lines))
|
||||
|
||||
b_lines_new = b_lines
|
||||
msg = ''
|
||||
changed = False
|
||||
|
||||
diffconfig = deepdiff(jsonconfig,config)
|
||||
if diffconfig is None:
|
||||
diffconfig = {}
|
||||
if jsonconfig != diffconfig:
|
||||
b_lines_new = to_bytes(json.dumps(diffconfig, sort_keys=True, indent=4, separators=(',', ': ')))
|
||||
msg = 'config removed'
|
||||
changed = True
|
||||
|
||||
if module._diff:
|
||||
diff['after'] = to_native(b('').join(b_lines_new))
|
||||
|
||||
backupdest = ""
|
||||
if changed and not module.check_mode:
|
||||
if backup:
|
||||
backupdest = module.backup_local(dest)
|
||||
write_changes(module, b_lines_new, dest)
|
||||
|
||||
attr_diff = {}
|
||||
msg, changed = check_file_attrs(module, changed, msg, attr_diff)
|
||||
|
||||
attr_diff['before_header'] = '%s (file attributes)' % dest
|
||||
attr_diff['after_header'] = '%s (file attributes)' % dest
|
||||
|
||||
difflist = [diff, attr_diff]
|
||||
|
||||
module.exit_json(changed=changed, msg=msg, backup=backupdest, diff=difflist)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
# define the available arguments/parameters that a user can pass to
|
||||
# the module
|
||||
module_args = dict(
|
||||
dest=dict(type='str', required=True),
|
||||
json=dict(default=None, required=True),
|
||||
merge=dict(type='bool', default=True),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
create=dict(type='bool', default=False),
|
||||
backup=dict(type='bool', default=False),
|
||||
validate=dict(default=None, type='str')
|
||||
)
|
||||
|
||||
# the AnsibleModule object will be our abstraction working with Ansible
|
||||
# this includes instantiation, a couple of common attr would be the
|
||||
# args/params passed to the execution, as well as if the module
|
||||
# supports check mode
|
||||
module = AnsibleModule(
|
||||
argument_spec=module_args,
|
||||
add_file_common_args=True,
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
params = module.params
|
||||
create = params['create']
|
||||
merge = params['merge']
|
||||
backup = params['backup']
|
||||
dest = params['dest']
|
||||
|
||||
b_dest = to_bytes(dest, errors='surrogate_or_strict')
|
||||
|
||||
if os.path.isdir(b_dest):
|
||||
module.fail_json(rc=256, msg='Destination %s is a directory !' % dest)
|
||||
|
||||
conf = params['json']
|
||||
|
||||
if params['state'] == 'present':
|
||||
present(module, dest, conf, merge, create, backup)
|
||||
else:
|
||||
absent(module, dest, conf, backup)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
5
ansible/roles/jsonconfig/tasks/main.yml
Normal file
5
ansible/roles/jsonconfig/tasks/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
|
||||
- name: Update
|
||||
jsonconfig: "dest='{{destination}}' json='{{jsonconfig}}' state={{(remove | default(false) | bool) | ternary('absent','present')}}"
|
||||
|
27
ansible/roles/setfile/tasks/main.yml
Normal file
27
ansible/roles/setfile/tasks/main.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
|
||||
- name: Download file if necessary
|
||||
when: source | regex_search('^https?://')
|
||||
get_url: "url={{source}} dest={{localdir}}/{{source | basename | regex_replace('\\?.*$','')}}"
|
||||
register: downloaded
|
||||
connection: local
|
||||
run_once: yes
|
||||
become: no
|
||||
|
||||
- name: Figure out file source
|
||||
set_fact:
|
||||
compiledsource: "{{ (downloaded.skipped is defined) | ternary(source, downloaded.dest) }}"
|
||||
connection: local
|
||||
become: no
|
||||
|
||||
- name: Extract file to destination
|
||||
when: compiledsource | regex_search('\\.(zip|tar|tar\\.gz|tgz|tb2|tbz|tbz2|tar\\.bz2|txz|tar\\.xz)$')
|
||||
register: extractcopy
|
||||
unarchive:
|
||||
src: "{{compiledsource}}"
|
||||
dest: "{{destination}}"
|
||||
|
||||
- name: Copy non-zipped file to destination
|
||||
when: extractcopy.skipped is defined
|
||||
copy: "src='{{compiledsource}}' dest='{{destination}}'"
|
||||
|
3
ansible/roles/tomlconfig/defaults/main.yml
Normal file
3
ansible/roles/tomlconfig/defaults/main.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
destination: /etc/{{service}}/config.toml
|
||||
|
386
ansible/roles/tomlconfig/library/tomlconfig.py
Normal file
386
ansible/roles/tomlconfig/library/tomlconfig.py
Normal file
@@ -0,0 +1,386 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'
|
||||
}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tomlconfig
|
||||
|
||||
short_description: Ensure a particular configuration is added to a toml-formatted configuration file
|
||||
|
||||
version_added: "2.4"
|
||||
|
||||
description:
|
||||
- This module will add configuration to a toml-formatted configuration file.
|
||||
|
||||
options:
|
||||
dest:
|
||||
description:
|
||||
- The file to modify.
|
||||
required: true
|
||||
aliases: [ name, destfile ]
|
||||
json:
|
||||
description:
|
||||
- The configuration in json format to apply. Either C(json) or C(toml) has to be present.
|
||||
required: false
|
||||
default: '{}'
|
||||
toml:
|
||||
description:
|
||||
- The configuration in toml format to apply. Either C(json) or C(toml) has to be present.
|
||||
default: ''
|
||||
merge:
|
||||
description:
|
||||
- Used with C(state=present). If specified, it will merge the configuration. Othwerwise
|
||||
the configuration will be overwritten.
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: "yes"
|
||||
state:
|
||||
description:
|
||||
- Whether the configuration should be there or not.
|
||||
required: false
|
||||
choices: [ present, absent ]
|
||||
default: "present"
|
||||
create:
|
||||
description:
|
||||
- Used with C(state=present). If specified, the file will be created
|
||||
if it does not already exist. By default it will fail if the file
|
||||
is missing.
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: "no"
|
||||
backup:
|
||||
description:
|
||||
- Create a backup file including the timestamp information so you can
|
||||
get the original file back if you somehow clobbered it incorrectly.
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: "no"
|
||||
others:
|
||||
description:
|
||||
- All arguments accepted by the M(file) module also work here.
|
||||
required: false
|
||||
|
||||
extends_documentation_fragment:
|
||||
- files
|
||||
- validate
|
||||
|
||||
author:
|
||||
- "Greg Szabo (@greg-szabo)"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Add a new section to a toml file
|
||||
- name: Add comment section
|
||||
tomlconfig:
|
||||
dest: /etc/config.toml
|
||||
json: '{ "comment": { "comment1": "mycomment" } }'
|
||||
|
||||
# Rewrite a toml file with the configuration
|
||||
- name: Create or overwrite config.toml
|
||||
tomlconfig:
|
||||
dest: /etc/config.toml
|
||||
json: '{ "regedit": { "freshfile": true } }'
|
||||
merge: no
|
||||
create: yes
|
||||
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
changed:
|
||||
description: True if the configuration changed.
|
||||
type: bool
|
||||
msg:
|
||||
description: Description of the change
|
||||
type: str
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.six import b
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
import tempfile
|
||||
import toml as pytoml
|
||||
import json
|
||||
import copy
|
||||
import os
|
||||
|
||||
def write_changes(module, b_lines, dest):
|
||||
|
||||
tmpfd, tmpfile = tempfile.mkstemp()
|
||||
f = os.fdopen(tmpfd, 'wb')
|
||||
f.writelines(b_lines)
|
||||
f.close()
|
||||
|
||||
validate = module.params.get('validate', None)
|
||||
valid = not validate
|
||||
if validate:
|
||||
if "%s" not in validate:
|
||||
module.fail_json(msg="validate must contain %%s: %s" % (validate))
|
||||
(rc, out, err) = module.run_command(to_bytes(validate % tmpfile, errors='surrogate_or_strict'))
|
||||
valid = rc == 0
|
||||
if rc != 0:
|
||||
module.fail_json(msg='failed to validate: '
|
||||
'rc:%s error:%s' % (rc, err))
|
||||
if valid:
|
||||
module.atomic_move(tmpfile,
|
||||
to_native(os.path.realpath(to_bytes(dest, errors='surrogate_or_strict')), errors='surrogate_or_strict'),
|
||||
unsafe_writes=module.params['unsafe_writes'])
|
||||
|
||||
|
||||
def check_file_attrs(module, changed, message, diff):
|
||||
|
||||
file_args = module.load_file_common_arguments(module.params)
|
||||
if module.set_fs_attributes_if_different(file_args, False, diff=diff):
|
||||
|
||||
if changed:
|
||||
message += " and "
|
||||
changed = True
|
||||
message += "ownership, perms or SE linux context changed"
|
||||
|
||||
return message, changed
|
||||
|
||||
|
||||
#Merge dict d2 into dict d1 and return a new object
|
||||
def deepmerge(d1, d2):
|
||||
if d1 is None:
|
||||
return copy.deepcopy(d2)
|
||||
if d2 is None:
|
||||
return copy.deepcopy(d1)
|
||||
if d1 == d2:
|
||||
return copy.deepcopy(d1)
|
||||
if isinstance(d1, dict) and isinstance(d2, dict):
|
||||
result={}
|
||||
for key in set(d1.keys()+d2.keys()):
|
||||
da = db = None
|
||||
if key in d1:
|
||||
da = d1[key]
|
||||
if key in d2:
|
||||
db = d2[key]
|
||||
result[key] = deepmerge(da, db)
|
||||
return result
|
||||
else:
|
||||
return copy.deepcopy(d2)
|
||||
|
||||
|
||||
#Remove dict d2 from dict d1 and return a new object
|
||||
def deepdiff(d1, d2):
|
||||
if d1 is None or d2 is None:
|
||||
return None
|
||||
if d1 == d2:
|
||||
return None
|
||||
if isinstance(d1, dict) and isinstance(d2, dict):
|
||||
result = {}
|
||||
for key in d1.keys():
|
||||
if key in d2:
|
||||
dd = deepdiff(d1[key],d2[key])
|
||||
if dd is not None:
|
||||
result[key] = dd
|
||||
else:
|
||||
result[key] = d1[key]
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def present(module, dest, conf, jsonbool, merge, create, backup):
|
||||
|
||||
diff = {'before': '',
|
||||
'after': '',
|
||||
'before_header': '%s (content)' % dest,
|
||||
'after_header': '%s (content)' % dest}
|
||||
|
||||
b_dest = to_bytes(dest, errors='surrogate_or_strict')
|
||||
if not os.path.exists(b_dest):
|
||||
if not create:
|
||||
module.fail_json(rc=257, msg='Destination %s does not exist !' % dest)
|
||||
b_destpath = os.path.dirname(b_dest)
|
||||
if not os.path.exists(b_destpath) and not module.check_mode:
|
||||
os.makedirs(b_destpath)
|
||||
b_lines = []
|
||||
else:
|
||||
f = open(b_dest, 'rb')
|
||||
b_lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
lines = to_native(b('').join(b_lines))
|
||||
|
||||
if module._diff:
|
||||
diff['before'] = lines
|
||||
|
||||
b_conf = to_bytes(conf, errors='surrogate_or_strict')
|
||||
|
||||
tomlconfig = pytoml.loads(lines)
|
||||
config = {}
|
||||
if jsonbool:
|
||||
config = eval(b_conf)
|
||||
else:
|
||||
config = pytoml.loads(b_conf)
|
||||
|
||||
if not isinstance(config, dict):
|
||||
if jsonbool:
|
||||
module.fail_json(msg="Invalid value in json parameter: {0}".format(config))
|
||||
else:
|
||||
module.fail_json(msg="Invalid value in toml parameter: {0}".format(config))
|
||||
|
||||
b_lines_new = b_lines
|
||||
msg = ''
|
||||
changed = False
|
||||
|
||||
if not merge:
|
||||
if tomlconfig != config:
|
||||
b_lines_new = to_bytes(pytoml.dumps(config))
|
||||
msg = 'config overwritten'
|
||||
changed = True
|
||||
else:
|
||||
mergedconfig = deepmerge(tomlconfig,config)
|
||||
if tomlconfig != mergedconfig:
|
||||
b_lines_new = to_bytes(pytoml.dumps(mergedconfig))
|
||||
msg = 'config merged'
|
||||
changed = True
|
||||
|
||||
if module._diff:
|
||||
diff['after'] = to_native(b('').join(b_lines_new))
|
||||
|
||||
backupdest = ""
|
||||
if changed and not module.check_mode:
|
||||
if backup and os.path.exists(b_dest):
|
||||
backupdest = module.backup_local(dest)
|
||||
write_changes(module, b_lines_new, dest)
|
||||
|
||||
if module.check_mode and not os.path.exists(b_dest):
|
||||
module.exit_json(changed=changed, msg=msg, backup=backupdest, diff=diff)
|
||||
|
||||
attr_diff = {}
|
||||
msg, changed = check_file_attrs(module, changed, msg, attr_diff)
|
||||
|
||||
attr_diff['before_header'] = '%s (file attributes)' % dest
|
||||
attr_diff['after_header'] = '%s (file attributes)' % dest
|
||||
|
||||
difflist = [diff, attr_diff]
|
||||
module.exit_json(changed=changed, msg=msg, backup=backupdest, diff=difflist)
|
||||
|
||||
|
||||
def absent(module, dest, conf, jsonbool, backup):
|
||||
|
||||
b_dest = to_bytes(dest, errors='surrogate_or_strict')
|
||||
if not os.path.exists(b_dest):
|
||||
module.exit_json(changed=False, msg="file not present")
|
||||
|
||||
msg = ''
|
||||
diff = {'before': '',
|
||||
'after': '',
|
||||
'before_header': '%s (content)' % dest,
|
||||
'after_header': '%s (content)' % dest}
|
||||
|
||||
f = open(b_dest, 'rb')
|
||||
b_lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
lines = to_native(b('').join(b_lines))
|
||||
b_conf = to_bytes(conf, errors='surrogate_or_strict')
|
||||
|
||||
lines = to_native(b('').join(b_lines))
|
||||
tomlconfig = pytoml.loads(lines)
|
||||
config = {}
|
||||
if jsonbool:
|
||||
config = eval(b_conf)
|
||||
else:
|
||||
config = pytoml.loads(b_conf)
|
||||
|
||||
if not isinstance(config, dict):
|
||||
if jsonbool:
|
||||
module.fail_json(msg="Invalid value in json parameter: {0}".format(config))
|
||||
else:
|
||||
module.fail_json(msg="Invalid value in toml parameter: {0}".format(config))
|
||||
|
||||
if module._diff:
|
||||
diff['before'] = to_native(b('').join(b_lines))
|
||||
|
||||
b_lines_new = b_lines
|
||||
msg = ''
|
||||
changed = False
|
||||
|
||||
diffconfig = deepdiff(tomlconfig,config)
|
||||
if diffconfig is None:
|
||||
diffconfig = {}
|
||||
if tomlconfig != diffconfig:
|
||||
b_lines_new = to_bytes(pytoml.dumps(diffconfig))
|
||||
msg = 'config removed'
|
||||
changed = True
|
||||
|
||||
if module._diff:
|
||||
diff['after'] = to_native(b('').join(b_lines_new))
|
||||
|
||||
backupdest = ""
|
||||
if changed and not module.check_mode:
|
||||
if backup:
|
||||
backupdest = module.backup_local(dest)
|
||||
write_changes(module, b_lines_new, dest)
|
||||
|
||||
attr_diff = {}
|
||||
msg, changed = check_file_attrs(module, changed, msg, attr_diff)
|
||||
|
||||
attr_diff['before_header'] = '%s (file attributes)' % dest
|
||||
attr_diff['after_header'] = '%s (file attributes)' % dest
|
||||
|
||||
difflist = [diff, attr_diff]
|
||||
|
||||
module.exit_json(changed=changed, msg=msg, backup=backupdest, diff=difflist)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
# define the available arguments/parameters that a user can pass to
|
||||
# the module
|
||||
module_args = dict(
|
||||
dest=dict(type='str', required=True),
|
||||
json=dict(default=None),
|
||||
toml=dict(default=None),
|
||||
merge=dict(type='bool', default=True),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
create=dict(type='bool', default=False),
|
||||
backup=dict(type='bool', default=False),
|
||||
validate=dict(default=None, type='str')
|
||||
)
|
||||
|
||||
# the AnsibleModule object will be our abstraction working with Ansible
|
||||
# this includes instantiation, a couple of common attr would be the
|
||||
# args/params passed to the execution, as well as if the module
|
||||
# supports check mode
|
||||
module = AnsibleModule(
|
||||
argument_spec=module_args,
|
||||
mutually_exclusive=[['json', 'toml']],
|
||||
add_file_common_args=True,
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
params = module.params
|
||||
create = params['create']
|
||||
merge = params['merge']
|
||||
backup = params['backup']
|
||||
dest = params['dest']
|
||||
|
||||
b_dest = to_bytes(dest, errors='surrogate_or_strict')
|
||||
|
||||
if os.path.isdir(b_dest):
|
||||
module.fail_json(rc=256, msg='Destination %s is a directory !' % dest)
|
||||
|
||||
par_json, par_toml, jsonbool = params['json'], params['toml'], False
|
||||
if par_json is None:
|
||||
conf = par_toml
|
||||
else:
|
||||
conf = par_json
|
||||
jsonbool = True
|
||||
|
||||
if params['state'] == 'present':
|
||||
present(module, dest, conf, jsonbool, merge, create, backup)
|
||||
else:
|
||||
absent(module, dest, conf, jsonbool, backup)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
10
ansible/roles/tomlconfig/tasks/main.yml
Normal file
10
ansible/roles/tomlconfig/tasks/main.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
|
||||
- name: Update config.toml with json
|
||||
when: jsonconfig is defined
|
||||
tomlconfig: "dest='{{destination}}' json='{{jsonconfig}}' state={{(remove | default(false) | bool) | ternary('absent','present')}}"
|
||||
|
||||
- name: Update config.toml with toml
|
||||
when: tomlconfig is defined
|
||||
tomlconfig: "dest='{{destination}}' toml='{{tomlconfig}}' state={{(remove | default(false) | bool) | ternary('absent','present')}}"
|
||||
|
@@ -6,6 +6,8 @@
|
||||
when: "service == 'basecoin'"
|
||||
become_user: basecoin
|
||||
|
||||
- shell: "export TMHOME=/etc/{{service}}/tendermint ; tendermint unsafe_reset_all"
|
||||
- shell: "export TMHOME=/etc/{{service}} ; tendermint unsafe_reset_all"
|
||||
become_user: "{{service}}"
|
||||
|
||||
- file: "path=/etc/{{service}}/data state=absent"
|
||||
|
||||
|
10
ansible/setfile.yml
Normal file
10
ansible/setfile.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
|
||||
#variable "source" is required
|
||||
#variable "destination" is required
|
||||
|
||||
- hosts: "{{ lookup('env','TF_VAR_TESTNET_NAME') }}:tag_Environment_{{ lookup('env','TF_VAR_TESTNET_NAME') | regex_replace('-','_') }}"
|
||||
gather_facts: no
|
||||
roles:
|
||||
- setfile
|
||||
|
8
ansible/tomlconfig.yml
Normal file
8
ansible/tomlconfig.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
|
||||
#variable "service" is required
|
||||
|
||||
- hosts: "{{ lookup('env','TF_VAR_TESTNET_NAME') }}:tag_Environment_{{ lookup('env','TF_VAR_TESTNET_NAME') | regex_replace('-','_') }}"
|
||||
roles:
|
||||
- tomlconfig
|
||||
|
Reference in New Issue
Block a user